Skip to content

Commit c270a7e

Browse files
xzpetertorvalds
authored andcommitted
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: Linus Torvalds <[email protected]> Signed-off-by: Peter Xu <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Tested-by: Brian Geffon <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Bobby Powers <[email protected]> Cc: Denis Plotnikov <[email protected]> Cc: "Dr . David Alan Gilbert" <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Jerome Glisse <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: "Kirill A . Shutemov" <[email protected]> Cc: Martin Cracauer <[email protected]> Cc: Marty McFadden <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Maya Gokhale <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Pavel Emelyanov <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent dde1607 commit c270a7e

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

fs/userfaultfd.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
462462
uwq.ctx = ctx;
463463
uwq.waken = false;
464464

465-
return_to_userland =
466-
(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
467-
(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
465+
return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
468466
blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
469467
TASK_KILLABLE;
470468

include/linux/mm.h

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -381,22 +381,38 @@ extern unsigned int kobjsize(const void *objp);
381381
*/
382382
extern pgprot_t protection_map[16];
383383

384-
#define FAULT_FLAG_WRITE 0x01 /* Fault was a write access */
385-
#define FAULT_FLAG_MKWRITE 0x02 /* Fault was mkwrite of existing pte */
386-
#define FAULT_FLAG_ALLOW_RETRY 0x04 /* Retry fault if blocking */
387-
#define FAULT_FLAG_RETRY_NOWAIT 0x08 /* Don't drop mmap_sem and wait when retrying */
388-
#define FAULT_FLAG_KILLABLE 0x10 /* The fault task is in SIGKILL killable region */
389-
#define FAULT_FLAG_TRIED 0x20 /* Second try */
390-
#define FAULT_FLAG_USER 0x40 /* The fault originated in userspace */
391-
#define FAULT_FLAG_REMOTE 0x80 /* faulting for non current tsk/mm */
392-
#define FAULT_FLAG_INSTRUCTION 0x100 /* The fault was during an instruction fetch */
384+
/**
385+
* Fault flag definitions.
386+
*
387+
* @FAULT_FLAG_WRITE: Fault was a write fault.
388+
* @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
389+
* @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
390+
* @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
391+
* @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
392+
* @FAULT_FLAG_TRIED: The fault has been tried once.
393+
* @FAULT_FLAG_USER: The fault originated in userspace.
394+
* @FAULT_FLAG_REMOTE: The fault is not for current task/mm.
395+
* @FAULT_FLAG_INSTRUCTION: The fault was during an instruction fetch.
396+
* @FAULT_FLAG_INTERRUPTIBLE: The fault can be interrupted by non-fatal signals.
397+
*/
398+
#define FAULT_FLAG_WRITE 0x01
399+
#define FAULT_FLAG_MKWRITE 0x02
400+
#define FAULT_FLAG_ALLOW_RETRY 0x04
401+
#define FAULT_FLAG_RETRY_NOWAIT 0x08
402+
#define FAULT_FLAG_KILLABLE 0x10
403+
#define FAULT_FLAG_TRIED 0x20
404+
#define FAULT_FLAG_USER 0x40
405+
#define FAULT_FLAG_REMOTE 0x80
406+
#define FAULT_FLAG_INSTRUCTION 0x100
407+
#define FAULT_FLAG_INTERRUPTIBLE 0x200
393408

394409
/*
395410
* The default fault flags that should be used by most of the
396411
* arch-specific page fault handlers.
397412
*/
398413
#define FAULT_FLAG_DEFAULT (FAULT_FLAG_ALLOW_RETRY | \
399-
FAULT_FLAG_KILLABLE)
414+
FAULT_FLAG_KILLABLE | \
415+
FAULT_FLAG_INTERRUPTIBLE)
400416

401417
#define FAULT_FLAG_TRACE \
402418
{ FAULT_FLAG_WRITE, "WRITE" }, \
@@ -407,7 +423,8 @@ extern pgprot_t protection_map[16];
407423
{ FAULT_FLAG_TRIED, "TRIED" }, \
408424
{ FAULT_FLAG_USER, "USER" }, \
409425
{ FAULT_FLAG_REMOTE, "REMOTE" }, \
410-
{ FAULT_FLAG_INSTRUCTION, "INSTRUCTION" }
426+
{ FAULT_FLAG_INSTRUCTION, "INSTRUCTION" }, \
427+
{ FAULT_FLAG_INTERRUPTIBLE, "INTERRUPTIBLE" }
411428

412429
/*
413430
* vm_fault is filled by the the pagefault handler and passed to the vma's

0 commit comments

Comments
 (0)