diff options
author | Laurent Dufour <ldufour@linux.vnet.ibm.com> | 2015-06-24 19:56:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-24 20:49:41 -0400 |
commit | 4abad2ca4a4dbdd4a218c12451231ab628f2e60c (patch) | |
tree | 4e9f1494ef5d8cffbdf379317bb144a96aaad9d8 | |
parent | 2ae416b142b625c58c9ccb039aa3ef48ad0e9bae (diff) |
mm: new arch_remap() hook
Some architectures would like to be triggered when a memory area is moved
through the mremap system call.
This patch introduces a new arch_remap() mm hook which is placed in the
path of mremap, and is called before the old area is unmapped (and the
arch_unmap() hook is called).
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/mm-arch-hooks.h | 9 | ||||
-rw-r--r-- | mm/mremap.c | 17 |
2 files changed, 20 insertions, 6 deletions
diff --git a/include/linux/mm-arch-hooks.h b/include/linux/mm-arch-hooks.h index 63005e367abd..4efc3f56e6df 100644 --- a/include/linux/mm-arch-hooks.h +++ b/include/linux/mm-arch-hooks.h | |||
@@ -13,4 +13,13 @@ | |||
13 | 13 | ||
14 | #include <asm/mm-arch-hooks.h> | 14 | #include <asm/mm-arch-hooks.h> |
15 | 15 | ||
16 | #ifndef arch_remap | ||
17 | static inline void arch_remap(struct mm_struct *mm, | ||
18 | unsigned long old_start, unsigned long old_end, | ||
19 | unsigned long new_start, unsigned long new_end) | ||
20 | { | ||
21 | } | ||
22 | #define arch_remap arch_remap | ||
23 | #endif | ||
24 | |||
16 | #endif /* _LINUX_MM_ARCH_HOOKS_H */ | 25 | #endif /* _LINUX_MM_ARCH_HOOKS_H */ |
diff --git a/mm/mremap.c b/mm/mremap.c index 034e2d360652..a7c93eceb1c8 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mmu_notifier.h> | 22 | #include <linux/mmu_notifier.h> |
23 | #include <linux/sched/sysctl.h> | 23 | #include <linux/sched/sysctl.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <linux/mm-arch-hooks.h> | ||
25 | 26 | ||
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
27 | #include <asm/tlbflush.h> | 28 | #include <asm/tlbflush.h> |
@@ -286,13 +287,17 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
286 | old_len = new_len; | 287 | old_len = new_len; |
287 | old_addr = new_addr; | 288 | old_addr = new_addr; |
288 | new_addr = -ENOMEM; | 289 | new_addr = -ENOMEM; |
289 | } else if (vma->vm_file && vma->vm_file->f_op->mremap) { | 290 | } else { |
290 | err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma); | 291 | if (vma->vm_file && vma->vm_file->f_op->mremap) { |
291 | if (err < 0) { | 292 | err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma); |
292 | move_page_tables(new_vma, new_addr, vma, old_addr, | 293 | if (err < 0) { |
293 | moved_len, true); | 294 | move_page_tables(new_vma, new_addr, vma, |
294 | return err; | 295 | old_addr, moved_len, true); |
296 | return err; | ||
297 | } | ||
295 | } | 298 | } |
299 | arch_remap(mm, old_addr, old_addr + old_len, | ||
300 | new_addr, new_addr + new_len); | ||
296 | } | 301 | } |
297 | 302 | ||
298 | /* Conceal VM_ACCOUNT so old reservation is not undone */ | 303 | /* Conceal VM_ACCOUNT so old reservation is not undone */ |