diff options
| author | Alex Thorlton <athorlton@sgi.com> | 2014-04-07 18:37:10 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 19:35:52 -0400 |
| commit | a0715cc22601e8830ace98366c0c2bd8da52af52 (patch) | |
| tree | 4444c61a4685d10d683e1f29177a9e7cfbccae73 | |
| parent | 1e1836e84f87d12feac6dd225fcef5eba1ca724b (diff) | |
mm, thp: add VM_INIT_DEF_MASK and PRCTL_THP_DISABLE
Add VM_INIT_DEF_MASK, to allow us to set the default flags for VMs. It
also adds a prctl control which allows us to set the THP disable bit in
mm->def_flags so that VMs will pick up the setting as they are created.
Signed-off-by: Alex Thorlton <athorlton@sgi.com>
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Mel Gorman <mgorman@suse.de>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | include/linux/mm.h | 3 | ||||
| -rw-r--r-- | include/uapi/linux/prctl.h | 3 | ||||
| -rw-r--r-- | kernel/fork.c | 11 | ||||
| -rw-r--r-- | kernel/sys.c | 15 |
4 files changed, 29 insertions, 3 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 35300f390eb6..c270fa68a32b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -177,6 +177,9 @@ extern unsigned int kobjsize(const void *objp); | |||
| 177 | */ | 177 | */ |
| 178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) | 178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) |
| 179 | 179 | ||
| 180 | /* This mask defines which mm->def_flags a process can inherit its parent */ | ||
| 181 | #define VM_INIT_DEF_MASK VM_NOHUGEPAGE | ||
| 182 | |||
| 180 | /* | 183 | /* |
| 181 | * mapping from the currently active vm_flags protection bits (the | 184 | * mapping from the currently active vm_flags protection bits (the |
| 182 | * low four bits) to a page protection mask.. | 185 | * low four bits) to a page protection mask.. |
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 289760f424aa..58afc04c107e 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h | |||
| @@ -149,4 +149,7 @@ | |||
| 149 | 149 | ||
| 150 | #define PR_GET_TID_ADDRESS 40 | 150 | #define PR_GET_TID_ADDRESS 40 |
| 151 | 151 | ||
| 152 | #define PR_SET_THP_DISABLE 41 | ||
| 153 | #define PR_GET_THP_DISABLE 42 | ||
| 154 | |||
| 152 | #endif /* _LINUX_PRCTL_H */ | 155 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/kernel/fork.c b/kernel/fork.c index abc45890f0a5..e40c0a01d5a6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -530,8 +530,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
| 530 | atomic_set(&mm->mm_count, 1); | 530 | atomic_set(&mm->mm_count, 1); |
| 531 | init_rwsem(&mm->mmap_sem); | 531 | init_rwsem(&mm->mmap_sem); |
| 532 | INIT_LIST_HEAD(&mm->mmlist); | 532 | INIT_LIST_HEAD(&mm->mmlist); |
| 533 | mm->flags = (current->mm) ? | ||
| 534 | (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; | ||
| 535 | mm->core_state = NULL; | 533 | mm->core_state = NULL; |
| 536 | atomic_long_set(&mm->nr_ptes, 0); | 534 | atomic_long_set(&mm->nr_ptes, 0); |
| 537 | memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); | 535 | memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); |
| @@ -540,8 +538,15 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
| 540 | mm_init_owner(mm, p); | 538 | mm_init_owner(mm, p); |
| 541 | clear_tlb_flush_pending(mm); | 539 | clear_tlb_flush_pending(mm); |
| 542 | 540 | ||
| 543 | if (likely(!mm_alloc_pgd(mm))) { | 541 | if (current->mm) { |
| 542 | mm->flags = current->mm->flags & MMF_INIT_MASK; | ||
| 543 | mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK; | ||
| 544 | } else { | ||
| 545 | mm->flags = default_dump_filter; | ||
| 544 | mm->def_flags = 0; | 546 | mm->def_flags = 0; |
| 547 | } | ||
| 548 | |||
| 549 | if (likely(!mm_alloc_pgd(mm))) { | ||
| 545 | mmu_notifier_mm_init(mm); | 550 | mmu_notifier_mm_init(mm); |
| 546 | return mm; | 551 | return mm; |
| 547 | } | 552 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index adaeab6f7a87..fba0f29401ea 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1996,6 +1996,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
| 1996 | if (arg2 || arg3 || arg4 || arg5) | 1996 | if (arg2 || arg3 || arg4 || arg5) |
| 1997 | return -EINVAL; | 1997 | return -EINVAL; |
| 1998 | return current->no_new_privs ? 1 : 0; | 1998 | return current->no_new_privs ? 1 : 0; |
| 1999 | case PR_GET_THP_DISABLE: | ||
| 2000 | if (arg2 || arg3 || arg4 || arg5) | ||
| 2001 | return -EINVAL; | ||
| 2002 | error = !!(me->mm->def_flags & VM_NOHUGEPAGE); | ||
| 2003 | break; | ||
| 2004 | case PR_SET_THP_DISABLE: | ||
| 2005 | if (arg3 || arg4 || arg5) | ||
| 2006 | return -EINVAL; | ||
| 2007 | down_write(&me->mm->mmap_sem); | ||
| 2008 | if (arg2) | ||
| 2009 | me->mm->def_flags |= VM_NOHUGEPAGE; | ||
| 2010 | else | ||
| 2011 | me->mm->def_flags &= ~VM_NOHUGEPAGE; | ||
| 2012 | up_write(&me->mm->mmap_sem); | ||
| 2013 | break; | ||
| 1999 | default: | 2014 | default: |
| 2000 | error = -EINVAL; | 2015 | error = -EINVAL; |
| 2001 | break; | 2016 | break; |
