diff mbox series

[v2,3/7] mm: Introduce FAULT_FLAG_INTERRUPTIBLE

Message ID 20190905101534.9637-4-peterx@redhat.com (mailing list archive)
State New, archived
Headers show
Series mm: Page fault enhancements | expand

Commit Message

Peter Xu Sept. 5, 2019, 10:15 a.m. UTC
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 <torvalds@linux-foundation.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
 fs/userfaultfd.c   |  4 +---
 include/linux/mm.h | 39 ++++++++++++++++++++++++++++-----------
 2 files changed, 29 insertions(+), 14 deletions(-)

Comments

David Hildenbrand Sept. 6, 2019, 9:02 a.m. UTC | #1
On 05.09.19 12:15, Peter Xu wrote:
> 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 <torvalds@linux-foundation.org>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  fs/userfaultfd.c   |  4 +---
>  include/linux/mm.h | 39 ++++++++++++++++++++++++++++-----------
>  2 files changed, 29 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
> index ccbdbd62f0d8..4a8ad2dc2b6f 100644
> --- a/fs/userfaultfd.c
> +++ b/fs/userfaultfd.c
> @@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
>  	uwq.ctx = ctx;
>  	uwq.waken = false;
>  
> -	return_to_userland =
> -		(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
> -		(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
> +	return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
>  	blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
>  			 TASK_KILLABLE;
>  
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 57fb5c535f8e..53ec7abb8472 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -383,22 +383,38 @@ extern unsigned int kobjsize(const void *objp);
>   */
>  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 */
> -#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 */
> -#define FAULT_FLAG_KILLABLE	0x10	/* The fault task is in SIGKILL killable region */
> -#define FAULT_FLAG_TRIED	0x20	/* Second try */
> -#define FAULT_FLAG_USER		0x40	/* The fault originated in userspace */
> -#define FAULT_FLAG_REMOTE	0x80	/* faulting for non current tsk/mm */
> -#define FAULT_FLAG_INSTRUCTION  0x100	/* The fault was during an instruction fetch */
> +/**
> + * Fault flag definitions.
> + *
> + * @FAULT_FLAG_WRITE: Fault was a write fault.
> + * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
> + * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
> + * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
> + * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
> + * @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
>  

I'd probably split off the unrelated doc changes. Just a matter of taste.

>  /*
>   * The default fault flags that should be used by most of the
>   * arch-specific page fault handlers.
>   */
>  #define FAULT_FLAG_DEFAULT  (FAULT_FLAG_ALLOW_RETRY | \
> -			     FAULT_FLAG_KILLABLE)
> +			     FAULT_FLAG_KILLABLE | \
> +			     FAULT_FLAG_INTERRUPTIBLE)

So by default, all faults are marked interruptible, also
!FAULT_FLAG_USER. I assume the trick right now is that
handle_userfault() will indeed only be called on user faults and the
flag is used nowhere else ;)

