]> git.itanic.dy.fi Git - linux-stable/commitdiff
drm/ttm: Use GFP_TRANSHUGE_LIGHT for allocating huge pages
authorMichel Dänzer <michel.daenzer@amd.com>
Wed, 25 Apr 2018 15:32:10 +0000 (17:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 May 2018 08:12:31 +0000 (10:12 +0200)
commit da291320baec914f0bb4e65a9dccb86bd6c728f2 upstream.

GFP_TRANSHUGE tries very hard to allocate huge pages, which can result
in long delays with high memory pressure. I have observed firefox
freezing for up to around a minute due to this while restic was taking
a full system backup.

Since we don't really need huge pages, use GFP_TRANSHUGE_LIGHT |
__GFP_NORETRY instead, in order to fail quickly when there are no huge
pages available.

Set __GFP_KSWAPD_RECLAIM as well, in order for huge pages to be freed
up in the background if necessary.

With these changes, I'm no longer seeing freezes during a restic backup.

Cc: stable@vger.kernel.org
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/ttm/ttm_page_alloc.c
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c

index 2b12c55a3bff82e48b581a60dba23b5c4c33b7a2..28311caf1e47b81702ff4e91d80bbfddd404e106 100644 (file)
@@ -904,7 +904,8 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags,
                        while (npages >= HPAGE_PMD_NR) {
                                gfp_t huge_flags = gfp_flags;
 
-                               huge_flags |= GFP_TRANSHUGE;
+                               huge_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
+                                       __GFP_KSWAPD_RECLAIM;
                                huge_flags &= ~__GFP_MOVABLE;
                                huge_flags &= ~__GFP_COMP;
                                p = alloc_pages(huge_flags, HPAGE_PMD_ORDER);
@@ -1021,11 +1022,15 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
                                  GFP_USER | GFP_DMA32, "uc dma", 0);
 
        ttm_page_pool_init_locked(&_manager->wc_pool_huge,
-                                 GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP),
+                                 (GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
+                                  __GFP_KSWAPD_RECLAIM) &
+                                 ~(__GFP_MOVABLE | __GFP_COMP),
                                  "wc huge", order);
 
        ttm_page_pool_init_locked(&_manager->uc_pool_huge,
-                                 GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP)
+                                 (GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
+                                  __GFP_KSWAPD_RECLAIM) &
+                                 ~(__GFP_MOVABLE | __GFP_COMP)
                                  , "uc huge", order);
 
        _manager->options.max_size = max_pages;
index a88051552acee7c90a526486a0632f1b2be1f98a..323cadaeb7d137a5c090f76fc677452c84967b9a 100644 (file)
@@ -915,7 +915,8 @@ static gfp_t ttm_dma_pool_gfp_flags(struct ttm_dma_tt *ttm_dma, bool huge)
                gfp_flags |= __GFP_ZERO;
 
        if (huge) {
-               gfp_flags |= GFP_TRANSHUGE;
+               gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
+                       __GFP_KSWAPD_RECLAIM;
                gfp_flags &= ~__GFP_MOVABLE;
                gfp_flags &= ~__GFP_COMP;
        }