|
@@ -680,9 +680,9 @@ static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
|
|
|
*/
|
|
|
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
|
|
|
{
|
|
|
- struct vm_area_struct *pvma, **pp, *next;
|
|
|
+ struct vm_area_struct *pvma, *prev;
|
|
|
struct address_space *mapping;
|
|
|
- struct rb_node **p, *parent;
|
|
|
+ struct rb_node **p, *parent, *rb_prev;
|
|
|
|
|
|
kenter(",%p", vma);
|
|
|
|
|
@@ -703,7 +703,7 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
|
|
|
}
|
|
|
|
|
|
/* add the VMA to the tree */
|
|
|
- parent = NULL;
|
|
|
+ parent = rb_prev = NULL;
|
|
|
p = &mm->mm_rb.rb_node;
|
|
|
while (*p) {
|
|
|
parent = *p;
|
|
@@ -713,17 +713,20 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
|
|
|
* (the latter is necessary as we may get identical VMAs) */
|
|
|
if (vma->vm_start < pvma->vm_start)
|
|
|
p = &(*p)->rb_left;
|
|
|
- else if (vma->vm_start > pvma->vm_start)
|
|
|
+ else if (vma->vm_start > pvma->vm_start) {
|
|
|
+ rb_prev = parent;
|
|
|
p = &(*p)->rb_right;
|
|
|
- else if (vma->vm_end < pvma->vm_end)
|
|
|
+ } else if (vma->vm_end < pvma->vm_end)
|
|
|
p = &(*p)->rb_left;
|
|
|
- else if (vma->vm_end > pvma->vm_end)
|
|
|
+ else if (vma->vm_end > pvma->vm_end) {
|
|
|
+ rb_prev = parent;
|
|
|
p = &(*p)->rb_right;
|
|
|
- else if (vma < pvma)
|
|
|
+ } else if (vma < pvma)
|
|
|
p = &(*p)->rb_left;
|
|
|
- else if (vma > pvma)
|
|
|
+ else if (vma > pvma) {
|
|
|
+ rb_prev = parent;
|
|
|
p = &(*p)->rb_right;
|
|
|
- else
|
|
|
+ } else
|
|
|
BUG();
|
|
|
}
|
|
|
|
|
@@ -731,20 +734,11 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
|
|
|
rb_insert_color(&vma->vm_rb, &mm->mm_rb);
|
|
|
|
|
|
/* add VMA to the VMA list also */
|
|
|
- for (pp = &mm->mmap; (pvma = *pp); pp = &(*pp)->vm_next) {
|
|
|
- if (pvma->vm_start > vma->vm_start)
|
|
|
- break;
|
|
|
- if (pvma->vm_start < vma->vm_start)
|
|
|
- continue;
|
|
|
- if (pvma->vm_end < vma->vm_end)
|
|
|
- break;
|
|
|
- }
|
|
|
+ prev = NULL;
|
|
|
+ if (rb_prev)
|
|
|
+ prev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
|
|
|
|
|
|
- next = *pp;
|
|
|
- *pp = vma;
|
|
|
- vma->vm_next = next;
|
|
|
- if (next)
|
|
|
- next->vm_prev = vma;
|
|
|
+ __vma_link_list(mm, vma, prev, parent);
|
|
|
}
|
|
|
|
|
|
/*
|