aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/mmap.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index bdcea6310fff..ff93f6c8436c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -322,31 +322,45 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)
322#ifdef CONFIG_DEBUG_VM_RB 322#ifdef CONFIG_DEBUG_VM_RB
323static int browse_rb(struct rb_root *root) 323static int browse_rb(struct rb_root *root)
324{ 324{
325 int i = 0, j; 325 int i = 0, j, bug = 0;
326 struct rb_node *nd, *pn = NULL; 326 struct rb_node *nd, *pn = NULL;
327 unsigned long prev = 0, pend = 0; 327 unsigned long prev = 0, pend = 0;
328 328
329 for (nd = rb_first(root); nd; nd = rb_next(nd)) { 329 for (nd = rb_first(root); nd; nd = rb_next(nd)) {
330 struct vm_area_struct *vma; 330 struct vm_area_struct *vma;
331 vma = rb_entry(nd, struct vm_area_struct, vm_rb); 331 vma = rb_entry(nd, struct vm_area_struct, vm_rb);
332 if (vma->vm_start < prev) 332 if (vma->vm_start < prev) {
333 printk("vm_start %lx prev %lx\n", vma->vm_start, prev), i = -1; 333 printk("vm_start %lx prev %lx\n", vma->vm_start, prev);
334 if (vma->vm_start < pend) 334 bug = 1;
335 }
336 if (vma->vm_start < pend) {
335 printk("vm_start %lx pend %lx\n", vma->vm_start, pend); 337 printk("vm_start %lx pend %lx\n", vma->vm_start, pend);
336 if (vma->vm_start > vma->vm_end) 338 bug = 1;
337 printk("vm_end %lx < vm_start %lx\n", vma->vm_end, vma->vm_start); 339 }
340 if (vma->vm_start > vma->vm_end) {
341 printk("vm_end %lx < vm_start %lx\n",
342 vma->vm_end, vma->vm_start);
343 bug = 1;
344 }
345 if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
346 printk("free gap %lx, correct %lx\n",
347 vma->rb_subtree_gap,
348 vma_compute_subtree_gap(vma));
349 bug = 1;
350 }
338 i++; 351 i++;
339 pn = nd; 352 pn = nd;
340 prev = vma->vm_start; 353 prev = vma->vm_start;
341 pend = vma->vm_end; 354 pend = vma->vm_end;
342 } 355 }
343 j = 0; 356 j = 0;
344 for (nd = pn; nd; nd = rb_prev(nd)) { 357 for (nd = pn; nd; nd = rb_prev(nd))
345 j++; 358 j++;
359 if (i != j) {
360 printk("backwards %d, forwards %d\n", j, i);
361 bug = 1;
346 } 362 }
347 if (i != j) 363 return bug ? -1 : i;
348 printk("backwards %d, forwards %d\n", j, i), i = 0;
349 return i;
350} 364}
351 365
352static void validate_mm_rb(struct rb_root *root, struct vm_area_struct *ignore) 366static void validate_mm_rb(struct rb_root *root, struct vm_area_struct *ignore)
@@ -365,6 +379,7 @@ void validate_mm(struct mm_struct *mm)
365{ 379{
366 int bug = 0; 380 int bug = 0;
367 int i = 0; 381 int i = 0;
382 unsigned long highest_address = 0;
368 struct vm_area_struct *vma = mm->mmap; 383 struct vm_area_struct *vma = mm->mmap;
369 while (vma) { 384 while (vma) {
370 struct anon_vma_chain *avc; 385 struct anon_vma_chain *avc;
@@ -372,14 +387,24 @@ void validate_mm(struct mm_struct *mm)
372 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) 387 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
373 anon_vma_interval_tree_verify(avc); 388 anon_vma_interval_tree_verify(avc);
374 vma_unlock_anon_vma(vma); 389 vma_unlock_anon_vma(vma);
390 highest_address = vma->vm_end;
375 vma = vma->vm_next; 391 vma = vma->vm_next;
376 i++; 392 i++;
377 } 393 }
378 if (i != mm->map_count) 394 if (i != mm->map_count) {
379 printk("map_count %d vm_next %d\n", mm->map_count, i), bug = 1; 395 printk("map_count %d vm_next %d\n", mm->map_count, i);
396 bug = 1;
397 }
398 if (highest_address != mm->highest_vm_end) {
399 printk("mm->highest_vm_end %lx, found %lx\n",
400 mm->highest_vm_end, highest_address);
401 bug = 1;
402 }
380 i = browse_rb(&mm->mm_rb); 403 i = browse_rb(&mm->mm_rb);
381 if (i != mm->map_count) 404 if (i != mm->map_count) {
382 printk("map_count %d rb %d\n", mm->map_count, i), bug = 1; 405 printk("map_count %d rb %d\n", mm->map_count, i);
406 bug = 1;
407 }
383 BUG_ON(bug); 408 BUG_ON(bug);
384} 409}
385#else 410#else