drm/ttm: allocate/free multiple pages in a single call
authorChristian König <christian.koenig@amd.com>
Tue, 19 Sep 2017 13:20:42 +0000 (15:20 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Oct 2017 20:30:17 +0000 (16:30 -0400)
Totally surprisingly this is more efficient than doing it page by page.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/ttm/ttm_page_alloc.c

index e11fd76..482dd9a 100644 (file)
@@ -873,15 +873,14 @@ int ttm_pool_populate(struct ttm_tt *ttm)
        if (ttm->state != tt_unpopulated)
                return 0;
 
-       for (i = 0; i < ttm->num_pages; ++i) {
-               ret = ttm_get_pages(&ttm->pages[i], 1,
-                                   ttm->page_flags,
-                                   ttm->caching_state);
-               if (ret != 0) {
-                       ttm_pool_unpopulate(ttm);
-                       return -ENOMEM;
-               }
+       ret = ttm_get_pages(ttm->pages, ttm->num_pages, ttm->page_flags,
+                           ttm->caching_state);
+       if (unlikely(ret != 0)) {
+               ttm_pool_unpopulate(ttm);
+               return ret;
+       }
 
+       for (i = 0; i < ttm->num_pages; ++i) {
                ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
                                                PAGE_SIZE);
                if (unlikely(ret != 0)) {
@@ -908,14 +907,14 @@ void ttm_pool_unpopulate(struct ttm_tt *ttm)
        unsigned i;
 
        for (i = 0; i < ttm->num_pages; ++i) {
-               if (ttm->pages[i]) {
-                       ttm_mem_global_free_page(ttm->glob->mem_glob,
-                                                ttm->pages[i], PAGE_SIZE);
-                       ttm_put_pages(&ttm->pages[i], 1,
-                                     ttm->page_flags,
-                                     ttm->caching_state);
-               }
+               if (!ttm->pages[i])
+                       continue;
+
+               ttm_mem_global_free_page(ttm->glob->mem_glob, ttm->pages[i],
+                                        PAGE_SIZE);
        }
+       ttm_put_pages(ttm->pages, ttm->num_pages, ttm->page_flags,
+                     ttm->caching_state);
        ttm->state = tt_unpopulated;
 }
 EXPORT_SYMBOL(ttm_pool_unpopulate);