mm, thp: add VM_INIT_DEF_MASK and PRCTL_THP_DISABLE
authorAlex Thorlton <athorlton@sgi.com>
Mon, 7 Apr 2014 22:37:10 +0000 (15:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 7 Apr 2014 23:35:52 +0000 (16:35 -0700)
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>
include/linux/mm.h
include/uapi/linux/prctl.h
kernel/fork.c
kernel/sys.c

index 35300f390eb6b732499d2ffd0b9c295f73d01e4d..c270fa68a32bf045ba821e9cb2528bacfacbdaa2 100644 (file)
@@ -177,6 +177,9 @@ extern unsigned int kobjsize(const void *objp);
  */
 #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
 
+/* This mask defines which mm->def_flags a process can inherit its parent */
+#define VM_INIT_DEF_MASK       VM_NOHUGEPAGE
+
 /*
  * mapping from the currently active vm_flags protection bits (the
  * low four bits) to a page protection mask..
index 289760f424aaa3247d2e4f66841334c67295c9ef..58afc04c107e40cf9f481a7f9eefefd67dbe74ce 100644 (file)
 
 #define PR_GET_TID_ADDRESS     40
 
+#define PR_SET_THP_DISABLE     41
+#define PR_GET_THP_DISABLE     42
+
 #endif /* _LINUX_PRCTL_H */
index abc45890f0a504dbf428c96cc07942de4a476cf4..e40c0a01d5a634d77d065b679d2c18d00ed7bc5a 100644 (file)
@@ -530,8 +530,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
        atomic_set(&mm->mm_count, 1);
        init_rwsem(&mm->mmap_sem);
        INIT_LIST_HEAD(&mm->mmlist);
-       mm->flags = (current->mm) ?
-               (current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
        mm->core_state = NULL;
        atomic_long_set(&mm->nr_ptes, 0);
        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)
        mm_init_owner(mm, p);
        clear_tlb_flush_pending(mm);
 
-       if (likely(!mm_alloc_pgd(mm))) {
+       if (current->mm) {
+               mm->flags = current->mm->flags & MMF_INIT_MASK;
+               mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK;
+       } else {
+               mm->flags = default_dump_filter;
                mm->def_flags = 0;
+       }
+
+       if (likely(!mm_alloc_pgd(mm))) {
                mmu_notifier_mm_init(mm);
                return mm;
        }
index adaeab6f7a870ae69537baebf4ca092a161d5013..fba0f29401eafba43b29602b0296ee16022b4633 100644 (file)
@@ -1996,6 +1996,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                if (arg2 || arg3 || arg4 || arg5)
                        return -EINVAL;
                return current->no_new_privs ? 1 : 0;
+       case PR_GET_THP_DISABLE:
+               if (arg2 || arg3 || arg4 || arg5)
+                       return -EINVAL;
+               error = !!(me->mm->def_flags & VM_NOHUGEPAGE);
+               break;
+       case PR_SET_THP_DISABLE:
+               if (arg3 || arg4 || arg5)
+                       return -EINVAL;
+               down_write(&me->mm->mmap_sem);
+               if (arg2)
+                       me->mm->def_flags |= VM_NOHUGEPAGE;
+               else
+                       me->mm->def_flags &= ~VM_NOHUGEPAGE;
+               up_write(&me->mm->mmap_sem);
+               break;
        default:
                error = -EINVAL;
                break;