Commit c270a7ee authored by Peter Xu's avatar Peter Xu Committed by Linus Torvalds

mm: introduce FAULT_FLAG_INTERRUPTIBLE

handle_userfaultfd() is currently the only one place in the kernel page
fault procedures that can respond to non-fatal userspace signals.  It was
trying to detect such an allowance by checking against USER & KILLABLE
flags, which was "un-official".

In this patch, we introduced a new flag (FAULT_FLAG_INTERRUPTIBLE) to show
that the fault handler allows the fault procedure to respond even to
non-fatal signals.  Meanwhile, add this new flag to the default fault
flags so that all the page fault handlers can benefit from the new flag.
With that, replacing the userfault check to this one.

Since the line is getting even longer, clean up the fault flags a bit too
to ease TTY users.

Although we've got a new flag and applied it, we shouldn't have any
functional change with this patch so far.
Suggested-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Tested-by: default avatarBrian Geffon <bgeffon@google.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Bobby Powers <bobbypowers@gmail.com>
Cc: Denis Plotnikov <dplotnikov@virtuozzo.com>
Cc: "Dr . David Alan Gilbert" <dgilbert@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Kirill A . Shutemov" <kirill@shutemov.name>
Cc: Martin Cracauer <cracauer@cons.org>
Cc: Marty McFadden <mcfadden8@llnl.gov>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Maya Gokhale <gokhale2@llnl.gov>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Link: http://lkml.kernel.org/r/20200220195348.16302-1-peterx@redhat.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent dde16072
...@@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason) ...@@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
uwq.ctx = ctx; uwq.ctx = ctx;
uwq.waken = false; uwq.waken = false;
return_to_userland = return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
blocking_state = return_to_userland ? TASK_INTERRUPTIBLE : blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
TASK_KILLABLE; TASK_KILLABLE;
......
...@@ -381,22 +381,38 @@ extern unsigned int kobjsize(const void *objp); ...@@ -381,22 +381,38 @@ extern unsigned int kobjsize(const void *objp);
*/ */
extern pgprot_t protection_map[16]; extern pgprot_t protection_map[16];
#define FAULT_FLAG_WRITE 0x01 /* Fault was a write access */ /**
#define FAULT_FLAG_MKWRITE 0x02 /* Fault was mkwrite of existing pte */ * Fault flag definitions.
#define FAULT_FLAG_ALLOW_RETRY 0x04 /* Retry fault if blocking */ *
#define FAULT_FLAG_RETRY_NOWAIT 0x08 /* Don't drop mmap_sem and wait when retrying */ * @FAULT_FLAG_WRITE: Fault was a write fault.
#define FAULT_FLAG_KILLABLE 0x10 /* The fault task is in SIGKILL killable region */ * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
#define FAULT_FLAG_TRIED 0x20 /* Second try */ * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
#define FAULT_FLAG_USER 0x40 /* The fault originated in userspace */ * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
#define FAULT_FLAG_REMOTE 0x80 /* faulting for non current tsk/mm */ * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
#define FAULT_FLAG_INSTRUCTION 0x100 /* The fault was during an instruction fetch */ * @FAULT_FLAG_TRIED: The fault has been tried once.
* @FAULT_FLAG_USER: The fault originated in userspace.
* @FAULT_FLAG_REMOTE: The fault is not for current task/mm.
* @FAULT_FLAG_INSTRUCTION: The fault was during an instruction fetch.
* @FAULT_FLAG_INTERRUPTIBLE: The fault can be interrupted by non-fatal signals.
*/
#define FAULT_FLAG_WRITE 0x01
#define FAULT_FLAG_MKWRITE 0x02
#define FAULT_FLAG_ALLOW_RETRY 0x04
#define FAULT_FLAG_RETRY_NOWAIT 0x08
#define FAULT_FLAG_KILLABLE 0x10
#define FAULT_FLAG_TRIED 0x20
#define FAULT_FLAG_USER 0x40
#define FAULT_FLAG_REMOTE 0x80
#define FAULT_FLAG_INSTRUCTION 0x100
#define FAULT_FLAG_INTERRUPTIBLE 0x200
/* /*
* The default fault flags that should be used by most of the * The default fault flags that should be used by most of the
* arch-specific page fault handlers. * arch-specific page fault handlers.
*/ */
#define FAULT_FLAG_DEFAULT (FAULT_FLAG_ALLOW_RETRY | \ #define FAULT_FLAG_DEFAULT (FAULT_FLAG_ALLOW_RETRY | \
FAULT_FLAG_KILLABLE) FAULT_FLAG_KILLABLE | \
FAULT_FLAG_INTERRUPTIBLE)
#define FAULT_FLAG_TRACE \ #define FAULT_FLAG_TRACE \
{ FAULT_FLAG_WRITE, "WRITE" }, \ { FAULT_FLAG_WRITE, "WRITE" }, \
...@@ -407,7 +423,8 @@ extern pgprot_t protection_map[16]; ...@@ -407,7 +423,8 @@ extern pgprot_t protection_map[16];
{ FAULT_FLAG_TRIED, "TRIED" }, \ { FAULT_FLAG_TRIED, "TRIED" }, \
{ FAULT_FLAG_USER, "USER" }, \ { FAULT_FLAG_USER, "USER" }, \
{ FAULT_FLAG_REMOTE, "REMOTE" }, \ { FAULT_FLAG_REMOTE, "REMOTE" }, \
{ FAULT_FLAG_INSTRUCTION, "INSTRUCTION" } { FAULT_FLAG_INSTRUCTION, "INSTRUCTION" }, \
{ FAULT_FLAG_INTERRUPTIBLE, "INTERRUPTIBLE" }
/* /*
* vm_fault is filled by the the pagefault handler and passed to the vma's * vm_fault is filled by the the pagefault handler and passed to the vma's
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment