find_vma_prev rewrite
Subsystems (2)
PATCH 1/1 find_vma_prev rewrite
find_vma_prev doesn't return a pointer to the `prev' vma if the address is greater than the last existing vma. This doesn't matter unless you're on a PA-RISC machine :-)
This rewrite should speed up & make find_vma_prev simpler, as well as fixing the previous behaviour.
mm/mmap.c +36 -42
@@ -417,54 +417,48 @@struct vm_area_struct *find_vma_prev (struct mm_struct * mm,unsigned long addr,struct vm_area_struct **pprev) { -if (mm) { -if (!mm->mmap_avl) { -/* Go through the linear list. */ -struct vm_area_struct * prev =NULL ; -struct vm_area_struct * vma = mm->mmap; -while (vma && vma->vm_end <= addr) { - prev = vma; - vma = vma->vm_next; - } - *pprev = prev; -return vma; - }else { -/* Go through the AVL tree quickly. */ -struct vm_area_struct * vma =NULL ; -struct vm_area_struct * last_turn_right =NULL ; -struct vm_area_struct * prev =NULL ; -struct vm_area_struct * tree = mm->mmap_avl; -for (;;) { -if (tree == vm_avl_empty) +struct vm_area_struct *vma =NULL ; +struct vm_area_struct *prev =NULL ; +if (!mm) + goto out; + prev = mm->mmap_cache; +if (prev) { + vma = prev->vm_next; +if (prev->vm_end < addr && + ((vma ==NULL ) || (addr < vma->vm_end))) + goto out; + prev =NULL ; + } + vma = mm->mmap;/* guard against there being no prev */ +if (!mm->mmap_avl) { +/* Go through the linear list. */ +while (vma && vma->vm_end <= addr) { + prev = vma; + vma = vma->vm_next; + } + }else { +/* Go through the AVL tree quickly. */ +struct vm_area_struct * tree = mm->mmap_avl; +while (tree != vm_avl_empty) { +if (addr < tree->vm_end) { + tree = tree->vm_avl_left; + }else { + prev = tree; +if (tree->vm_next ==NULL )break ; -if (tree->vm_end > addr) { - vma = tree; - prev = last_turn_right; -if (tree->vm_start <= addr) -break ; - tree = tree->vm_avl_left; - }else { - last_turn_right = tree; - tree = tree->vm_avl_right; - } - } -if (vma) { -if (vma->vm_avl_left != vm_avl_empty) { - prev = vma->vm_avl_left; -while (prev->vm_avl_right != vm_avl_empty) - prev = prev->vm_avl_right; - } -if ((prev ? prev->vm_next : mm->mmap) != vma) -printk ("find_vma_prev: tree inconsistent with list\n" ); - *pprev = prev; -return vma; +if (addr < tree->vm_next->vm_end) +break ; + tree = tree->vm_avl_right; } } } - *pprev =NULL ; -return NULL ; + mm->mmap_cache = prev; +out: + *pprev = prev; +return prev ? prev->vm_next : vma; } +/* XXX: Needs to be fixed for PA-RISC -- won't grow our stack. */ struct vm_area_struct *find_extend_vma (struct mm_struct * mm,unsigned long addr) {struct vm_area_struct * vma;
Signature · 5 lines
Revolutions do not require corporate support. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] Please read the FAQ at http://www.tux.org/lkml/