diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/ksm.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -150,23 +150,25 @@ struct stable_node { | |||
150 | * struct rmap_item - reverse mapping item for virtual addresses | 150 | * struct rmap_item - reverse mapping item for virtual addresses |
151 | * @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list | 151 | * @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list |
152 | * @anon_vma: pointer to anon_vma for this mm,address, when in stable tree | 152 | * @anon_vma: pointer to anon_vma for this mm,address, when in stable tree |
153 | * @nid: NUMA node id of unstable tree in which linked (may not match page) | ||
153 | * @mm: the memory structure this rmap_item is pointing into | 154 | * @mm: the memory structure this rmap_item is pointing into |
154 | * @address: the virtual address this rmap_item tracks (+ flags in low bits) | 155 | * @address: the virtual address this rmap_item tracks (+ flags in low bits) |
155 | * @oldchecksum: previous checksum of the page at that virtual address | 156 | * @oldchecksum: previous checksum of the page at that virtual address |
156 | * @nid: NUMA node id of unstable tree in which linked (may not match page) | ||
157 | * @node: rb node of this rmap_item in the unstable tree | 157 | * @node: rb node of this rmap_item in the unstable tree |
158 | * @head: pointer to stable_node heading this list in the stable tree | 158 | * @head: pointer to stable_node heading this list in the stable tree |
159 | * @hlist: link into hlist of rmap_items hanging off that stable_node | 159 | * @hlist: link into hlist of rmap_items hanging off that stable_node |
160 | */ | 160 | */ |
161 | struct rmap_item { | 161 | struct rmap_item { |
162 | struct rmap_item *rmap_list; | 162 | struct rmap_item *rmap_list; |
163 | struct anon_vma *anon_vma; /* when stable */ | 163 | union { |
164 | struct anon_vma *anon_vma; /* when stable */ | ||
165 | #ifdef CONFIG_NUMA | ||
166 | int nid; /* when node of unstable tree */ | ||
167 | #endif | ||
168 | }; | ||
164 | struct mm_struct *mm; | 169 | struct mm_struct *mm; |
165 | unsigned long address; /* + low bits used for flags below */ | 170 | unsigned long address; /* + low bits used for flags below */ |
166 | unsigned int oldchecksum; /* when unstable */ | 171 | unsigned int oldchecksum; /* when unstable */ |
167 | #ifdef CONFIG_NUMA | ||
168 | int nid; | ||
169 | #endif | ||
170 | union { | 172 | union { |
171 | struct rb_node node; /* when node of unstable tree */ | 173 | struct rb_node node; /* when node of unstable tree */ |
172 | struct { /* when listed from stable tree */ | 174 | struct { /* when listed from stable tree */ |
@@ -1094,6 +1096,9 @@ static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item, | |||
1094 | if (err) | 1096 | if (err) |
1095 | goto out; | 1097 | goto out; |
1096 | 1098 | ||
1099 | /* Unstable nid is in union with stable anon_vma: remove first */ | ||
1100 | remove_rmap_item_from_tree(rmap_item); | ||
1101 | |||
1097 | /* Must get reference to anon_vma while still holding mmap_sem */ | 1102 | /* Must get reference to anon_vma while still holding mmap_sem */ |
1098 | rmap_item->anon_vma = vma->anon_vma; | 1103 | rmap_item->anon_vma = vma->anon_vma; |
1099 | get_anon_vma(vma->anon_vma); | 1104 | get_anon_vma(vma->anon_vma); |
@@ -1468,14 +1473,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) | |||
1468 | kpage = try_to_merge_two_pages(rmap_item, page, | 1473 | kpage = try_to_merge_two_pages(rmap_item, page, |
1469 | tree_rmap_item, tree_page); | 1474 | tree_rmap_item, tree_page); |
1470 | put_page(tree_page); | 1475 | put_page(tree_page); |
1471 | /* | ||
1472 | * As soon as we merge this page, we want to remove the | ||
1473 | * rmap_item of the page we have merged with from the unstable | ||
1474 | * tree, and insert it instead as new node in the stable tree. | ||
1475 | */ | ||
1476 | if (kpage) { | 1476 | if (kpage) { |
1477 | remove_rmap_item_from_tree(tree_rmap_item); | 1477 | /* |
1478 | 1478 | * The pages were successfully merged: insert new | |
1479 | * node in the stable tree and add both rmap_items. | ||
1480 | */ | ||
1479 | lock_page(kpage); | 1481 | lock_page(kpage); |
1480 | stable_node = stable_tree_insert(kpage); | 1482 | stable_node = stable_tree_insert(kpage); |
1481 | if (stable_node) { | 1483 | if (stable_node) { |