diff options
Diffstat (limited to 'mm/compaction.c')
-rw-r--r-- | mm/compaction.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index be1ff3f7552b..77854fbc0f56 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/compaction.h> | 12 | #include <linux/compaction.h> |
13 | #include <linux/mm_inline.h> | 13 | #include <linux/mm_inline.h> |
14 | #include <linux/backing-dev.h> | 14 | #include <linux/backing-dev.h> |
15 | #include <linux/sysctl.h> | ||
15 | #include "internal.h" | 16 | #include "internal.h" |
16 | 17 | ||
17 | /* | 18 | /* |
@@ -391,3 +392,64 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
391 | 392 | ||
392 | return ret; | 393 | return ret; |
393 | } | 394 | } |
395 | |||
396 | /* Compact all zones within a node */ | ||
397 | static int compact_node(int nid) | ||
398 | { | ||
399 | int zoneid; | ||
400 | pg_data_t *pgdat; | ||
401 | struct zone *zone; | ||
402 | |||
403 | if (nid < 0 || nid >= nr_node_ids || !node_online(nid)) | ||
404 | return -EINVAL; | ||
405 | pgdat = NODE_DATA(nid); | ||
406 | |||
407 | /* Flush pending updates to the LRU lists */ | ||
408 | lru_add_drain_all(); | ||
409 | |||
410 | for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { | ||
411 | struct compact_control cc = { | ||
412 | .nr_freepages = 0, | ||
413 | .nr_migratepages = 0, | ||
414 | }; | ||
415 | |||
416 | zone = &pgdat->node_zones[zoneid]; | ||
417 | if (!populated_zone(zone)) | ||
418 | continue; | ||
419 | |||
420 | cc.zone = zone; | ||
421 | INIT_LIST_HEAD(&cc.freepages); | ||
422 | INIT_LIST_HEAD(&cc.migratepages); | ||
423 | |||
424 | compact_zone(zone, &cc); | ||
425 | |||
426 | VM_BUG_ON(!list_empty(&cc.freepages)); | ||
427 | VM_BUG_ON(!list_empty(&cc.migratepages)); | ||
428 | } | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /* Compact all nodes in the system */ | ||
434 | static int compact_nodes(void) | ||
435 | { | ||
436 | int nid; | ||
437 | |||
438 | for_each_online_node(nid) | ||
439 | compact_node(nid); | ||
440 | |||
441 | return COMPACT_COMPLETE; | ||
442 | } | ||
443 | |||
444 | /* The written value is actually unused, all memory is compacted */ | ||
445 | int sysctl_compact_memory; | ||
446 | |||
447 | /* This is the entry point for compacting all nodes via /proc/sys/vm */ | ||
448 | int sysctl_compaction_handler(struct ctl_table *table, int write, | ||
449 | void __user *buffer, size_t *length, loff_t *ppos) | ||
450 | { | ||
451 | if (write) | ||
452 | return compact_nodes(); | ||
453 | |||
454 | return 0; | ||
455 | } | ||