Subject: Re: TTM placement & caching issue/questions

From: Benjamin Herrenschmidt <[email-masked]>
Date: Thu, 04 Sep 2014 12:15:48 +1000

On Wed, 2014-09-03 at 21:55 -0400, Jerome Glisse wrote:
> So i think we need to get a platform flags and or set_pages_array_wc|uc
> needs to fail and this would fallback to cached mapping if the fallback
> code still works. So if your arch properly return and error for those
> cache changing function then you should be fine.
> 
> This also means that we need to fix ttm_tt_set_placement_caching so that
> when it returns an error it switches to cached mapping. Which will always
> work.

Can't I just filter the mem_type definitions in the mem_type_manager
with something along that totally untested patch ?

Or do I *also* need to make those set_page_array_* things fail ?

--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1308,6 +1308,24 @@ int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned 
 }
 EXPORT_SYMBOL(ttm_bo_evict_mm);
 
+static void ttm_bo_filter_mem_type(struct ttm_bo_device *bdev, unsigned type,
+                                  struct ttm_mem_type_manager *man)
+{
+       /*
+        * On some architectures/patforms, we cannot allow non-cachable
+        * mappings of system memory. This can be a problem with AGP on
+        * old G5 systems vs. TTM_PL_TT but we don't really have a choice
+        * at this point on ppc64 at least and the AGP on these never
+        * worked reliably anyway.
+        */
+#if defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
+       if (type == TTM_PL_SYSTEM || type == TTM_PL_TT) {
+               man->available_caching &= TTM_PL_FLAG_CACHED;
+               man->default_caching &= man->available_caching;
+       }
+#endif
+}
+
 int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
                        unsigned long p_size)
 {
@@ -1327,6 +1345,8 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned ty
                return ret;
        man->bdev = bdev;
 
+       ttm_bo_filter_mem_type(bdev, type, man);
+
        ret = 0;
        if (type != TTM_PL_SYSTEM) {
                ret = (*man->func->init)(man, p_size);