diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-20 19:24:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-21 11:49:21 -0400 |
commit | 297c5eee372478fc32fec5fe8eed711eedb13f3d (patch) | |
tree | 18415eae0833ff4767943f985900524d6b1d73f1 /mm/mmap.c | |
parent | 36423a5ed5e4ea95ceedb68fad52965033e11639 (diff) |
mm: make the vma list be doubly linked
It's a really simple list, and several of the users want to go backwards
in it to find the previous vma. So rather than have to look up the
previous entry with 'find_vma_prev()' or something similar, just make it
doubly linked instead.
Tested-by: Ian Campbell <ijc@hellion.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -388,17 +388,23 @@ static inline void | |||
388 | __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, | 388 | __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, |
389 | struct vm_area_struct *prev, struct rb_node *rb_parent) | 389 | struct vm_area_struct *prev, struct rb_node *rb_parent) |
390 | { | 390 | { |
391 | struct vm_area_struct *next; | ||
392 | |||
393 | vma->vm_prev = prev; | ||
391 | if (prev) { | 394 | if (prev) { |
392 | vma->vm_next = prev->vm_next; | 395 | next = prev->vm_next; |
393 | prev->vm_next = vma; | 396 | prev->vm_next = vma; |
394 | } else { | 397 | } else { |
395 | mm->mmap = vma; | 398 | mm->mmap = vma; |
396 | if (rb_parent) | 399 | if (rb_parent) |
397 | vma->vm_next = rb_entry(rb_parent, | 400 | next = rb_entry(rb_parent, |
398 | struct vm_area_struct, vm_rb); | 401 | struct vm_area_struct, vm_rb); |
399 | else | 402 | else |
400 | vma->vm_next = NULL; | 403 | next = NULL; |
401 | } | 404 | } |
405 | vma->vm_next = next; | ||
406 | if (next) | ||
407 | next->vm_prev = vma; | ||
402 | } | 408 | } |
403 | 409 | ||
404 | void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, | 410 | void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, |
@@ -483,7 +489,11 @@ static inline void | |||
483 | __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, | 489 | __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, |
484 | struct vm_area_struct *prev) | 490 | struct vm_area_struct *prev) |
485 | { | 491 | { |
486 | prev->vm_next = vma->vm_next; | 492 | struct vm_area_struct *next = vma->vm_next; |
493 | |||
494 | prev->vm_next = next; | ||
495 | if (next) | ||
496 | next->vm_prev = prev; | ||
487 | rb_erase(&vma->vm_rb, &mm->mm_rb); | 497 | rb_erase(&vma->vm_rb, &mm->mm_rb); |
488 | if (mm->mmap_cache == vma) | 498 | if (mm->mmap_cache == vma) |
489 | mm->mmap_cache = prev; | 499 | mm->mmap_cache = prev; |
@@ -1915,6 +1925,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1915 | unsigned long addr; | 1925 | unsigned long addr; |
1916 | 1926 | ||
1917 | insertion_point = (prev ? &prev->vm_next : &mm->mmap); | 1927 | insertion_point = (prev ? &prev->vm_next : &mm->mmap); |
1928 | vma->vm_prev = NULL; | ||
1918 | do { | 1929 | do { |
1919 | rb_erase(&vma->vm_rb, &mm->mm_rb); | 1930 | rb_erase(&vma->vm_rb, &mm->mm_rb); |
1920 | mm->map_count--; | 1931 | mm->map_count--; |
@@ -1922,6 +1933,8 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1922 | vma = vma->vm_next; | 1933 | vma = vma->vm_next; |
1923 | } while (vma && vma->vm_start < end); | 1934 | } while (vma && vma->vm_start < end); |
1924 | *insertion_point = vma; | 1935 | *insertion_point = vma; |
1936 | if (vma) | ||
1937 | vma->vm_prev = prev; | ||
1925 | tail_vma->vm_next = NULL; | 1938 | tail_vma->vm_next = NULL; |
1926 | if (mm->unmap_area == arch_unmap_area) | 1939 | if (mm->unmap_area == arch_unmap_area) |
1927 | addr = prev ? prev->vm_end : mm->mmap_base; | 1940 | addr = prev ? prev->vm_end : mm->mmap_base; |