Commit ed4a6d7f0676db50b5023cc01f6cda82a2f2a307

Authored by Mel Gorman
Committed by Linus Torvalds
1 parent 76ab0f530e

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
... ... @@ -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 */
... ... @@ -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 */