diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 103 |
1 files changed, 95 insertions, 8 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 269eded9b459..4b8e62a19370 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -74,6 +74,9 @@ struct scan_control { | |||
74 | 74 | ||
75 | int may_writepage; | 75 | int may_writepage; |
76 | 76 | ||
77 | /* Can pages be swapped as part of reclaim? */ | ||
78 | int may_swap; | ||
79 | |||
77 | /* This context's SWAP_CLUSTER_MAX. If freeing memory for | 80 | /* This context's SWAP_CLUSTER_MAX. If freeing memory for |
78 | * suspend, we effectively ignore SWAP_CLUSTER_MAX. | 81 | * suspend, we effectively ignore SWAP_CLUSTER_MAX. |
79 | * In this context, it doesn't matter that we scan the | 82 | * In this context, it doesn't matter that we scan the |
@@ -180,17 +183,20 @@ EXPORT_SYMBOL(remove_shrinker); | |||
180 | * `lru_pages' represents the number of on-LRU pages in all the zones which | 183 | * `lru_pages' represents the number of on-LRU pages in all the zones which |
181 | * are eligible for the caller's allocation attempt. It is used for balancing | 184 | * are eligible for the caller's allocation attempt. It is used for balancing |
182 | * slab reclaim versus page reclaim. | 185 | * slab reclaim versus page reclaim. |
186 | * | ||
187 | * Returns the number of slab objects which we shrunk. | ||
183 | */ | 188 | */ |
184 | static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, | 189 | static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, |
185 | unsigned long lru_pages) | 190 | unsigned long lru_pages) |
186 | { | 191 | { |
187 | struct shrinker *shrinker; | 192 | struct shrinker *shrinker; |
193 | int ret = 0; | ||
188 | 194 | ||
189 | if (scanned == 0) | 195 | if (scanned == 0) |
190 | scanned = SWAP_CLUSTER_MAX; | 196 | scanned = SWAP_CLUSTER_MAX; |
191 | 197 | ||
192 | if (!down_read_trylock(&shrinker_rwsem)) | 198 | if (!down_read_trylock(&shrinker_rwsem)) |
193 | return 0; | 199 | return 1; /* Assume we'll be able to shrink next time */ |
194 | 200 | ||
195 | list_for_each_entry(shrinker, &shrinker_list, list) { | 201 | list_for_each_entry(shrinker, &shrinker_list, list) { |
196 | unsigned long long delta; | 202 | unsigned long long delta; |
@@ -209,10 +215,14 @@ static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, | |||
209 | while (total_scan >= SHRINK_BATCH) { | 215 | while (total_scan >= SHRINK_BATCH) { |
210 | long this_scan = SHRINK_BATCH; | 216 | long this_scan = SHRINK_BATCH; |
211 | int shrink_ret; | 217 | int shrink_ret; |
218 | int nr_before; | ||
212 | 219 | ||
220 | nr_before = (*shrinker->shrinker)(0, gfp_mask); | ||
213 | shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask); | 221 | shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask); |
214 | if (shrink_ret == -1) | 222 | if (shrink_ret == -1) |
215 | break; | 223 | break; |
224 | if (shrink_ret < nr_before) | ||
225 | ret += nr_before - shrink_ret; | ||
216 | mod_page_state(slabs_scanned, this_scan); | 226 | mod_page_state(slabs_scanned, this_scan); |
217 | total_scan -= this_scan; | 227 | total_scan -= this_scan; |
218 | 228 | ||
@@ -222,7 +232,7 @@ static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, | |||
222 | shrinker->nr += total_scan; | 232 | shrinker->nr += total_scan; |
223 | } | 233 | } |
224 | up_read(&shrinker_rwsem); | 234 | up_read(&shrinker_rwsem); |
225 | return 0; | 235 | return ret; |
226 | } | 236 | } |
227 | 237 | ||
228 | /* Called without lock on whether page is mapped, so answer is unstable */ | 238 | /* Called without lock on whether page is mapped, so answer is unstable */ |
@@ -407,7 +417,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) | |||
407 | * Anonymous process memory has backing store? | 417 | * Anonymous process memory has backing store? |
408 | * Try to allocate it some swap space here. | 418 | * Try to allocate it some swap space here. |
409 | */ | 419 | */ |
410 | if (PageAnon(page) && !PageSwapCache(page)) { | 420 | if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) { |
411 | if (!add_to_swap(page)) | 421 | if (!add_to_swap(page)) |
412 | goto activate_locked; | 422 | goto activate_locked; |
413 | } | 423 | } |
@@ -890,7 +900,9 @@ shrink_caches(struct zone **zones, struct scan_control *sc) | |||
890 | if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) | 900 | if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) |
891 | continue; /* Let kswapd poll it */ | 901 | continue; /* Let kswapd poll it */ |
892 | 902 | ||
903 | atomic_inc(&zone->reclaim_in_progress); | ||
893 | shrink_zone(zone, sc); | 904 | shrink_zone(zone, sc); |
905 | atomic_dec(&zone->reclaim_in_progress); | ||
894 | } | 906 | } |
895 | } | 907 | } |
896 | 908 | ||
@@ -907,8 +919,7 @@ shrink_caches(struct zone **zones, struct scan_control *sc) | |||
907 | * holds filesystem locks which prevent writeout this might not work, and the | 919 | * holds filesystem locks which prevent writeout this might not work, and the |
908 | * allocation attempt will fail. | 920 | * allocation attempt will fail. |
909 | */ | 921 | */ |
910 | int try_to_free_pages(struct zone **zones, | 922 | int try_to_free_pages(struct zone **zones, unsigned int gfp_mask) |
911 | unsigned int gfp_mask, unsigned int order) | ||
912 | { | 923 | { |
913 | int priority; | 924 | int priority; |
914 | int ret = 0; | 925 | int ret = 0; |
@@ -920,6 +931,7 @@ int try_to_free_pages(struct zone **zones, | |||
920 | 931 | ||
921 | sc.gfp_mask = gfp_mask; | 932 | sc.gfp_mask = gfp_mask; |
922 | sc.may_writepage = 0; | 933 | sc.may_writepage = 0; |
934 | sc.may_swap = 1; | ||
923 | 935 | ||
924 | inc_page_state(allocstall); | 936 | inc_page_state(allocstall); |
925 | 937 | ||
@@ -1020,6 +1032,7 @@ loop_again: | |||
1020 | total_reclaimed = 0; | 1032 | total_reclaimed = 0; |
1021 | sc.gfp_mask = GFP_KERNEL; | 1033 | sc.gfp_mask = GFP_KERNEL; |
1022 | sc.may_writepage = 0; | 1034 | sc.may_writepage = 0; |
1035 | sc.may_swap = 1; | ||
1023 | sc.nr_mapped = read_page_state(nr_mapped); | 1036 | sc.nr_mapped = read_page_state(nr_mapped); |
1024 | 1037 | ||
1025 | inc_page_state(pageoutrun); | 1038 | inc_page_state(pageoutrun); |
@@ -1079,6 +1092,7 @@ scan: | |||
1079 | */ | 1092 | */ |
1080 | for (i = 0; i <= end_zone; i++) { | 1093 | for (i = 0; i <= end_zone; i++) { |
1081 | struct zone *zone = pgdat->node_zones + i; | 1094 | struct zone *zone = pgdat->node_zones + i; |
1095 | int nr_slab; | ||
1082 | 1096 | ||
1083 | if (zone->present_pages == 0) | 1097 | if (zone->present_pages == 0) |
1084 | continue; | 1098 | continue; |
@@ -1098,16 +1112,19 @@ scan: | |||
1098 | sc.nr_reclaimed = 0; | 1112 | sc.nr_reclaimed = 0; |
1099 | sc.priority = priority; | 1113 | sc.priority = priority; |
1100 | sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; | 1114 | sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; |
1115 | atomic_inc(&zone->reclaim_in_progress); | ||
1101 | shrink_zone(zone, &sc); | 1116 | shrink_zone(zone, &sc); |
1117 | atomic_dec(&zone->reclaim_in_progress); | ||
1102 | reclaim_state->reclaimed_slab = 0; | 1118 | reclaim_state->reclaimed_slab = 0; |
1103 | shrink_slab(sc.nr_scanned, GFP_KERNEL, lru_pages); | 1119 | nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, |
1120 | lru_pages); | ||
1104 | sc.nr_reclaimed += reclaim_state->reclaimed_slab; | 1121 | sc.nr_reclaimed += reclaim_state->reclaimed_slab; |
1105 | total_reclaimed += sc.nr_reclaimed; | 1122 | total_reclaimed += sc.nr_reclaimed; |
1106 | total_scanned += sc.nr_scanned; | 1123 | total_scanned += sc.nr_scanned; |
1107 | if (zone->all_unreclaimable) | 1124 | if (zone->all_unreclaimable) |
1108 | continue; | 1125 | continue; |
1109 | if (zone->pages_scanned >= (zone->nr_active + | 1126 | if (nr_slab == 0 && zone->pages_scanned >= |
1110 | zone->nr_inactive) * 4) | 1127 | (zone->nr_active + zone->nr_inactive) * 4) |
1111 | zone->all_unreclaimable = 1; | 1128 | zone->all_unreclaimable = 1; |
1112 | /* | 1129 | /* |
1113 | * If we've done a decent amount of scanning and | 1130 | * If we've done a decent amount of scanning and |
@@ -1309,3 +1326,73 @@ static int __init kswapd_init(void) | |||
1309 | } | 1326 | } |
1310 | 1327 | ||
1311 | module_init(kswapd_init) | 1328 | module_init(kswapd_init) |
1329 | |||
1330 | |||
1331 | /* | ||
1332 | * Try to free up some pages from this zone through reclaim. | ||
1333 | */ | ||
1334 | int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order) | ||
1335 | { | ||
1336 | struct scan_control sc; | ||
1337 | int nr_pages = 1 << order; | ||
1338 | int total_reclaimed = 0; | ||
1339 | |||
1340 | /* The reclaim may sleep, so don't do it if sleep isn't allowed */ | ||
1341 | if (!(gfp_mask & __GFP_WAIT)) | ||
1342 | return 0; | ||
1343 | if (zone->all_unreclaimable) | ||
1344 | return 0; | ||
1345 | |||
1346 | sc.gfp_mask = gfp_mask; | ||
1347 | sc.may_writepage = 0; | ||
1348 | sc.may_swap = 0; | ||
1349 | sc.nr_mapped = read_page_state(nr_mapped); | ||
1350 | sc.nr_scanned = 0; | ||
1351 | sc.nr_reclaimed = 0; | ||
1352 | /* scan at the highest priority */ | ||
1353 | sc.priority = 0; | ||
1354 | |||
1355 | if (nr_pages > SWAP_CLUSTER_MAX) | ||
1356 | sc.swap_cluster_max = nr_pages; | ||
1357 | else | ||
1358 | sc.swap_cluster_max = SWAP_CLUSTER_MAX; | ||
1359 | |||
1360 | /* Don't reclaim the zone if there are other reclaimers active */ | ||
1361 | if (!atomic_inc_and_test(&zone->reclaim_in_progress)) | ||
1362 | goto out; | ||
1363 | |||
1364 | shrink_zone(zone, &sc); | ||
1365 | total_reclaimed = sc.nr_reclaimed; | ||
1366 | |||
1367 | out: | ||
1368 | atomic_dec(&zone->reclaim_in_progress); | ||
1369 | return total_reclaimed; | ||
1370 | } | ||
1371 | |||
1372 | asmlinkage long sys_set_zone_reclaim(unsigned int node, unsigned int zone, | ||
1373 | unsigned int state) | ||
1374 | { | ||
1375 | struct zone *z; | ||
1376 | int i; | ||
1377 | |||
1378 | if (node >= MAX_NUMNODES || !node_online(node)) | ||
1379 | return -EINVAL; | ||
1380 | |||
1381 | /* This will break if we ever add more zones */ | ||
1382 | if (!(zone & (1<<ZONE_DMA|1<<ZONE_NORMAL|1<<ZONE_HIGHMEM))) | ||
1383 | return -EINVAL; | ||
1384 | |||
1385 | for (i = 0; i < MAX_NR_ZONES; i++) { | ||
1386 | if (!(zone & 1<<i)) | ||
1387 | continue; | ||
1388 | |||
1389 | z = &NODE_DATA(node)->node_zones[i]; | ||
1390 | |||
1391 | if (state) | ||
1392 | z->reclaim_pages = 1; | ||
1393 | else | ||
1394 | z->reclaim_pages = 0; | ||
1395 | } | ||
1396 | |||
1397 | return 0; | ||
1398 | } | ||