Skip to content

Commit abdba2d

Browse files
howlettakpm00
authored andcommitted
mm: use maple tree operations for find_vma_intersection()
Move find_vma_intersection() to mmap.c and change implementation to maple tree. When searching for a vma within a range, it is easier to use the maple tree interface. Exported find_vma_intersection() for kvm module. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Liam R. Howlett <[email protected]> Tested-by: Yu Zhao <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: David Howells <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: "Matthew Wilcox (Oracle)" <[email protected]> Cc: SeongJae Park <[email protected]> Cc: Sven Schnelle <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 2e7ce7d commit abdba2d

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

include/linux/mm.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,26 +2778,12 @@ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long add
27782778
extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
27792779
struct vm_area_struct **pprev);
27802780

2781-
/**
2782-
* find_vma_intersection() - Look up the first VMA which intersects the interval
2783-
* @mm: The process address space.
2784-
* @start_addr: The inclusive start user address.
2785-
* @end_addr: The exclusive end user address.
2786-
*
2787-
* Returns: The first VMA within the provided range, %NULL otherwise. Assumes
2788-
* start_addr < end_addr.
2781+
/*
2782+
* Look up the first VMA which intersects the interval [start_addr, end_addr)
2783+
* NULL if none. Assume start_addr < end_addr.
27892784
*/
2790-
static inline
27912785
struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
2792-
unsigned long start_addr,
2793-
unsigned long end_addr)
2794-
{
2795-
struct vm_area_struct *vma = find_vma(mm, start_addr);
2796-
2797-
if (vma && end_addr <= vma->vm_start)
2798-
vma = NULL;
2799-
return vma;
2800-
}
2786+
unsigned long start_addr, unsigned long end_addr);
28012787

28022788
/**
28032789
* vma_lookup() - Find a VMA at a specific address

mm/mmap.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,35 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
20612061

20622062
EXPORT_SYMBOL(get_unmapped_area);
20632063

2064+
/**
2065+
* find_vma_intersection() - Look up the first VMA which intersects the interval
2066+
* @mm: The process address space.
2067+
* @start_addr: The inclusive start user address.
2068+
* @end_addr: The exclusive end user address.
2069+
*
2070+
* Returns: The first VMA within the provided range, %NULL otherwise. Assumes
2071+
* start_addr < end_addr.
2072+
*/
2073+
struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
2074+
unsigned long start_addr,
2075+
unsigned long end_addr)
2076+
{
2077+
struct vm_area_struct *vma;
2078+
unsigned long index = start_addr;
2079+
2080+
mmap_assert_locked(mm);
2081+
/* Check the cache first. */
2082+
vma = vmacache_find(mm, start_addr);
2083+
if (likely(vma))
2084+
return vma;
2085+
2086+
vma = mt_find(&mm->mm_mt, &index, end_addr - 1);
2087+
if (vma)
2088+
vmacache_update(start_addr, vma);
2089+
return vma;
2090+
}
2091+
EXPORT_SYMBOL(find_vma_intersection);
2092+
20642093
/**
20652094
* find_vma() - Find the VMA for a given address, or the next VMA.
20662095
* @mm: The mm_struct to check

mm/nommu.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,17 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
642642
vm_area_free(vma);
643643
}
644644

645+
struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
646+
unsigned long start_addr,
647+
unsigned long end_addr)
648+
{
649+
unsigned long index = start_addr;
650+
651+
mmap_assert_locked(mm);
652+
return mt_find(&mm->mm_mt, &index, end_addr - 1);
653+
}
654+
EXPORT_SYMBOL(find_vma_intersection);
655+
645656
/*
646657
* look up the first VMA in which addr resides, NULL if none
647658
* - should be called with mm->mmap_lock at least held readlocked

0 commit comments

Comments
 (0)