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>
This commit is contained in:
Mel Gorman 2010-05-24 14:32:29 -07:00 коммит произвёл Linus Torvalds
Родитель 76ab0f530e
Коммит ed4a6d7f06
4 изменённых файлов: 49 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,7 @@
What: /sys/devices/system/node/nodeX/compact
Date: February 2010
Contact: Mel Gorman <mel@csn.ul.ie>
Description:
When this file is written to, all memory within that node
will be compacted. When it completes, memory will be freed
into blocks which have as many contiguous pages as possible

Просмотреть файл

@ -9,6 +9,7 @@
#include <linux/memory.h> #include <linux/memory.h>
#include <linux/node.h> #include <linux/node.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/compaction.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/nodemask.h> #include <linux/nodemask.h>
@ -246,6 +247,8 @@ int register_node(struct node *node, int num, struct node *parent)
scan_unevictable_register_node(node); scan_unevictable_register_node(node);
hugetlb_register_node(node); hugetlb_register_node(node);
compaction_register_node(node);
} }
return error; return error;
} }

Просмотреть файл

@ -12,4 +12,20 @@ extern int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos); void __user *buffer, size_t *length, loff_t *ppos);
#endif /* CONFIG_COMPACTION */ #endif /* CONFIG_COMPACTION */
#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
extern int compaction_register_node(struct node *node);
extern void compaction_unregister_node(struct node *node);
#else
static inline int compaction_register_node(struct node *node)
{
return 0;
}
static inline void compaction_unregister_node(struct node *node)
{
}
#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */
#endif /* _LINUX_COMPACTION_H */ #endif /* _LINUX_COMPACTION_H */

Просмотреть файл

@ -13,6 +13,7 @@
#include <linux/mm_inline.h> #include <linux/mm_inline.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/sysfs.h>
#include "internal.h" #include "internal.h"
/* /*
@ -453,3 +454,25 @@ int sysctl_compaction_handler(struct ctl_table *table, int write,
return 0; return 0;
} }
#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
ssize_t sysfs_compact_node(struct sys_device *dev,
struct sysdev_attribute *attr,
const char *buf, size_t count)
{
compact_node(dev->id);
return count;
}
static SYSDEV_ATTR(compact, S_IWUSR, NULL, sysfs_compact_node);
int compaction_register_node(struct node *node)
{
return sysdev_create_file(&node->sysdev, &attr_compact);
}
void compaction_unregister_node(struct node *node)
{
return sysdev_remove_file(&node->sysdev, &attr_compact);
}
#endif /* CONFIG_SYSFS && CONFIG_NUMA */