aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pat.c
diff options
context:
space:
mode:
authorAndreas Herrmann <andreas.herrmann3@amd.com>2008-06-20 16:07:09 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-24 07:05:57 -0400
commit64fe44c38bbdfab4fe052029058ce5fe9804de68 (patch)
tree64ee256a93b359174cf30ca4d0ac61947bb747e9 /arch/x86/mm/pat.c
parentf6887264deba4cd991f0ca006918dcff4c939021 (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/pat.c')
-rw-r--r--arch/x86/mm/pat.c96
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
181static 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));