diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 6379ddbffd9b..7da846960d8a 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1323,3 +1323,67 @@ static int __init kswapd_init(void) | |||
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | module_init(kswapd_init) | 1325 | module_init(kswapd_init) |
1326 | |||
1327 | |||
1328 | /* | ||
1329 | * Try to free up some pages from this zone through reclaim. | ||
1330 | */ | ||
1331 | int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order) | ||
1332 | { | ||
1333 | struct scan_control sc; | ||
1334 | int nr_pages = 1 << order; | ||
1335 | int total_reclaimed = 0; | ||
1336 | |||
1337 | /* The reclaim may sleep, so don't do it if sleep isn't allowed */ | ||
1338 | if (!(gfp_mask & __GFP_WAIT)) | ||
1339 | return 0; | ||
1340 | if (zone->all_unreclaimable) | ||
1341 | return 0; | ||
1342 | |||
1343 | sc.gfp_mask = gfp_mask; | ||
1344 | sc.may_writepage = 0; | ||
1345 | sc.may_swap = 0; | ||
1346 | sc.nr_mapped = read_page_state(nr_mapped); | ||
1347 | sc.nr_scanned = 0; | ||
1348 | sc.nr_reclaimed = 0; | ||
1349 | /* scan at the highest priority */ | ||
1350 | sc.priority = 0; | ||
1351 | |||
1352 | if (nr_pages > SWAP_CLUSTER_MAX) | ||
1353 | sc.swap_cluster_max = nr_pages; | ||
1354 | else | ||
1355 | sc.swap_cluster_max = SWAP_CLUSTER_MAX; | ||
1356 | |||
1357 | shrink_zone(zone, &sc); | ||
1358 | total_reclaimed = sc.nr_reclaimed; | ||
1359 | |||
1360 | return total_reclaimed; | ||
1361 | } | ||
1362 | |||
1363 | asmlinkage long sys_set_zone_reclaim(unsigned int node, unsigned int zone, | ||
1364 | unsigned int state) | ||
1365 | { | ||
1366 | struct zone *z; | ||
1367 | int i; | ||
1368 | |||
1369 | if (node >= MAX_NUMNODES || !node_online(node)) | ||
1370 | return -EINVAL; | ||
1371 | |||
1372 | /* This will break if we ever add more zones */ | ||
1373 | if (!(zone & (1<<ZONE_DMA|1<<ZONE_NORMAL|1<<ZONE_HIGHMEM))) | ||
1374 | return -EINVAL; | ||
1375 | |||
1376 | for (i = 0; i < MAX_NR_ZONES; i++) { | ||
1377 | if (!(zone & 1<<i)) | ||
1378 | continue; | ||
1379 | |||
1380 | z = &NODE_DATA(node)->node_zones[i]; | ||
1381 | |||
1382 | if (state) | ||
1383 | z->reclaim_pages = 1; | ||
1384 | else | ||
1385 | z->reclaim_pages = 0; | ||
1386 | } | ||
1387 | |||
1388 | return 0; | ||
1389 | } | ||