Would it make sense to name it FAULT_FLAG_USER_INTERRUPTIBLE, to stress
that the flag only applies to user faults? (or am I missing something
and this could also apply to !user faults somewhen in the future?

(I am no expert on the fault paths yet, so sorry for the silly questions)

>  
>  #define FAULT_FLAG_TRACE \
>  	{ FAULT_FLAG_WRITE,		"WRITE" }, \
> @@ -409,7 +425,8 @@ extern pgprot_t protection_map[16];
>  	{ FAULT_FLAG_TRIED,		"TRIED" }, \
>  	{ FAULT_FLAG_USER,		"USER" }, \
>  	{ 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
>
Peter Xu Sept. 6, 2019, 12:38 p.m. UTC | #2
On Fri, Sep 06, 2019 at 11:02:22AM +0200, David Hildenbrand wrote:
> On 05.09.19 12:15, Peter Xu wrote:
> > 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 <torvalds@linux-foundation.org>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  fs/userfaultfd.c   |  4 +---
> >  include/linux/mm.h | 39 ++++++++++++++++++++++++++++-----------
> >  2 files changed, 29 insertions(+), 14 deletions(-)
> > 
> > diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
> > index ccbdbd62f0d8..4a8ad2dc2b6f 100644
> > --- a/fs/userfaultfd.c
> > +++ b/fs/userfaultfd.c
> > @@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
> >  	uwq.ctx = ctx;
> >  	uwq.waken = false;
> >  
> > -	return_to_userland =
> > -		(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
> > -		(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
> > +	return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
> >  	blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
> >  			 TASK_KILLABLE;
> >  
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index 57fb5c535f8e..53ec7abb8472 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -383,22 +383,38 @@ extern unsigned int kobjsize(const void *objp);
> >   */
> >  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 */
> > -#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 */
> > -#define FAULT_FLAG_KILLABLE	0x10	/* The fault task is in SIGKILL killable region */
> > -#define FAULT_FLAG_TRIED	0x20	/* Second try */
> > -#define FAULT_FLAG_USER		0x40	/* The fault originated in userspace */
> > -#define FAULT_FLAG_REMOTE	0x80	/* faulting for non current tsk/mm */
> > -#define FAULT_FLAG_INSTRUCTION  0x100	/* The fault was during an instruction fetch */
> > +/**
> > + * Fault flag definitions.
> > + *
> > + * @FAULT_FLAG_WRITE: Fault was a write fault.
> > + * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
> > + * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
> > + * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
> > + * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
> > + * @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
> >  
> 
> I'd probably split off the unrelated doc changes. Just a matter of taste.

The thing is that it's not really a document change but only a format
change (when I wanted to add the new macro it's easily getting out of
80 chars so I simply reformatted all the rest to make them look
similar).  I'm afraid that could be too trivial to change the format
as a single patch, but I can do it if anyone else also thinks it
proper.

> 
> >  /*
> >   * The default fault flags that should be used by most of the
> >   * arch-specific page fault handlers.
> >   */
> >  #define FAULT_FLAG_DEFAULT  (FAULT_FLAG_ALLOW_RETRY | \
> > -			     FAULT_FLAG_KILLABLE)
> > +			     FAULT_FLAG_KILLABLE | \
> > +			     FAULT_FLAG_INTERRUPTIBLE)
> 
> So by default, all faults are marked interruptible, also
> !FAULT_FLAG_USER. I assume the trick right now is that
> handle_userfault() will indeed only be called on user faults and the
> flag is used nowhere else ;)

Sorry if this is confusing, but FAULT_FLAG_DEFAULT is just a macro to
make the patchset easier so we define this initial flags for most of
the archs (say, there can be some arch that does not use this default
value, but the fact is most archs are indeed using the same flags
hence we define it here now).

And, userfaultfd can also handle kernel faults.  For FAULT_FLAG_USER,
it will be set if the fault comes from userspace (in
do_user_addr_fault()).

> 
> Would it make sense to name it FAULT_FLAG_USER_INTERRUPTIBLE, to stress
> that the flag only applies to user faults? (or am I missing something
> and this could also apply to !user faults somewhen in the future?

As mentioned above, uffd can handle kernel faults.  And, for what I
understand, it's not really directly related to user fault or not at
all, instead its more or less match with TASK_{INTERRUPTIBLE|KILLABLE}
on what kind of signals we care about during the fault processing.  So
it seems to me that it's two different things.

> 
> (I am no expert on the fault paths yet, so sorry for the silly questions)

(I only hope that I'm not providing silly answers. :)

Thanks,
David Hildenbrand Sept. 6, 2019, 12:53 p.m. UTC | #3
On 06.09.19 14:38, Peter Xu wrote:
> On Fri, Sep 06, 2019 at 11:02:22AM +0200, David Hildenbrand wrote:
>> On 05.09.19 12:15, Peter Xu wrote:
>>> 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 <torvalds@linux-foundation.org>
>>> Signed-off-by: Peter Xu <peterx@redhat.com>
>>> ---
>>>  fs/userfaultfd.c   |  4 +---
>>>  include/linux/mm.h | 39 ++++++++++++++++++++++++++++-----------
>>>  2 files changed, 29 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
>>> index ccbdbd62f0d8..4a8ad2dc2b6f 100644
>>> --- a/fs/userfaultfd.c
>>> +++ b/fs/userfaultfd.c
>>> @@ -462,9 +462,7 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
>>>  	uwq.ctx = ctx;
>>>  	uwq.waken = false;
>>>  
>>> -	return_to_userland =
>>> -		(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
>>> -		(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
>>> +	return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
>>>  	blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
>>>  			 TASK_KILLABLE;
>>>  
>>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>>> index 57fb5c535f8e..53ec7abb8472 100644
>>> --- a/include/linux/mm.h
>>> +++ b/include/linux/mm.h
>>> @@ -383,22 +383,38 @@ extern unsigned int kobjsize(const void *objp);
>>>   */
>>>  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 */
>>> -#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 */
>>> -#define FAULT_FLAG_KILLABLE	0x10	/* The fault task is in SIGKILL killable region */
>>> -#define FAULT_FLAG_TRIED	0x20	/* Second try */
>>> -#define FAULT_FLAG_USER		0x40	/* The fault originated in userspace */
>>> -#define FAULT_FLAG_REMOTE	0x80	/* faulting for non current tsk/mm */
>>> -#define FAULT_FLAG_INSTRUCTION  0x100	/* The fault was during an instruction fetch */
>>> +/**
>>> + * Fault flag definitions.
>>> + *
>>> + * @FAULT_FLAG_WRITE: Fault was a write fault.
>>> + * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
>>> + * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
>>> + * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
>>> + * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
>>> + * @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
>>>  
>>
>> I'd probably split off the unrelated doc changes. Just a matter of taste.
> 
> The thing is that it's not really a document change but only a format
> change (when I wanted to add the new macro it's easily getting out of
> 80 chars so I simply reformatted all the rest to make them look
> similar).  I'm afraid that could be too trivial to change the format
> as a single patch, but I can do it if anyone else also thinks it
> proper.
> 
>>
>>>  /*
>>>   * The default fault flags that should be used by most of the
>>>   * arch-specific page fault handlers.
>>>   */
>>>  #define FAULT_FLAG_DEFAULT  (FAULT_FLAG_ALLOW_RETRY | \
>>> -			     FAULT_FLAG_KILLABLE)
>>> +			     FAULT_FLAG_KILLABLE | \
>>> +			     FAULT_FLAG_INTERRUPTIBLE)
>>
>> So by default, all faults are marked interruptible, also
>> !FAULT_FLAG_USER. I assume the trick right now is that
>> handle_userfault() will indeed only be called on user faults and the
>> flag is used nowhere else ;)
> 
> Sorry if this is confusing, but FAULT_FLAG_DEFAULT is just a macro to
> make the patchset easier so we define this initial flags for most of
> the archs (say, there can be some arch that does not use this default
> value, but the fact is most archs are indeed using the same flags
> hence we define it here now).
> 
> And, userfaultfd can also handle kernel faults.  For FAULT_FLAG_USER,
> it will be set if the fault comes from userspace (in
> do_user_addr_fault()).
> 
Got it, sounds sane to me then.

>>
>> Would it make sense to name it FAULT_FLAG_USER_INTERRUPTIBLE, to stress
>> that the flag only applies to user faults? (or am I missing something
>> and this could also apply to !user faults somewhen in the future?
> 
> As mentioned above, uffd can handle kernel faults.  And, for what I
> understand, it's not really directly related to user fault or not at
> all, instead its more or less match with TASK_{INTERRUPTIBLE|KILLABLE}
> on what kind of signals we care about during the fault processing.  So
> it seems to me that it's two different things.
> 
>>
>> (I am no expert on the fault paths yet, so sorry for the silly questions)
> 
> (I only hope that I'm not providing silly answers. :)

I highly doubt it :) Thanks!
diff mbox series

Patch

diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index ccbdbd62f0d8..4a8ad2dc2b6f 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -462,9 +462,7 @@  vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
 	uwq.ctx = ctx;
 	uwq.waken = false;
 
-	return_to_userland =
-		(vmf->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
-		(FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
+	return_to_userland = vmf->flags & FAULT_FLAG_INTERRUPTIBLE;
 	blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
 			 TASK_KILLABLE;
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 57fb5c535f8e..53ec7abb8472 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -383,22 +383,38 @@  extern unsigned int kobjsize(const void *objp);
  */
 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 */
-#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 */
-#define FAULT_FLAG_KILLABLE	0x10	/* The fault task is in SIGKILL killable region */
-#define FAULT_FLAG_TRIED	0x20	/* Second try */
-#define FAULT_FLAG_USER		0x40	/* The fault originated in userspace */
-#define FAULT_FLAG_REMOTE	0x80	/* faulting for non current tsk/mm */
-#define FAULT_FLAG_INSTRUCTION  0x100	/* The fault was during an instruction fetch */
+/**
+ * Fault flag definitions.
+ *
+ * @FAULT_FLAG_WRITE: Fault was a write fault.
+ * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE.
+ * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked.
+ * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_sem and wait when retrying.
+ * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region.
+ * @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
  * arch-specific page fault handlers.
  */
 #define FAULT_FLAG_DEFAULT  (FAULT_FLAG_ALLOW_RETRY | \
-			     FAULT_FLAG_KILLABLE)
+			     FAULT_FLAG_KILLABLE | \
+			     FAULT_FLAG_INTERRUPTIBLE)
 
 #define FAULT_FLAG_TRACE \
 	{ FAULT_FLAG_WRITE,		"WRITE" }, \
@@ -409,7 +425,8 @@  extern pgprot_t protection_map[16];
 	{ FAULT_FLAG_TRIED,		"TRIED" }, \
 	{ FAULT_FLAG_USER,		"USER" }, \
 	{ 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