Commit ed4a6d7f0676db50b5023cc01f6cda82a2f2a307
Committed by
Linus Torvalds
1 parent
76ab0f530e
Exists in
master
and in
20 other branches
mm: compaction: add /sys trigger for per-node memory compaction
Add a per-node sysfs file called compact. When the file is written to, each zone in that node is compacted. The intention that this would be used by something like a job scheduler in a batch system before a job starts so that the job can allocate the maximum number of hugepages without significant start-up cost. Signed-off-by: Mel Gorman <mel@csn.ul.ie> Acked-by: Rik van Riel <riel@redhat.com> Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Reviewed-by: Christoph Lameter <cl@linux-foundation.org> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 4 changed files with 49 additions and 0 deletions Side-by-side Diff
Documentation/ABI/testing/sysfs-devices-node
1 | +What: /sys/devices/system/node/nodeX/compact | |
2 | +Date: February 2010 | |
3 | +Contact: Mel Gorman <mel@csn.ul.ie> | |
4 | +Description: | |
5 | + When this file is written to, all memory within that node | |
6 | + will be compacted. When it completes, memory will be freed | |
7 | + into blocks which have as many contiguous pages as possible |
drivers/base/node.c
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | #include <linux/memory.h> |
10 | 10 | #include <linux/node.h> |
11 | 11 | #include <linux/hugetlb.h> |
12 | +#include <linux/compaction.h> | |
12 | 13 | #include <linux/cpumask.h> |
13 | 14 | #include <linux/topology.h> |
14 | 15 | #include <linux/nodemask.h> |
... | ... | @@ -246,6 +247,8 @@ |
246 | 247 | scan_unevictable_register_node(node); |
247 | 248 | |
248 | 249 | hugetlb_register_node(node); |
250 | + | |
251 | + compaction_register_node(node); | |
249 | 252 | } |
250 | 253 | return error; |
251 | 254 | } |
include/linux/compaction.h
... | ... | @@ -12,5 +12,21 @@ |
12 | 12 | void __user *buffer, size_t *length, loff_t *ppos); |
13 | 13 | #endif /* CONFIG_COMPACTION */ |
14 | 14 | |
15 | +#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) | |
16 | +extern int compaction_register_node(struct node *node); | |
17 | +extern void compaction_unregister_node(struct node *node); | |
18 | + | |
19 | +#else | |
20 | + | |
21 | +static inline int compaction_register_node(struct node *node) | |
22 | +{ | |
23 | + return 0; | |
24 | +} | |
25 | + | |
26 | +static inline void compaction_unregister_node(struct node *node) | |
27 | +{ | |
28 | +} | |
29 | +#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */ | |
30 | + | |
15 | 31 | #endif /* _LINUX_COMPACTION_H */ |
mm/compaction.c
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | #include <linux/mm_inline.h> |
14 | 14 | #include <linux/backing-dev.h> |
15 | 15 | #include <linux/sysctl.h> |
16 | +#include <linux/sysfs.h> | |
16 | 17 | #include "internal.h" |
17 | 18 | |
18 | 19 | /* |
... | ... | @@ -453,4 +454,26 @@ |
453 | 454 | |
454 | 455 | return 0; |
455 | 456 | } |
457 | + | |
458 | +#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) | |
459 | +ssize_t sysfs_compact_node(struct sys_device *dev, | |
460 | + struct sysdev_attribute *attr, | |
461 | + const char *buf, size_t count) | |
462 | +{ | |
463 | + compact_node(dev->id); | |
464 | + | |
465 | + return count; | |
466 | +} | |
467 | +static SYSDEV_ATTR(compact, S_IWUSR, NULL, sysfs_compact_node); | |
468 | + | |
469 | +int compaction_register_node(struct node *node) | |
470 | +{ | |
471 | + return sysdev_create_file(&node->sysdev, &attr_compact); | |
472 | +} | |
473 | + | |
474 | +void compaction_unregister_node(struct node *node) | |
475 | +{ | |
476 | + return sysdev_remove_file(&node->sysdev, &attr_compact); | |
477 | +} | |
478 | +#endif /* CONFIG_SYSFS && CONFIG_NUMA */ |