diff options
Diffstat (limited to 'mm/nommu.c')
-rw-r--r-- | mm/nommu.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/mm/nommu.c b/mm/nommu.c index 5afce48ce339..0b16cb4c517b 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -680,9 +680,9 @@ static void protect_vma(struct vm_area_struct *vma, unsigned long flags) | |||
680 | */ | 680 | */ |
681 | static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | 681 | static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) |
682 | { | 682 | { |
683 | struct vm_area_struct *pvma, **pp, *next; | 683 | struct vm_area_struct *pvma, *prev; |
684 | struct address_space *mapping; | 684 | struct address_space *mapping; |
685 | struct rb_node **p, *parent; | 685 | struct rb_node **p, *parent, *rb_prev; |
686 | 686 | ||
687 | kenter(",%p", vma); | 687 | kenter(",%p", vma); |
688 | 688 | ||
@@ -703,7 +703,7 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | |||
703 | } | 703 | } |
704 | 704 | ||
705 | /* add the VMA to the tree */ | 705 | /* add the VMA to the tree */ |
706 | parent = NULL; | 706 | parent = rb_prev = NULL; |
707 | p = &mm->mm_rb.rb_node; | 707 | p = &mm->mm_rb.rb_node; |
708 | while (*p) { | 708 | while (*p) { |
709 | parent = *p; | 709 | parent = *p; |
@@ -713,17 +713,20 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | |||
713 | * (the latter is necessary as we may get identical VMAs) */ | 713 | * (the latter is necessary as we may get identical VMAs) */ |
714 | if (vma->vm_start < pvma->vm_start) | 714 | if (vma->vm_start < pvma->vm_start) |
715 | p = &(*p)->rb_left; | 715 | p = &(*p)->rb_left; |
716 | else if (vma->vm_start > pvma->vm_start) | 716 | else if (vma->vm_start > pvma->vm_start) { |
717 | rb_prev = parent; | ||
717 | p = &(*p)->rb_right; | 718 | p = &(*p)->rb_right; |
718 | else if (vma->vm_end < pvma->vm_end) | 719 | } else if (vma->vm_end < pvma->vm_end) |
719 | p = &(*p)->rb_left; | 720 | p = &(*p)->rb_left; |
720 | else if (vma->vm_end > pvma->vm_end) | 721 | else if (vma->vm_end > pvma->vm_end) { |
722 | rb_prev = parent; | ||
721 | p = &(*p)->rb_right; | 723 | p = &(*p)->rb_right; |
722 | else if (vma < pvma) | 724 | } else if (vma < pvma) |
723 | p = &(*p)->rb_left; | 725 | p = &(*p)->rb_left; |
724 | else if (vma > pvma) | 726 | else if (vma > pvma) { |
727 | rb_prev = parent; | ||
725 | p = &(*p)->rb_right; | 728 | p = &(*p)->rb_right; |
726 | else | 729 | } else |
727 | BUG(); | 730 | BUG(); |
728 | } | 731 | } |
729 | 732 | ||
@@ -731,20 +734,11 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) | |||
731 | rb_insert_color(&vma->vm_rb, &mm->mm_rb); | 734 | rb_insert_color(&vma->vm_rb, &mm->mm_rb); |
732 | 735 | ||
733 | /* add VMA to the VMA list also */ | 736 | /* add VMA to the VMA list also */ |
734 | for (pp = &mm->mmap; (pvma = *pp); pp = &(*pp)->vm_next) { | 737 | prev = NULL; |
735 | if (pvma->vm_start > vma->vm_start) | 738 | if (rb_prev) |
736 | break; | 739 | prev = rb_entry(rb_prev, struct vm_area_struct, vm_rb); |
737 | if (pvma->vm_start < vma->vm_start) | ||
738 | continue; | ||
739 | if (pvma->vm_end < vma->vm_end) | ||
740 | break; | ||
741 | } | ||
742 | 740 | ||
743 | next = *pp; | 741 | __vma_link_list(mm, vma, prev, parent); |
744 | *pp = vma; | ||
745 | vma->vm_next = next; | ||
746 | if (next) | ||
747 | next->vm_prev = vma; | ||
748 | } | 742 | } |
749 | 743 | ||
750 | /* | 744 | /* |