|
@@ -15,6 +15,7 @@
|
|
|
|
|
|
#include <linux/export.h>
|
|
#include <linux/export.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/mm.h>
|
|
|
|
+#include <linux/vmacache.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/file.h>
|
|
#include <linux/file.h>
|
|
@@ -768,16 +769,23 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
|
|
*/
|
|
*/
|
|
static void delete_vma_from_mm(struct vm_area_struct *vma)
|
|
static void delete_vma_from_mm(struct vm_area_struct *vma)
|
|
{
|
|
{
|
|
|
|
+ int i;
|
|
struct address_space *mapping;
|
|
struct address_space *mapping;
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
|
|
+ struct task_struct *curr = current;
|
|
|
|
|
|
kenter("%p", vma);
|
|
kenter("%p", vma);
|
|
|
|
|
|
protect_vma(vma, 0);
|
|
protect_vma(vma, 0);
|
|
|
|
|
|
mm->map_count--;
|
|
mm->map_count--;
|
|
- if (mm->mmap_cache == vma)
|
|
|
|
- mm->mmap_cache = NULL;
|
|
|
|
|
|
+ for (i = 0; i < VMACACHE_SIZE; i++) {
|
|
|
|
+ /* if the vma is cached, invalidate the entire cache */
|
|
|
|
+ if (curr->vmacache[i] == vma) {
|
|
|
|
+ vmacache_invalidate(curr->mm);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
/* remove the VMA from the mapping */
|
|
/* remove the VMA from the mapping */
|
|
if (vma->vm_file) {
|
|
if (vma->vm_file) {
|
|
@@ -825,8 +833,8 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
|
|
struct vm_area_struct *vma;
|
|
struct vm_area_struct *vma;
|
|
|
|
|
|
/* check the cache first */
|
|
/* check the cache first */
|
|
- vma = ACCESS_ONCE(mm->mmap_cache);
|
|
|
|
- if (vma && vma->vm_start <= addr && vma->vm_end > addr)
|
|
|
|
|
|
+ vma = vmacache_find(mm, addr);
|
|
|
|
+ if (likely(vma))
|
|
return vma;
|
|
return vma;
|
|
|
|
|
|
/* trawl the list (there may be multiple mappings in which addr
|
|
/* trawl the list (there may be multiple mappings in which addr
|
|
@@ -835,7 +843,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
|
|
if (vma->vm_start > addr)
|
|
if (vma->vm_start > addr)
|
|
return NULL;
|
|
return NULL;
|
|
if (vma->vm_end > addr) {
|
|
if (vma->vm_end > addr) {
|
|
- mm->mmap_cache = vma;
|
|
|
|
|
|
+ vmacache_update(addr, vma);
|
|
return vma;
|
|
return vma;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -874,8 +882,8 @@ static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
|
|
unsigned long end = addr + len;
|
|
unsigned long end = addr + len;
|
|
|
|
|
|
/* check the cache first */
|
|
/* check the cache first */
|
|
- vma = mm->mmap_cache;
|
|
|
|
- if (vma && vma->vm_start == addr && vma->vm_end == end)
|
|
|
|
|
|
+ vma = vmacache_find_exact(mm, addr, end);
|
|
|
|
+ if (vma)
|
|
return vma;
|
|
return vma;
|
|
|
|
|
|
/* trawl the list (there may be multiple mappings in which addr
|
|
/* trawl the list (there may be multiple mappings in which addr
|
|
@@ -886,7 +894,7 @@ static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
|
|
if (vma->vm_start > addr)
|
|
if (vma->vm_start > addr)
|
|
return NULL;
|
|
return NULL;
|
|
if (vma->vm_end == end) {
|
|
if (vma->vm_end == end) {
|
|
- mm->mmap_cache = vma;
|
|
|
|
|
|
+ vmacache_update(addr, vma);
|
|
return vma;
|
|
return vma;
|
|
}
|
|
}
|
|
}
|
|
}
|