aboutsummaryrefslogtreecommitdiffstats
path: root/mm/ksm.c
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2013-02-22 19:36:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:24 -0500
commitef53d16cded7f89b3843b7a96970dab897843ea5 (patch)
tree3098af6a91b088212acb5c459ee9af1488cfdfe1 /mm/ksm.c
parent56f31801ccdecb420d0d1fd2bf9f337c355214a9 (diff)
ksm: allocate roots when needed
It is a pity to have MAX_NUMNODES+MAX_NUMNODES tree roots statically allocated, particularly when very few users will ever actually tune merge_across_nodes 0 to use more than 1+1 of those trees. Not a big deal (only 16kB wasted on each machine with CONFIG_MAXSMP), but a pity. Start off with 1+1 statically allocated, then if merge_across_nodes is ever tuned, allocate for nr_node_ids+nr_node_ids. Do not attempt to free up the extra if it's tuned back, that would be a waste of effort. Signed-off-by: Hugh Dickins <hughd@google.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Petr Holasek <pholasek@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Izik Eidus <izik.eidus@ravellosystems.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/ksm.c')
-rw-r--r--mm/ksm.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/mm/ksm.c b/mm/ksm.c
index d61cba6fa1dc..ab2ba9ad3c59 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -183,8 +183,10 @@ struct rmap_item {
183#define STABLE_FLAG 0x200 /* is listed from the stable tree */ 183#define STABLE_FLAG 0x200 /* is listed from the stable tree */
184 184
185/* The stable and unstable tree heads */ 185/* The stable and unstable tree heads */
186static struct rb_root root_unstable_tree[MAX_NUMNODES]; 186static struct rb_root one_stable_tree[1] = { RB_ROOT };
187static struct rb_root root_stable_tree[MAX_NUMNODES]; 187static struct rb_root one_unstable_tree[1] = { RB_ROOT };
188static struct rb_root *root_stable_tree = one_stable_tree;
189static struct rb_root *root_unstable_tree = one_unstable_tree;
188 190
189/* Recently migrated nodes of stable tree, pending proper placement */ 191/* Recently migrated nodes of stable tree, pending proper placement */
190static LIST_HEAD(migrate_nodes); 192static LIST_HEAD(migrate_nodes);
@@ -224,8 +226,10 @@ static unsigned int ksm_thread_sleep_millisecs = 20;
224#ifdef CONFIG_NUMA 226#ifdef CONFIG_NUMA
225/* Zeroed when merging across nodes is not allowed */ 227/* Zeroed when merging across nodes is not allowed */
226static unsigned int ksm_merge_across_nodes = 1; 228static unsigned int ksm_merge_across_nodes = 1;
229static int ksm_nr_node_ids = 1;
227#else 230#else
228#define ksm_merge_across_nodes 1U 231#define ksm_merge_across_nodes 1U
232#define ksm_nr_node_ids 1
229#endif 233#endif
230 234
231#define KSM_RUN_STOP 0 235#define KSM_RUN_STOP 0
@@ -508,7 +512,7 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node)
508 list_del(&stable_node->list); 512 list_del(&stable_node->list);
509 else 513 else
510 rb_erase(&stable_node->node, 514 rb_erase(&stable_node->node,
511 &root_stable_tree[NUMA(stable_node->nid)]); 515 root_stable_tree + NUMA(stable_node->nid));
512 free_stable_node(stable_node); 516 free_stable_node(stable_node);
513} 517}
514 518
@@ -644,7 +648,7 @@ static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
644 BUG_ON(age > 1); 648 BUG_ON(age > 1);
645 if (!age) 649 if (!age)
646 rb_erase(&rmap_item->node, 650 rb_erase(&rmap_item->node,
647 &root_unstable_tree[NUMA(rmap_item->nid)]); 651 root_unstable_tree + NUMA(rmap_item->nid));
648 ksm_pages_unshared--; 652 ksm_pages_unshared--;
649 rmap_item->address &= PAGE_MASK; 653 rmap_item->address &= PAGE_MASK;
650 } 654 }
@@ -742,7 +746,7 @@ static int remove_all_stable_nodes(void)
742 int nid; 746 int nid;
743 int err = 0; 747 int err = 0;
744 748
745 for (nid = 0; nid < nr_node_ids; nid++) { 749 for (nid = 0; nid < ksm_nr_node_ids; nid++) {
746 while (root_stable_tree[nid].rb_node) { 750 while (root_stable_tree[nid].rb_node) {
747 stable_node = rb_entry(root_stable_tree[nid].rb_node, 751 stable_node = rb_entry(root_stable_tree[nid].rb_node,
748 struct stable_node, node); 752 struct stable_node, node);
@@ -1150,6 +1154,7 @@ static struct page *try_to_merge_two_pages(struct rmap_item *rmap_item,
1150static struct page *stable_tree_search(struct page *page) 1154static struct page *stable_tree_search(struct page *page)
1151{ 1155{
1152 int nid; 1156 int nid;
1157 struct rb_root *root;
1153 struct rb_node **new; 1158 struct rb_node **new;
1154 struct rb_node *parent; 1159 struct rb_node *parent;
1155 struct stable_node *stable_node; 1160 struct stable_node *stable_node;
@@ -1163,8 +1168,9 @@ static struct page *stable_tree_search(struct page *page)
1163 } 1168 }
1164 1169
1165 nid = get_kpfn_nid(page_to_pfn(page)); 1170 nid = get_kpfn_nid(page_to_pfn(page));
1171 root = root_stable_tree + nid;
1166again: 1172again:
1167 new = &root_stable_tree[nid].rb_node; 1173 new = &root->rb_node;
1168 parent = NULL; 1174 parent = NULL;
1169 1175
1170 while (*new) { 1176 while (*new) {
@@ -1219,7 +1225,7 @@ again:
1219 list_del(&page_node->list); 1225 list_del(&page_node->list);
1220 DO_NUMA(page_node->nid = nid); 1226 DO_NUMA(page_node->nid = nid);
1221 rb_link_node(&page_node->node, parent, new); 1227 rb_link_node(&page_node->node, parent, new);
1222 rb_insert_color(&page_node->node, &root_stable_tree[nid]); 1228 rb_insert_color(&page_node->node, root);
1223 get_page(page); 1229 get_page(page);
1224 return page; 1230 return page;
1225 1231
@@ -1227,11 +1233,10 @@ replace:
1227 if (page_node) { 1233 if (page_node) {
1228 list_del(&page_node->list); 1234 list_del(&page_node->list);
1229 DO_NUMA(page_node->nid = nid); 1235 DO_NUMA(page_node->nid = nid);
1230 rb_replace_node(&stable_node->node, 1236 rb_replace_node(&stable_node->node, &page_node->node, root);
1231 &page_node->node, &root_stable_tree[nid]);
1232 get_page(page); 1237 get_page(page);
1233 } else { 1238 } else {
1234 rb_erase(&stable_node->node, &root_stable_tree[nid]); 1239 rb_erase(&stable_node->node, root);
1235 page = NULL; 1240 page = NULL;
1236 } 1241 }
1237 stable_node->head = &migrate_nodes; 1242 stable_node->head = &migrate_nodes;
@@ -1250,13 +1255,15 @@ static struct stable_node *stable_tree_insert(struct page *kpage)
1250{ 1255{
1251 int nid; 1256 int nid;
1252 unsigned long kpfn; 1257 unsigned long kpfn;
1258 struct rb_root *root;
1253 struct rb_node **new; 1259 struct rb_node **new;
1254 struct rb_node *parent = NULL; 1260 struct rb_node *parent = NULL;
1255 struct stable_node *stable_node; 1261 struct stable_node *stable_node;
1256 1262
1257 kpfn = page_to_pfn(kpage); 1263 kpfn = page_to_pfn(kpage);
1258 nid = get_kpfn_nid(kpfn); 1264 nid = get_kpfn_nid(kpfn);
1259 new = &root_stable_tree[nid].rb_node; 1265 root = root_stable_tree + nid;
1266 new = &root->rb_node;
1260 1267
1261 while (*new) { 1268 while (*new) {
1262 struct page *tree_page; 1269 struct page *tree_page;
@@ -1295,7 +1302,7 @@ static struct stable_node *stable_tree_insert(struct page *kpage)
1295 set_page_stable_node(kpage, stable_node); 1302 set_page_stable_node(kpage, stable_node);
1296 DO_NUMA(stable_node->nid = nid); 1303 DO_NUMA(stable_node->nid = nid);
1297 rb_link_node(&stable_node->node, parent, new); 1304 rb_link_node(&stable_node->node, parent, new);
1298 rb_insert_color(&stable_node->node, &root_stable_tree[nid]); 1305 rb_insert_color(&stable_node->node, root);
1299 1306
1300 return stable_node; 1307 return stable_node;
1301} 1308}
@@ -1325,7 +1332,7 @@ struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item,
1325 int nid; 1332 int nid;
1326 1333
1327 nid = get_kpfn_nid(page_to_pfn(page)); 1334 nid = get_kpfn_nid(page_to_pfn(page));
1328 root = &root_unstable_tree[nid]; 1335 root = root_unstable_tree + nid;
1329 new = &root->rb_node; 1336 new = &root->rb_node;
1330 1337
1331 while (*new) { 1338 while (*new) {
@@ -1422,7 +1429,7 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
1422 if (stable_node->head != &migrate_nodes && 1429 if (stable_node->head != &migrate_nodes &&
1423 get_kpfn_nid(stable_node->kpfn) != NUMA(stable_node->nid)) { 1430 get_kpfn_nid(stable_node->kpfn) != NUMA(stable_node->nid)) {
1424 rb_erase(&stable_node->node, 1431 rb_erase(&stable_node->node,
1425 &root_stable_tree[NUMA(stable_node->nid)]); 1432 root_stable_tree + NUMA(stable_node->nid));
1426 stable_node->head = &migrate_nodes; 1433 stable_node->head = &migrate_nodes;
1427 list_add(&stable_node->list, stable_node->head); 1434 list_add(&stable_node->list, stable_node->head);
1428 } 1435 }
@@ -1574,7 +1581,7 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page)
1574 } 1581 }
1575 } 1582 }
1576 1583
1577 for (nid = 0; nid < nr_node_ids; nid++) 1584 for (nid = 0; nid < ksm_nr_node_ids; nid++)
1578 root_unstable_tree[nid] = RB_ROOT; 1585 root_unstable_tree[nid] = RB_ROOT;
1579 1586
1580 spin_lock(&ksm_mmlist_lock); 1587 spin_lock(&ksm_mmlist_lock);
@@ -2094,8 +2101,8 @@ static void ksm_check_stable_tree(unsigned long start_pfn,
2094 struct rb_node *node; 2101 struct rb_node *node;
2095 int nid; 2102 int nid;
2096 2103
2097 for (nid = 0; nid < nr_node_ids; nid++) { 2104 for (nid = 0; nid < ksm_nr_node_ids; nid++) {
2098 node = rb_first(&root_stable_tree[nid]); 2105 node = rb_first(root_stable_tree + nid);
2099 while (node) { 2106 while (node) {
2100 stable_node = rb_entry(node, struct stable_node, node); 2107 stable_node = rb_entry(node, struct stable_node, node);
2101 if (stable_node->kpfn >= start_pfn && 2108 if (stable_node->kpfn >= start_pfn &&
@@ -2105,7 +2112,7 @@ static void ksm_check_stable_tree(unsigned long start_pfn,
2105 * which is why we keep kpfn instead of page* 2112 * which is why we keep kpfn instead of page*
2106 */ 2113 */
2107 remove_node_from_stable_tree(stable_node); 2114 remove_node_from_stable_tree(stable_node);
2108 node = rb_first(&root_stable_tree[nid]); 2115 node = rb_first(root_stable_tree + nid);
2109 } else 2116 } else
2110 node = rb_next(node); 2117 node = rb_next(node);
2111 cond_resched(); 2118 cond_resched();
@@ -2298,8 +2305,31 @@ static ssize_t merge_across_nodes_store(struct kobject *kobj,
2298 if (ksm_merge_across_nodes != knob) { 2305 if (ksm_merge_across_nodes != knob) {
2299 if (ksm_pages_shared || remove_all_stable_nodes()) 2306 if (ksm_pages_shared || remove_all_stable_nodes())
2300 err = -EBUSY; 2307 err = -EBUSY;
2301 else 2308 else if (root_stable_tree == one_stable_tree) {
2309 struct rb_root *buf;
2310 /*
2311 * This is the first time that we switch away from the
2312 * default of merging across nodes: must now allocate
2313 * a buffer to hold as many roots as may be needed.
2314 * Allocate stable and unstable together:
2315 * MAXSMP NODES_SHIFT 10 will use 16kB.
2316 */
2317 buf = kcalloc(nr_node_ids + nr_node_ids,
2318 sizeof(*buf), GFP_KERNEL | __GFP_ZERO);
2319 /* Let us assume that RB_ROOT is NULL is zero */
2320 if (!buf)
2321 err = -ENOMEM;
2322 else {
2323 root_stable_tree = buf;
2324 root_unstable_tree = buf + nr_node_ids;
2325 /* Stable tree is empty but not the unstable */
2326 root_unstable_tree[0] = one_unstable_tree[0];
2327 }
2328 }
2329 if (!err) {
2302 ksm_merge_across_nodes = knob; 2330 ksm_merge_across_nodes = knob;
2331 ksm_nr_node_ids = knob ? 1 : nr_node_ids;
2332 }
2303 } 2333 }
2304 mutex_unlock(&ksm_thread_mutex); 2334 mutex_unlock(&ksm_thread_mutex);
2305 2335
@@ -2378,15 +2408,11 @@ static int __init ksm_init(void)
2378{ 2408{
2379 struct task_struct *ksm_thread; 2409 struct task_struct *ksm_thread;
2380 int err; 2410 int err;
2381 int nid;
2382 2411
2383 err = ksm_slab_init(); 2412 err = ksm_slab_init();
2384 if (err) 2413 if (err)
2385 goto out; 2414 goto out;
2386 2415
2387 for (nid = 0; nid < nr_node_ids; nid++)
2388 root_stable_tree[nid] = RB_ROOT;
2389
2390 ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd"); 2416 ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd");
2391 if (IS_ERR(ksm_thread)) { 2417 if (IS_ERR(ksm_thread)) {
2392 printk(KERN_ERR "ksm: creating kthread failed\n"); 2418 printk(KERN_ERR "ksm: creating kthread failed\n");