forked from Minki/linux
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>
This commit is contained in:
parent
2ae416b142
commit
4abad2ca4a
@ -13,4 +13,13 @@
|
|||||||
|
|
||||||
#include <asm/mm-arch-hooks.h>
|
#include <asm/mm-arch-hooks.h>
|
||||||
|
|
||||||
|
#ifndef arch_remap
|
||||||
|
static inline void arch_remap(struct mm_struct *mm,
|
||||||
|
unsigned long old_start, unsigned long old_end,
|
||||||
|
unsigned long new_start, unsigned long new_end)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#define arch_remap arch_remap
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _LINUX_MM_ARCH_HOOKS_H */
|
#endif /* _LINUX_MM_ARCH_HOOKS_H */
|
||||||
|
17
mm/mremap.c
17
mm/mremap.c
@ -22,6 +22,7 @@
|
|||||||
#include <linux/mmu_notifier.h>
|
#include <linux/mmu_notifier.h>
|
||||||
#include <linux/sched/sysctl.h>
|
#include <linux/sched/sysctl.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/mm-arch-hooks.h>
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
@ -286,13 +287,17 @@ static unsigned long move_vma(struct vm_area_struct *vma,
|
|||||||
old_len = new_len;
|
old_len = new_len;
|
||||||
old_addr = new_addr;
|
old_addr = new_addr;
|
||||||
new_addr = -ENOMEM;
|
new_addr = -ENOMEM;
|
||||||
} else if (vma->vm_file && vma->vm_file->f_op->mremap) {
|
} else {
|
||||||
err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma);
|
if (vma->vm_file && vma->vm_file->f_op->mremap) {
|
||||||
if (err < 0) {
|
err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma);
|
||||||
move_page_tables(new_vma, new_addr, vma, old_addr,
|
if (err < 0) {
|
||||||
moved_len, true);
|
move_page_tables(new_vma, new_addr, vma,
|
||||||
return err;
|
old_addr, moved_len, true);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
arch_remap(mm, old_addr, old_addr + old_len,
|
||||||
|
new_addr, new_addr + new_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conceal VM_ACCOUNT so old reservation is not undone */
|
/* Conceal VM_ACCOUNT so old reservation is not undone */
|
||||||
|
Loading…
Reference in New Issue
Block a user