Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198247
b: refs/heads/master
c: 76ab0f5
h: refs/heads/master
i:
  198245: e6cc5d7
  198243: 222b03c
  198239: d83e277
v: v3
  • Loading branch information
Mel Gorman authored and Linus Torvalds committed May 25, 2010
1 parent 961c425 commit 8fe06cc
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 748446bb6b5a9390b546af38ec899c868a9dbcf0
refs/heads/master: 76ab0f530e4a01d4dc20cdc1d5e87753c579dc18
10 changes: 10 additions & 0 deletions trunk/Documentation/sysctl/vm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ files can be found in mm/swap.c.
Currently, these files are in /proc/sys/vm:

- block_dump
- compact_memory
- dirty_background_bytes
- dirty_background_ratio
- dirty_bytes
Expand Down Expand Up @@ -64,6 +65,15 @@ information on block I/O debugging is in Documentation/laptops/laptop-mode.txt.

==============================================================

compact_memory

Available only when CONFIG_COMPACTION is set. When 1 is written to the file,
all zones are compacted such that free memory is available in contiguous
blocks where possible. This can be important for example in the allocation of
huge pages although processes will also directly compact memory as required.

==============================================================

dirty_background_bytes

Contains the amount of dirty memory at which the pdflush background writeback
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/compaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@
#define COMPACT_PARTIAL 1
#define COMPACT_COMPLETE 2

#ifdef CONFIG_COMPACTION
extern int sysctl_compact_memory;
extern int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos);
#endif /* CONFIG_COMPACTION */

#endif /* _LINUX_COMPACTION_H */
10 changes: 10 additions & 0 deletions trunk/kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <linux/highuid.h>
#include <linux/writeback.h>
#include <linux/ratelimit.h>
#include <linux/compaction.h>
#include <linux/hugetlb.h>
#include <linux/initrd.h>
#include <linux/key.h>
Expand Down Expand Up @@ -1121,6 +1122,15 @@ static struct ctl_table vm_table[] = {
.mode = 0644,
.proc_handler = drop_caches_sysctl_handler,
},
#ifdef CONFIG_COMPACTION
{
.procname = "compact_memory",
.data = &sysctl_compact_memory,
.maxlen = sizeof(int),
.mode = 0200,
.proc_handler = sysctl_compaction_handler,
},
#endif /* CONFIG_COMPACTION */
{
.procname = "min_free_kbytes",
.data = &min_free_kbytes,
Expand Down
62 changes: 62 additions & 0 deletions trunk/mm/compaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/compaction.h>
#include <linux/mm_inline.h>
#include <linux/backing-dev.h>
#include <linux/sysctl.h>
#include "internal.h"

/*
Expand Down Expand Up @@ -391,3 +392,64 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)

return ret;
}

/* Compact all zones within a node */
static int compact_node(int nid)
{
int zoneid;
pg_data_t *pgdat;
struct zone *zone;

if (nid < 0 || nid >= nr_node_ids || !node_online(nid))
return -EINVAL;
pgdat = NODE_DATA(nid);

/* Flush pending updates to the LRU lists */
lru_add_drain_all();

for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
struct compact_control cc = {
.nr_freepages = 0,
.nr_migratepages = 0,
};

zone = &pgdat->node_zones[zoneid];
if (!populated_zone(zone))
continue;

cc.zone = zone;
INIT_LIST_HEAD(&cc.freepages);
INIT_LIST_HEAD(&cc.migratepages);

compact_zone(zone, &cc);

VM_BUG_ON(!list_empty(&cc.freepages));
VM_BUG_ON(!list_empty(&cc.migratepages));
}

return 0;
}

/* Compact all nodes in the system */
static int compact_nodes(void)
{
int nid;

for_each_online_node(nid)
compact_node(nid);

return COMPACT_COMPLETE;
}

/* The written value is actually unused, all memory is compacted */
int sysctl_compact_memory;

/* This is the entry point for compacting all nodes via /proc/sys/vm */
int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
{
if (write)
return compact_nodes();

return 0;
}

0 comments on commit 8fe06cc

Please sign in to comment.