diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-08-04 09:14:38 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-08-04 09:14:38 -0400 |
commit | d790d4d583aeaed9fc6f8a9f4d9f8ce6b1c15c7f (patch) | |
tree | 854ab394486288d40fa8179cbfaf66e8bdc44b0f /arch/x86/mm | |
parent | 73b2c7165b76b20eb1290e7efebc33cfd21db1ca (diff) | |
parent | 3a09b1be53d23df780a0cd0e4087a05e2ca4a00c (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/pat.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/pat_rbtree.c | 35 |
2 files changed, 8 insertions, 29 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index acc15b23b743..64121a18b8cb 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -302,7 +302,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
302 | return -EINVAL; | 302 | return -EINVAL; |
303 | } | 303 | } |
304 | 304 | ||
305 | new = kmalloc(sizeof(struct memtype), GFP_KERNEL); | 305 | new = kzalloc(sizeof(struct memtype), GFP_KERNEL); |
306 | if (!new) | 306 | if (!new) |
307 | return -ENOMEM; | 307 | return -ENOMEM; |
308 | 308 | ||
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index f537087bb740..8acaddd0fb21 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c | |||
@@ -34,8 +34,7 @@ | |||
34 | * memtype_lock protects the rbtree. | 34 | * memtype_lock protects the rbtree. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | static void memtype_rb_augment_cb(struct rb_node *node); | 37 | static struct rb_root memtype_rbroot = RB_ROOT; |
38 | static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb); | ||
39 | 38 | ||
40 | static int is_node_overlap(struct memtype *node, u64 start, u64 end) | 39 | static int is_node_overlap(struct memtype *node, u64 start, u64 end) |
41 | { | 40 | { |
@@ -56,7 +55,7 @@ static u64 get_subtree_max_end(struct rb_node *node) | |||
56 | } | 55 | } |
57 | 56 | ||
58 | /* Update 'subtree_max_end' for a node, based on node and its children */ | 57 | /* Update 'subtree_max_end' for a node, based on node and its children */ |
59 | static void update_node_max_end(struct rb_node *node) | 58 | static void memtype_rb_augment_cb(struct rb_node *node, void *__unused) |
60 | { | 59 | { |
61 | struct memtype *data; | 60 | struct memtype *data; |
62 | u64 max_end, child_max_end; | 61 | u64 max_end, child_max_end; |
@@ -78,25 +77,6 @@ static void update_node_max_end(struct rb_node *node) | |||
78 | data->subtree_max_end = max_end; | 77 | data->subtree_max_end = max_end; |
79 | } | 78 | } |
80 | 79 | ||
81 | /* Update 'subtree_max_end' for a node and all its ancestors */ | ||
82 | static void update_path_max_end(struct rb_node *node) | ||
83 | { | ||
84 | u64 old_max_end, new_max_end; | ||
85 | |||
86 | while (node) { | ||
87 | struct memtype *data = container_of(node, struct memtype, rb); | ||
88 | |||
89 | old_max_end = data->subtree_max_end; | ||
90 | update_node_max_end(node); | ||
91 | new_max_end = data->subtree_max_end; | ||
92 | |||
93 | if (new_max_end == old_max_end) | ||
94 | break; | ||
95 | |||
96 | node = rb_parent(node); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* Find the first (lowest start addr) overlapping range from rb tree */ | 80 | /* Find the first (lowest start addr) overlapping range from rb tree */ |
101 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, | 81 | static struct memtype *memtype_rb_lowest_match(struct rb_root *root, |
102 | u64 start, u64 end) | 82 | u64 start, u64 end) |
@@ -190,12 +170,6 @@ failure: | |||
190 | return -EBUSY; | 170 | return -EBUSY; |
191 | } | 171 | } |
192 | 172 | ||
193 | static void memtype_rb_augment_cb(struct rb_node *node) | ||
194 | { | ||
195 | if (node) | ||
196 | update_path_max_end(node); | ||
197 | } | ||
198 | |||
199 | static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | 173 | static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) |
200 | { | 174 | { |
201 | struct rb_node **node = &(root->rb_node); | 175 | struct rb_node **node = &(root->rb_node); |
@@ -213,6 +187,7 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | |||
213 | 187 | ||
214 | rb_link_node(&newdata->rb, parent, node); | 188 | rb_link_node(&newdata->rb, parent, node); |
215 | rb_insert_color(&newdata->rb, root); | 189 | rb_insert_color(&newdata->rb, root); |
190 | rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL); | ||
216 | } | 191 | } |
217 | 192 | ||
218 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | 193 | int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) |
@@ -226,6 +201,7 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | |||
226 | if (ret_type) | 201 | if (ret_type) |
227 | new->type = *ret_type; | 202 | new->type = *ret_type; |
228 | 203 | ||
204 | new->subtree_max_end = new->end; | ||
229 | memtype_rb_insert(&memtype_rbroot, new); | 205 | memtype_rb_insert(&memtype_rbroot, new); |
230 | } | 206 | } |
231 | return err; | 207 | return err; |
@@ -233,13 +209,16 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | |||
233 | 209 | ||
234 | struct memtype *rbt_memtype_erase(u64 start, u64 end) | 210 | struct memtype *rbt_memtype_erase(u64 start, u64 end) |
235 | { | 211 | { |
212 | struct rb_node *deepest; | ||
236 | struct memtype *data; | 213 | struct memtype *data; |
237 | 214 | ||
238 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); | 215 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); |
239 | if (!data) | 216 | if (!data) |
240 | goto out; | 217 | goto out; |
241 | 218 | ||
219 | deepest = rb_augment_erase_begin(&data->rb); | ||
242 | rb_erase(&data->rb, &memtype_rbroot); | 220 | rb_erase(&data->rb, &memtype_rbroot); |
221 | rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL); | ||
243 | out: | 222 | out: |
244 | return data; | 223 | return data; |
245 | } | 224 | } |