From 3a69f2fb730ada06764417f9c68e95311b955a84 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 22 Feb 2013 16:36:06 -0800 Subject: [PATCH] --- yaml --- r: 356629 b: refs/heads/master c: bc56620b493496b8a6962080b644ccc537f4d526 h: refs/heads/master i: 356627: 1b71dea94b6c77dc5ea22436584d46e554a42675 v: v3 --- [refs] | 2 +- trunk/mm/ksm.c | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index a2bf985a36a8..24a5c8c5cb8a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b599cbdf1c2d88eac7caed00854ee4eecb119a6b +refs/heads/master: bc56620b493496b8a6962080b644ccc537f4d526 diff --git a/trunk/mm/ksm.c b/trunk/mm/ksm.c index c059ca1c9356..0320327b8a6c 100644 --- a/trunk/mm/ksm.c +++ b/trunk/mm/ksm.c @@ -150,23 +150,25 @@ struct stable_node { * struct rmap_item - reverse mapping item for virtual addresses * @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list * @anon_vma: pointer to anon_vma for this mm,address, when in stable tree + * @nid: NUMA node id of unstable tree in which linked (may not match page) * @mm: the memory structure this rmap_item is pointing into * @address: the virtual address this rmap_item tracks (+ flags in low bits) * @oldchecksum: previous checksum of the page at that virtual address - * @nid: NUMA node id of unstable tree in which linked (may not match page) * @node: rb node of this rmap_item in the unstable tree * @head: pointer to stable_node heading this list in the stable tree * @hlist: link into hlist of rmap_items hanging off that stable_node */ struct rmap_item { struct rmap_item *rmap_list; - struct anon_vma *anon_vma; /* when stable */ + union { + struct anon_vma *anon_vma; /* when stable */ +#ifdef CONFIG_NUMA + int nid; /* when node of unstable tree */ +#endif + }; struct mm_struct *mm; unsigned long address; /* + low bits used for flags below */ unsigned int oldchecksum; /* when unstable */ -#ifdef CONFIG_NUMA - int nid; -#endif union { struct rb_node node; /* when node of unstable tree */ struct { /* when listed from stable tree */ @@ -1094,6 +1096,9 @@ static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item, if (err) goto out; + /* Unstable nid is in union with stable anon_vma: remove first */ + remove_rmap_item_from_tree(rmap_item); + /* Must get reference to anon_vma while still holding mmap_sem */ rmap_item->anon_vma = vma->anon_vma; get_anon_vma(vma->anon_vma); @@ -1468,14 +1473,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) kpage = try_to_merge_two_pages(rmap_item, page, tree_rmap_item, tree_page); put_page(tree_page); - /* - * As soon as we merge this page, we want to remove the - * rmap_item of the page we have merged with from the unstable - * tree, and insert it instead as new node in the stable tree. - */ if (kpage) { - remove_rmap_item_from_tree(tree_rmap_item); - + /* + * The pages were successfully merged: insert new + * node in the stable tree and add both rmap_items. + */ lock_page(kpage); stable_node = stable_tree_insert(kpage); if (stable_node) {