diff options
author | Andreas Herrmann <andreas.herrmann3@amd.com> | 2008-06-20 16:07:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-24 07:05:57 -0400 |
commit | 64fe44c38bbdfab4fe052029058ce5fe9804de68 (patch) | |
tree | 64ee256a93b359174cf30ca4d0ac61947bb747e9 /arch/x86/mm | |
parent | f6887264deba4cd991f0ca006918dcff4c939021 (diff) |
x86: pat.c introduce function to check for conflicts with existing memtypes
... to strip down loop body in reserve_memtype.
Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Suresh B Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/pat.c | 96 |
1 files changed, 33 insertions, 63 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 49dcd9652ec8..281ac6489c08 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -178,6 +178,33 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type) | |||
178 | return req_type; | 178 | return req_type; |
179 | } | 179 | } |
180 | 180 | ||
181 | static int chk_conflict(struct memtype *new, struct memtype *entry, | ||
182 | unsigned long *type) | ||
183 | { | ||
184 | if (new->type != entry->type) { | ||
185 | if (type) { | ||
186 | new->type = entry->type; | ||
187 | *type = entry->type; | ||
188 | } else | ||
189 | goto conflict; | ||
190 | } | ||
191 | |||
192 | /* check overlaps with more than one entry in the list */ | ||
193 | list_for_each_entry_continue(entry, &memtype_list, nd) { | ||
194 | if (new->end <= entry->start) | ||
195 | break; | ||
196 | else if (new->type != entry->type) | ||
197 | goto conflict; | ||
198 | } | ||
199 | return 0; | ||
200 | |||
201 | conflict: | ||
202 | printk(KERN_INFO "%s:%d conflicting memory types " | ||
203 | "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start, | ||
204 | new->end, cattr_name(new->type), cattr_name(entry->type)); | ||
205 | return -EBUSY; | ||
206 | } | ||
207 | |||
181 | /* | 208 | /* |
182 | * req_type typically has one of the: | 209 | * req_type typically has one of the: |
183 | * - _PAGE_CACHE_WB | 210 | * - _PAGE_CACHE_WB |
@@ -254,94 +281,37 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
254 | /* Search for existing mapping that overlaps the current range */ | 281 | /* Search for existing mapping that overlaps the current range */ |
255 | where = NULL; | 282 | where = NULL; |
256 | list_for_each_entry(entry, &memtype_list, nd) { | 283 | list_for_each_entry(entry, &memtype_list, nd) { |
257 | struct memtype *saved_ptr; | ||
258 | |||
259 | if (entry->start >= end) { | 284 | if (entry->start >= end) { |
260 | where = entry->nd.prev; | 285 | where = entry->nd.prev; |
261 | break; | 286 | break; |
262 | } | 287 | } |
263 | 288 | ||
264 | if (start <= entry->start && end >= entry->start) { | 289 | if (start <= entry->start && end >= entry->start) { |
265 | if (actual_type != entry->type && new_type) { | 290 | err = chk_conflict(new, entry, new_type); |
266 | actual_type = entry->type; | ||
267 | *new_type = actual_type; | ||
268 | new->type = actual_type; | ||
269 | } | ||
270 | |||
271 | if (actual_type != entry->type) { | ||
272 | err = -EBUSY; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | saved_ptr = entry; | ||
277 | /* | ||
278 | * Check to see whether the request overlaps more | ||
279 | * than one entry in the list | ||
280 | */ | ||
281 | list_for_each_entry_continue(entry, &memtype_list, nd) { | ||
282 | if (end <= entry->start) { | ||
283 | break; | ||
284 | } | ||
285 | |||
286 | if (actual_type != entry->type) { | ||
287 | err = -EBUSY; | ||
288 | break; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (err) { | 291 | if (err) { |
293 | break; | 292 | break; |
294 | } | 293 | } |
295 | 294 | ||
296 | dprintk("Overlap at 0x%Lx-0x%Lx\n", | 295 | dprintk("Overlap at 0x%Lx-0x%Lx\n", |
297 | saved_ptr->start, saved_ptr->end); | 296 | entry->start, entry->end); |
298 | where = saved_ptr->nd.prev; | 297 | where = entry->nd.prev; |
299 | break; | 298 | break; |
300 | } | 299 | } |
301 | 300 | ||
302 | if (start < entry->end) { | 301 | if (start < entry->end) { |
303 | if (actual_type != entry->type && new_type) { | 302 | err = chk_conflict(new, entry, new_type); |
304 | actual_type = entry->type; | ||
305 | *new_type = actual_type; | ||
306 | new->type = actual_type; | ||
307 | } | ||
308 | |||
309 | if (actual_type != entry->type) { | ||
310 | err = -EBUSY; | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | saved_ptr = entry; | ||
315 | /* | ||
316 | * Check to see whether the request overlaps more | ||
317 | * than one entry in the list | ||
318 | */ | ||
319 | list_for_each_entry_continue(entry, &memtype_list, nd) { | ||
320 | if (end <= entry->start) { | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | if (actual_type != entry->type) { | ||
325 | err = -EBUSY; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | if (err) { | 303 | if (err) { |
331 | break; | 304 | break; |
332 | } | 305 | } |
333 | 306 | ||
334 | dprintk("Overlap at 0x%Lx-0x%Lx\n", | 307 | dprintk("Overlap at 0x%Lx-0x%Lx\n", |
335 | saved_ptr->start, saved_ptr->end); | 308 | entry->start, entry->end); |
336 | where = &saved_ptr->nd; | 309 | where = &entry->nd; |
337 | break; | 310 | break; |
338 | } | 311 | } |
339 | } | 312 | } |
340 | 313 | ||
341 | if (err) { | 314 | if (err) { |
342 | printk(KERN_INFO "%s:%d conflicting memory types " | ||
343 | "%Lx-%Lx %s<->%s\n", current->comm, current->pid, start, | ||
344 | end, cattr_name(new->type), cattr_name(entry->type)); | ||
345 | printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " | 315 | printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " |
346 | "track %s, req %s\n", | 316 | "track %s, req %s\n", |
347 | start, end, cattr_name(new->type), cattr_name(req_type)); | 317 | start, end, cattr_name(new->type), cattr_name(req_type)); |