aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/internal.h4
-rw-r--r--mm/page_alloc.c26
-rw-r--r--mm/vmscan.c11
3 files changed, 32 insertions, 9 deletions
diff --git a/mm/internal.h b/mm/internal.h
index f02c7508068d..f290c4db528b 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -259,4 +259,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
259 unsigned long start, int len, int flags, 259 unsigned long start, int len, int flags,
260 struct page **pages, struct vm_area_struct **vmas); 260 struct page **pages, struct vm_area_struct **vmas);
261 261
262#define ZONE_RECLAIM_NOSCAN -2
263#define ZONE_RECLAIM_FULL -1
264#define ZONE_RECLAIM_SOME 0
265#define ZONE_RECLAIM_SUCCESS 1
262#endif 266#endif
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6407cbfccd77..2f457a756d46 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1462,15 +1462,33 @@ zonelist_scan:
1462 BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); 1462 BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK);
1463 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { 1463 if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
1464 unsigned long mark; 1464 unsigned long mark;
1465 int ret;
1466
1465 mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK]; 1467 mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];
1466 if (!zone_watermark_ok(zone, order, mark, 1468 if (zone_watermark_ok(zone, order, mark,
1467 classzone_idx, alloc_flags)) { 1469 classzone_idx, alloc_flags))
1468 if (!zone_reclaim_mode || 1470 goto try_this_zone;
1469 !zone_reclaim(zone, gfp_mask, order)) 1471
1472 if (zone_reclaim_mode == 0)
1473 goto this_zone_full;
1474
1475 ret = zone_reclaim(zone, gfp_mask, order);
1476 switch (ret) {
1477 case ZONE_RECLAIM_NOSCAN:
1478 /* did not scan */
1479 goto try_next_zone;
1480 case ZONE_RECLAIM_FULL:
1481 /* scanned but unreclaimable */
1482 goto this_zone_full;
1483 default:
1484 /* did we reclaim enough */
1485 if (!zone_watermark_ok(zone, order, mark,
1486 classzone_idx, alloc_flags))
1470 goto this_zone_full; 1487 goto this_zone_full;
1471 } 1488 }
1472 } 1489 }
1473 1490
1491try_this_zone:
1474 page = buffered_rmqueue(preferred_zone, zone, order, 1492 page = buffered_rmqueue(preferred_zone, zone, order,
1475 gfp_mask, migratetype); 1493 gfp_mask, migratetype);
1476 if (page) 1494 if (page)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 79a98d98ed33..16c82a868e2b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2492,16 +2492,16 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2492 */ 2492 */
2493 if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages && 2493 if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages &&
2494 zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages) 2494 zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
2495 return 0; 2495 return ZONE_RECLAIM_FULL;
2496 2496
2497 if (zone_is_all_unreclaimable(zone)) 2497 if (zone_is_all_unreclaimable(zone))
2498 return 0; 2498 return ZONE_RECLAIM_FULL;
2499 2499
2500 /* 2500 /*
2501 * Do not scan if the allocation should not be delayed. 2501 * Do not scan if the allocation should not be delayed.
2502 */ 2502 */
2503 if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC)) 2503 if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC))
2504 return 0; 2504 return ZONE_RECLAIM_NOSCAN;
2505 2505
2506 /* 2506 /*
2507 * Only run zone reclaim on the local zone or on zones that do not 2507 * Only run zone reclaim on the local zone or on zones that do not
@@ -2511,10 +2511,11 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2511 */ 2511 */
2512 node_id = zone_to_nid(zone); 2512 node_id = zone_to_nid(zone);
2513 if (node_state(node_id, N_CPU) && node_id != numa_node_id()) 2513 if (node_state(node_id, N_CPU) && node_id != numa_node_id())
2514 return 0; 2514 return ZONE_RECLAIM_NOSCAN;
2515 2515
2516 if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED)) 2516 if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
2517 return 0; 2517 return ZONE_RECLAIM_NOSCAN;
2518
2518 ret = __zone_reclaim(zone, gfp_mask, order); 2519 ret = __zone_reclaim(zone, gfp_mask, order);
2519 zone_clear_flag(zone, ZONE_RECLAIM_LOCKED); 2520 zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
2520 2521