forked from mirrors/linux
		
	mm: simplify find_vma_prev()
commit 297c5eee37 ("mm: make the vma list be doubly linked") added the
vm_prev member to vm_area_struct.  We can simplify find_vma_prev() by
using it.  Also, this change helps to improve page fault performance
because it has stronger locality of reference.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Shaohua Li <shaohua.li@intel.com>
Cc: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									948f017b09
								
							
						
					
					
						commit
						6bd4837de9
					
				
					 1 changed files with 8 additions and 28 deletions
				
			
		
							
								
								
									
										36
									
								
								mm/mmap.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								mm/mmap.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1603,39 +1603,19 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
 | 
			
		|||
 | 
			
		||||
EXPORT_SYMBOL(find_vma);
 | 
			
		||||
 | 
			
		||||
/* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
 | 
			
		||||
/*
 | 
			
		||||
 * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
 | 
			
		||||
 * Note: pprev is set to NULL when return value is NULL.
 | 
			
		||||
 */
 | 
			
		||||
struct vm_area_struct *
 | 
			
		||||
find_vma_prev(struct mm_struct *mm, unsigned long addr,
 | 
			
		||||
			struct vm_area_struct **pprev)
 | 
			
		||||
{
 | 
			
		||||
	struct vm_area_struct *vma = NULL, *prev = NULL;
 | 
			
		||||
	struct rb_node *rb_node;
 | 
			
		||||
	if (!mm)
 | 
			
		||||
		goto out;
 | 
			
		||||
	struct vm_area_struct *vma;
 | 
			
		||||
 | 
			
		||||
	/* Guard against addr being lower than the first VMA */
 | 
			
		||||
	vma = mm->mmap;
 | 
			
		||||
 | 
			
		||||
	/* Go through the RB tree quickly. */
 | 
			
		||||
	rb_node = mm->mm_rb.rb_node;
 | 
			
		||||
 | 
			
		||||
	while (rb_node) {
 | 
			
		||||
		struct vm_area_struct *vma_tmp;
 | 
			
		||||
		vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
 | 
			
		||||
 | 
			
		||||
		if (addr < vma_tmp->vm_end) {
 | 
			
		||||
			rb_node = rb_node->rb_left;
 | 
			
		||||
		} else {
 | 
			
		||||
			prev = vma_tmp;
 | 
			
		||||
			if (!prev->vm_next || (addr < prev->vm_next->vm_end))
 | 
			
		||||
				break;
 | 
			
		||||
			rb_node = rb_node->rb_right;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	*pprev = prev;
 | 
			
		||||
	return prev ? prev->vm_next : vma;
 | 
			
		||||
	vma = find_vma(mm, addr);
 | 
			
		||||
	*pprev = vma ? vma->vm_prev : NULL;
 | 
			
		||||
	return vma;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue