diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2046e333ea8f..32b3e121a388 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3268,7 +3268,6 @@ static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone) | |||
3268 | } | 3268 | } |
3269 | #endif /* CONFIG_NUMA */ | 3269 | #endif /* CONFIG_NUMA */ |
3270 | 3270 | ||
3271 | #ifdef CONFIG_ZONE_DMA32 | ||
3272 | /* | 3271 | /* |
3273 | * The restriction on ZONE_DMA32 as being a suitable zone to use to avoid | 3272 | * The restriction on ZONE_DMA32 as being a suitable zone to use to avoid |
3274 | * fragmentation is subtle. If the preferred zone was HIGHMEM then | 3273 | * fragmentation is subtle. If the preferred zone was HIGHMEM then |
@@ -3278,10 +3277,16 @@ static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone) | |||
3278 | * fragmentation between the Normal and DMA32 zones. | 3277 | * fragmentation between the Normal and DMA32 zones. |
3279 | */ | 3278 | */ |
3280 | static inline unsigned int | 3279 | static inline unsigned int |
3281 | alloc_flags_nofragment(struct zone *zone) | 3280 | alloc_flags_nofragment(struct zone *zone, gfp_t gfp_mask) |
3282 | { | 3281 | { |
3282 | unsigned int alloc_flags = 0; | ||
3283 | |||
3284 | if (gfp_mask & __GFP_KSWAPD_RECLAIM) | ||
3285 | alloc_flags |= ALLOC_KSWAPD; | ||
3286 | |||
3287 | #ifdef CONFIG_ZONE_DMA32 | ||
3283 | if (zone_idx(zone) != ZONE_NORMAL) | 3288 | if (zone_idx(zone) != ZONE_NORMAL) |
3284 | return 0; | 3289 | goto out; |
3285 | 3290 | ||
3286 | /* | 3291 | /* |
3287 | * If ZONE_DMA32 exists, assume it is the one after ZONE_NORMAL and | 3292 | * If ZONE_DMA32 exists, assume it is the one after ZONE_NORMAL and |
@@ -3290,17 +3295,12 @@ alloc_flags_nofragment(struct zone *zone) | |||
3290 | */ | 3295 | */ |
3291 | BUILD_BUG_ON(ZONE_NORMAL - ZONE_DMA32 != 1); | 3296 | BUILD_BUG_ON(ZONE_NORMAL - ZONE_DMA32 != 1); |
3292 | if (nr_online_nodes > 1 && !populated_zone(--zone)) | 3297 | if (nr_online_nodes > 1 && !populated_zone(--zone)) |
3293 | return 0; | 3298 | goto out; |
3294 | 3299 | ||
3295 | return ALLOC_NOFRAGMENT; | 3300 | out: |
3296 | } | 3301 | #endif /* CONFIG_ZONE_DMA32 */ |
3297 | #else | 3302 | return alloc_flags; |
3298 | static inline unsigned int | ||
3299 | alloc_flags_nofragment(struct zone *zone) | ||
3300 | { | ||
3301 | return 0; | ||
3302 | } | 3303 | } |
3303 | #endif | ||
3304 | 3304 | ||
3305 | /* | 3305 | /* |
3306 | * get_page_from_freelist goes through the zonelist trying to allocate | 3306 | * get_page_from_freelist goes through the zonelist trying to allocate |
@@ -3939,6 +3939,9 @@ gfp_to_alloc_flags(gfp_t gfp_mask) | |||
3939 | } else if (unlikely(rt_task(current)) && !in_interrupt()) | 3939 | } else if (unlikely(rt_task(current)) && !in_interrupt()) |
3940 | alloc_flags |= ALLOC_HARDER; | 3940 | alloc_flags |= ALLOC_HARDER; |
3941 | 3941 | ||
3942 | if (gfp_mask & __GFP_KSWAPD_RECLAIM) | ||
3943 | alloc_flags |= ALLOC_KSWAPD; | ||
3944 | |||
3942 | #ifdef CONFIG_CMA | 3945 | #ifdef CONFIG_CMA |
3943 | if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) | 3946 | if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) |
3944 | alloc_flags |= ALLOC_CMA; | 3947 | alloc_flags |= ALLOC_CMA; |
@@ -4170,7 +4173,7 @@ retry_cpuset: | |||
4170 | if (!ac->preferred_zoneref->zone) | 4173 | if (!ac->preferred_zoneref->zone) |
4171 | goto nopage; | 4174 | goto nopage; |
4172 | 4175 | ||
4173 | if (gfp_mask & __GFP_KSWAPD_RECLAIM) | 4176 | if (alloc_flags & ALLOC_KSWAPD) |
4174 | wake_all_kswapds(order, gfp_mask, ac); | 4177 | wake_all_kswapds(order, gfp_mask, ac); |
4175 | 4178 | ||
4176 | /* | 4179 | /* |
@@ -4228,7 +4231,7 @@ retry_cpuset: | |||
4228 | 4231 | ||
4229 | retry: | 4232 | retry: |
4230 | /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ | 4233 | /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ |
4231 | if (gfp_mask & __GFP_KSWAPD_RECLAIM) | 4234 | if (alloc_flags & ALLOC_KSWAPD) |
4232 | wake_all_kswapds(order, gfp_mask, ac); | 4235 | wake_all_kswapds(order, gfp_mask, ac); |
4233 | 4236 | ||
4234 | reserve_flags = __gfp_pfmemalloc_flags(gfp_mask); | 4237 | reserve_flags = __gfp_pfmemalloc_flags(gfp_mask); |
@@ -4451,7 +4454,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid, | |||
4451 | * Forbid the first pass from falling back to types that fragment | 4454 | * Forbid the first pass from falling back to types that fragment |
4452 | * memory until all local zones are considered. | 4455 | * memory until all local zones are considered. |
4453 | */ | 4456 | */ |
4454 | alloc_flags |= alloc_flags_nofragment(ac.preferred_zoneref->zone); | 4457 | alloc_flags |= alloc_flags_nofragment(ac.preferred_zoneref->zone, gfp_mask); |
4455 | 4458 | ||
4456 | /* First allocation attempt */ | 4459 | /* First allocation attempt */ |
4457 | page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac); | 4460 | page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac); |