1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

tif-task_work.arch-2020-12-14

-----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAl/YJxsQHGF4Ym9lQGtl
 cm5lbC5kawAKCRD301j7KXHgpjpyEACBdW+YjenjTbkUPeEXzQgkBkTZUYw3g007
 DPcUT1g8PQZXYXlQvBKCvGhhIr7/KVcjepKoowiNQfBNGcIPJTVopW58nzpqAfTQ
 goI2WYGn5EKFFKBPvtH04cJD/Wo8muXdxynKtqyZbnGGgZjQxPrE259b8dpHjBSR
 6L7HHkk0D1oU/5b6h6Ocpg9mc/0iIUCZylySAYY3eGO0JaVPJaXgZSJZYgHxCHll
 Lb+/y/fXdtm/0PmQ3ko0ev54g3yEWqZIX0NsZW1asrButIy+KLzQ2Mz1xFLFDMag
 prtIfwb8tzgc4dFPY090C/azjCh5CPpxqYS6FkRwS0p86n6OhkyXrqfily5Hs4/B
 NC7CBPBSH/j+NKUK7CYZcpTzTpxPjUr9p0anUdlvMJz8FhTb/3YEEZ1UTeWOeHmk
 Yo5SxnFghLeZZeZ1ok6rdymnVa7WEX12SCLGQX31BB2mld0tNbKb4b+FsBF6OUMk
 IUaX6OjwDFVRaysC88BQ4hjcIP1HxsViG4/VZDX15gjAAH2Pvb+7tev+lcDcOhjz
 TCD4GNFspTFzRhh9nT7oxQ679qCh9G9zHbzuIRewnrS6iqvo5SJQB3dR2yrWZRRH
 ySkQFiHpYOlnLJYv0jg9COlGwo2FUdcvKhCvkjQKKBz48rzW/IC0LwKdRQWZDFk3
 FKGzP/NBig==
 =cadT
 -----END PGP SIGNATURE-----

Merge tag 'tif-task_work.arch-2020-12-14' of git://git.kernel.dk/linux-block

Pull TIF_NOTIFY_SIGNAL updates from Jens Axboe:
 "This sits on top of of the core entry/exit and x86 entry branch from
  the tip tree, which contains the generic and x86 parts of this work.

  Here we convert the rest of the archs to support TIF_NOTIFY_SIGNAL.

  With that done, we can get rid of JOBCTL_TASK_WORK from task_work and
  signal.c, and also remove a deadlock work-around in io_uring around
  knowing that signal based task_work waking is invoked with the sighand
  wait queue head lock.

  The motivation for this work is to decouple signal notify based
  task_work, of which io_uring is a heavy user of, from sighand. The
  sighand lock becomes a huge contention point, particularly for
  threaded workloads where it's shared between threads. Even outside of
  threaded applications it's slower than it needs to be.

  Roman Gershman <romger@amazon.com> reported that his networked
  workload dropped from 1.6M QPS at 80% CPU to 1.0M QPS at 100% CPU
  after io_uring was changed to use TIF_NOTIFY_SIGNAL. The time was all
  spent hammering on the sighand lock, showing 57% of the CPU time there
  [1].

  There are further cleanups possible on top of this. One example is
  TIF_PATCH_PENDING, where a patch already exists to use
  TIF_NOTIFY_SIGNAL instead. Hopefully this will also lead to more
  consolidation, but the work stands on its own as well"

[1] https://github.com/axboe/liburing/issues/215

* tag 'tif-task_work.arch-2020-12-14' of git://git.kernel.dk/linux-block: (28 commits)
  io_uring: remove 'twa_signal_ok' deadlock work-around
  kernel: remove checking for TIF_NOTIFY_SIGNAL
  signal: kill JOBCTL_TASK_WORK
  io_uring: JOBCTL_TASK_WORK is no longer used by task_work
  task_work: remove legacy TWA_SIGNAL path
  sparc: add support for TIF_NOTIFY_SIGNAL
  riscv: add support for TIF_NOTIFY_SIGNAL
  nds32: add support for TIF_NOTIFY_SIGNAL
  ia64: add support for TIF_NOTIFY_SIGNAL
  h8300: add support for TIF_NOTIFY_SIGNAL
  c6x: add support for TIF_NOTIFY_SIGNAL
  alpha: add support for TIF_NOTIFY_SIGNAL
  xtensa: add support for TIF_NOTIFY_SIGNAL
  arm: add support for TIF_NOTIFY_SIGNAL
  microblaze: add support for TIF_NOTIFY_SIGNAL
  hexagon: add support for TIF_NOTIFY_SIGNAL
  csky: add support for TIF_NOTIFY_SIGNAL
  openrisc: add support for TIF_NOTIFY_SIGNAL
  sh: add support for TIF_NOTIFY_SIGNAL
  um: add support for TIF_NOTIFY_SIGNAL
  ...
This commit is contained in:
Linus Torvalds 2020-12-16 12:33:35 -08:00
commit 005b2a9dc8
61 changed files with 124 additions and 138 deletions

View file

@ -62,6 +62,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SYSCALL_AUDIT 4 /* syscall audit active */ #define TIF_SYSCALL_AUDIT 4 /* syscall audit active */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
#define TIF_MEMDIE 13 /* is terminating due to OOM killer */ #define TIF_MEMDIE 13 /* is terminating due to OOM killer */
#define TIF_POLLING_NRFLAG 14 /* idle is polling for TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 14 /* idle is polling for TIF_NEED_RESCHED */
@ -71,6 +72,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
/* Work to do on interrupt/exception return. */ /* Work to do on interrupt/exception return. */

View file

@ -544,7 +544,7 @@ $ret_success:
.align 4 .align 4
.type work_pending, @function .type work_pending, @function
work_pending: work_pending:
and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2
bne $2, $work_notifysig bne $2, $work_notifysig
$work_resched: $work_resched:

View file

@ -527,7 +527,7 @@ do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
schedule(); schedule();
} else { } else {
local_irq_enable(); local_irq_enable();
if (thread_flags & _TIF_SIGPENDING) { if (thread_flags & (_TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL)) {
do_signal(regs, r0, r19); do_signal(regs, r0, r19);
r0 = 0; r0 = 0;
} else { } else {

View file

@ -79,6 +79,7 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_SYSCALL_TRACE 15 /* syscall trace active */ #define TIF_SYSCALL_TRACE 15 /* syscall trace active */
/* true if poll_idle() is polling TIF_NEED_RESCHED */ /* true if poll_idle() is polling TIF_NEED_RESCHED */
@ -89,11 +90,12 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1<<TIF_MEMDIE) #define _TIF_MEMDIE (1<<TIF_MEMDIE)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME) _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)
/* /*
* _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it. * _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it.

View file

@ -307,7 +307,8 @@ resume_user_mode_begin:
mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume()
GET_CURR_THR_INFO_FLAGS r9 GET_CURR_THR_INFO_FLAGS r9
bbit0 r9, TIF_SIGPENDING, .Lchk_notify_resume and.f 0, r9, TIF_SIGPENDING|TIF_NOTIFY_SIGNAL
bz .Lchk_notify_resume
; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
; in pt_reg since the "C" ABI (kernel code) will automatically ; in pt_reg since the "C" ABI (kernel code) will automatically

View file

@ -362,7 +362,7 @@ void do_signal(struct pt_regs *regs)
restart_scall = in_syscall(regs) && syscall_restartable(regs); restart_scall = in_syscall(regs) && syscall_restartable(regs);
if (get_signal(&ksig)) { if (test_thread_flag(TIF_SIGPENDING) && get_signal(&ksig)) {
if (restart_scall) { if (restart_scall) {
arc_restart_syscall(&ksig.ka, regs); arc_restart_syscall(&ksig.ka, regs);
syscall_wont_restart(regs); /* No more restarts */ syscall_wont_restart(regs); /* No more restarts */

View file

@ -126,6 +126,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
* thread information flags: * thread information flags:
* TIF_USEDFPU - FPU was used by this task this quantum (SMP) * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
* TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
*
* Any bit in the range of 0..15 will cause do_work_pending() to be invoked.
*/ */
#define TIF_SIGPENDING 0 /* signal pending */ #define TIF_SIGPENDING 0 /* signal pending */
#define TIF_NEED_RESCHED 1 /* rescheduling necessary */ #define TIF_NEED_RESCHED 1 /* rescheduling necessary */
@ -135,6 +137,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
#define TIF_SECCOMP 7 /* seccomp syscall filtering active */ #define TIF_SECCOMP 7 /* seccomp syscall filtering active */
#define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */
#define TIF_USING_IWMMXT 17 #define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@ -148,6 +151,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
/* Checks for any syscall work in entry-common.S */ /* Checks for any syscall work in entry-common.S */
@ -158,7 +162,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
* Change these and you break ASM code in entry-common.S * Change these and you break ASM code in entry-common.S
*/ */
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_UPROBE) _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
_TIF_NOTIFY_SIGNAL)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __ASM_ARM_THREAD_INFO_H */ #endif /* __ASM_ARM_THREAD_INFO_H */

View file

@ -53,7 +53,7 @@ __ret_fast_syscall:
cmp r2, #TASK_SIZE cmp r2, #TASK_SIZE
blne addr_limit_check_failed blne addr_limit_check_failed
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK movs r1, r1, lsl #16
bne fast_work_pending bne fast_work_pending
@ -90,7 +90,7 @@ __ret_fast_syscall:
cmp r2, #TASK_SIZE cmp r2, #TASK_SIZE
blne addr_limit_check_failed blne addr_limit_check_failed
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK movs r1, r1, lsl #16
beq no_work_pending beq no_work_pending
UNWIND(.fnend ) UNWIND(.fnend )
ENDPROC(ret_fast_syscall) ENDPROC(ret_fast_syscall)
@ -131,7 +131,7 @@ ENTRY(ret_to_user_from_irq)
cmp r2, #TASK_SIZE cmp r2, #TASK_SIZE
blne addr_limit_check_failed blne addr_limit_check_failed
ldr r1, [tsk, #TI_FLAGS] ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK movs r1, r1, lsl #16
bne slow_work_pending bne slow_work_pending
no_work_pending: no_work_pending:
asm_trace_hardirqs_on save = 0 asm_trace_hardirqs_on save = 0

View file

@ -59,7 +59,7 @@ __irq_entry:
get_thread_info tsk get_thread_info tsk
ldr r2, [tsk, #TI_FLAGS] ldr r2, [tsk, #TI_FLAGS]
tst r2, #_TIF_WORK_MASK movs r2, r2, lsl #16
beq 2f @ no work pending beq 2f @ no work pending
mov r0, #V7M_SCB_ICSR_PENDSVSET mov r0, #V7M_SCB_ICSR_PENDSVSET
str r0, [r1, V7M_SCB_ICSR] @ raise PendSV str r0, [r1, V7M_SCB_ICSR] @ raise PendSV

View file

@ -655,7 +655,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
if (unlikely(!user_mode(regs))) if (unlikely(!user_mode(regs)))
return 0; return 0;
local_irq_enable(); local_irq_enable();
if (thread_flags & _TIF_SIGPENDING) { if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
int restart = do_signal(regs, syscall); int restart = do_signal(regs, syscall);
if (unlikely(restart)) { if (unlikely(restart)) {
/* /*

View file

@ -64,6 +64,7 @@ void arch_release_task_struct(struct task_struct *tsk);
#define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */
#define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */
#define TIF_MTE_ASYNC_FAULT 5 /* MTE Asynchronous Tag Check Fault */ #define TIF_MTE_ASYNC_FAULT 5 /* MTE Asynchronous Tag Check Fault */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */ #define TIF_SYSCALL_TRACE 8 /* syscall trace active */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing */
#define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */ #define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */
@ -93,10 +94,12 @@ void arch_release_task_struct(struct task_struct *tsk);
#define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_32BIT (1 << TIF_32BIT)
#define _TIF_SVE (1 << TIF_SVE) #define _TIF_SVE (1 << TIF_SVE)
#define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) #define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
_TIF_UPROBE | _TIF_MTE_ASYNC_FAULT) _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \
_TIF_NOTIFY_SIGNAL)
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \

View file

@ -939,7 +939,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
(void __user *)NULL, current); (void __user *)NULL, current);
} }
if (thread_flags & _TIF_SIGPENDING) if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME) { if (thread_flags & _TIF_NOTIFY_RESUME) {

View file

@ -82,6 +82,7 @@ struct thread_info *current_thread_info(void)
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_MEMDIE 17 /* OOM killer killed process */ #define TIF_MEMDIE 17 /* OOM killer killed process */

View file

@ -116,6 +116,7 @@ void foo(void)
DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME)); DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING)); DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED)); DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
DEFINE(_TIF_NOTIFY_SIGNAL, (1<<TIF_NOTIFY_SIGNAL));
DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK); DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK); DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);

View file

@ -13,6 +13,7 @@
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/asm-offsets.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
@ -313,7 +314,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags,
int syscall) int syscall)
{ {
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & (1 << TIF_SIGPENDING)) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs, syscall); do_signal(regs, syscall);
if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) if (thread_info_flags & (1 << TIF_NOTIFY_RESUME))

View file

@ -64,6 +64,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 4 /* syscall trace active */ #define TIF_SYSCALL_TRACE 4 /* syscall trace active */
#define TIF_SYSCALL_TRACEPOINT 5 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 5 /* syscall tracepoint instrumentation */
#define TIF_SYSCALL_AUDIT 6 /* syscall auditing */ #define TIF_SYSCALL_AUDIT 6 /* syscall auditing */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
@ -75,6 +76,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_UPROBE (1 << TIF_UPROBE)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
@ -82,7 +84,8 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_UPROBE) _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
_TIF_NOTIFY_SIGNAL)
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP) _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)

View file

@ -257,7 +257,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
uprobe_notify_resume(regs); uprobe_notify_resume(regs);
/* Handle pending signal delivery */ /* Handle pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) { if (thread_info_flags & _TIF_NOTIFY_RESUME) {

View file

@ -73,6 +73,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */
#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_NOTIFY_SIGNAL 10 /* signal notifications exist */
/* as above, but as bit values */ /* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
@ -83,6 +84,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
/* work to do in syscall trace */ /* work to do in syscall trace */
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ #define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
@ -92,7 +94,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
_TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \ _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \
_TIF_SYSCALL_TRACEPOINT) _TIF_SYSCALL_TRACEPOINT | _TIF_NOTIFY_SIGNAL)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \ #define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \

View file

@ -279,7 +279,7 @@ static void do_signal(struct pt_regs *regs)
asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
{ {
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) if (thread_info_flags & _TIF_NOTIFY_RESUME)

View file

@ -95,6 +95,7 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */ #define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */
#define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */ #define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
/* true if poll_idle() is polling TIF_NEED_RESCHED */ /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* OOM killer killed process */ #define TIF_MEMDIE 17 /* OOM killer killed process */
@ -103,6 +104,7 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
/* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */ /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
#define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE) #define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE)

View file

@ -174,7 +174,7 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
return 1; return 1;
} }
if (thread_info_flags & _TIF_SIGPENDING) { if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
do_signal(regs); do_signal(regs);
return 1; return 1;
} }

View file

@ -103,6 +103,7 @@ struct thread_info {
#define TIF_SYSCALL_TRACE 2 /* syscall trace active */ #define TIF_SYSCALL_TRACE 2 /* syscall trace active */
#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_NOTIFY_SIGNAL 5 /* signal notification exist */
#define TIF_NOTIFY_RESUME 6 /* resumption notification requested */ #define TIF_NOTIFY_RESUME 6 /* resumption notification requested */
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */
#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ #define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
@ -115,6 +116,7 @@ struct thread_info {
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP) #define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_MCA_INIT (1 << TIF_MCA_INIT) #define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
@ -124,7 +126,7 @@ struct thread_info {
/* "work to do on user-return" bits */ /* "work to do on user-return" bits */
#define TIF_ALLWORK_MASK (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\ #define TIF_ALLWORK_MASK (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\
_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE) _TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_NOTIFY_SIGNAL)
/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */ /* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */
#define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)) #define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))

View file

@ -171,7 +171,8 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
} }
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (test_thread_flag(TIF_SIGPENDING)) { if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL)) {
local_irq_enable(); /* force interrupt enable */ local_irq_enable(); /* force interrupt enable */
ia64_do_signal(scr, in_syscall); ia64_do_signal(scr, in_syscall);
} }

View file

@ -60,6 +60,7 @@ static inline struct thread_info *current_thread_info(void)
* bits 0-7 are tested at every exception exit * bits 0-7 are tested at every exception exit
* bits 8-15 are also tested at syscall exit * bits 8-15 are also tested at syscall exit
*/ */
#define TIF_NOTIFY_SIGNAL 4
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_SIGPENDING 6 /* signal pending */ #define TIF_SIGPENDING 6 /* signal pending */
#define TIF_NEED_RESCHED 7 /* rescheduling necessary */ #define TIF_NEED_RESCHED 7 /* rescheduling necessary */

View file

@ -1133,7 +1133,8 @@ static void do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SIGPENDING)) if (test_thread_flag(TIF_NOTIFY_SIGNAL) ||
test_thread_flag(TIF_SIGPENDING))
do_signal(regs); do_signal(regs);
if (test_thread_flag(TIF_NOTIFY_RESUME)) if (test_thread_flag(TIF_NOTIFY_RESUME))

View file

@ -115,6 +115,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SECCOMP 4 /* secure computing */ #define TIF_SECCOMP 4 /* secure computing */
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_UPROBE 6 /* breakpointed or singlestepping */ #define TIF_UPROBE 6 /* breakpointed or singlestepping */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@ -139,6 +140,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_UPROBE (1<<TIF_UPROBE) #define _TIF_UPROBE (1<<TIF_UPROBE)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_NOHZ (1<<TIF_NOHZ) #define _TIF_NOHZ (1<<TIF_NOHZ)
#define _TIF_FIXADE (1<<TIF_FIXADE) #define _TIF_FIXADE (1<<TIF_FIXADE)
@ -164,7 +166,7 @@ static inline struct thread_info *current_thread_info(void)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME | \ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME | \
_TIF_UPROBE) _TIF_UPROBE | _TIF_NOTIFY_SIGNAL)
/* work to do on any return to u-space */ /* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \ #define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
_TIF_WORK_SYSCALL_EXIT | \ _TIF_WORK_SYSCALL_EXIT | \

View file

@ -903,7 +903,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
uprobe_notify_resume(regs); uprobe_notify_resume(regs);
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) { if (thread_info_flags & _TIF_NOTIFY_RESUME) {

View file

@ -48,6 +48,7 @@ struct thread_info {
#define TIF_NEED_RESCHED 2 #define TIF_NEED_RESCHED 2
#define TIF_SINGLESTEP 3 #define TIF_SINGLESTEP 3
#define TIF_NOTIFY_RESUME 4 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 4 /* callback before returning to user */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_POLLING_NRFLAG 17 #define TIF_POLLING_NRFLAG 17
#define TIF_MEMDIE 18 #define TIF_MEMDIE 18
@ -57,6 +58,7 @@ struct thread_info {
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)

View file

@ -120,7 +120,7 @@ work_pending:
andi $p1, $r1, #_TIF_NEED_RESCHED andi $p1, $r1, #_TIF_NEED_RESCHED
bnez $p1, work_resched bnez $p1, work_resched
andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME|#_TIF_NOTIFY_SIGNAL
beqz $p1, no_work_pending beqz $p1, no_work_pending
move $r0, $sp ! 'regs' move $r0, $sp ! 'regs'

View file

@ -376,7 +376,7 @@ static void do_signal(struct pt_regs *regs)
asmlinkage void asmlinkage void
do_notify_resume(struct pt_regs *regs, unsigned int thread_flags) do_notify_resume(struct pt_regs *regs, unsigned int thread_flags)
{ {
if (thread_flags & _TIF_SIGPENDING) if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME) if (thread_flags & _TIF_NOTIFY_RESUME)

View file

@ -86,6 +86,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ #define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_SECCOMP 5 /* secure computing */ #define TIF_SECCOMP 5 /* secure computing */
#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling
@ -97,6 +98,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)

View file

@ -306,7 +306,8 @@ asmlinkage int do_notify_resume(struct pt_regs *regs)
if (!user_mode(regs)) if (!user_mode(regs))
return 0; return 0;
if (test_thread_flag(TIF_SIGPENDING)) { if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL)) {
int restart = do_signal(regs); int restart = do_signal(regs);
if (unlikely(restart)) { if (unlikely(restart)) {

View file

@ -98,6 +98,7 @@ register struct thread_info *current_thread_info_reg asm("r10");
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user #define TIF_SINGLESTEP 4 /* restore singlestep on return to user
* mode * mode
*/ */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */
#define TIF_RESTORE_SIGMASK 9 #define TIF_RESTORE_SIGMASK 9
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling * TIF_NEED_RESCHED #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling * TIF_NEED_RESCHED
@ -109,6 +110,7 @@ register struct thread_info *current_thread_info_reg asm("r10");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)

View file

@ -299,7 +299,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
if (unlikely(!user_mode(regs))) if (unlikely(!user_mode(regs)))
return 0; return 0;
local_irq_enable(); local_irq_enable();
if (thread_flags & _TIF_SIGPENDING) { if (thread_flags & (_TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL)) {
int restart = do_signal(regs, syscall); int restart = do_signal(regs, syscall);
if (unlikely(restart)) { if (unlikely(restart)) {
/* /*

View file

@ -52,6 +52,7 @@ struct thread_info {
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_32BIT 4 /* 32 bit binary */ #define TIF_32BIT 4 /* 32 bit binary */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_NOTIFY_SIGNAL 6 /* signal notifications exist */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
#define TIF_SINGLESTEP 9 /* single stepping? */ #define TIF_SINGLESTEP 9 /* single stepping? */
@ -61,6 +62,7 @@ struct thread_info {
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_32BIT (1 << TIF_32BIT)
@ -72,7 +74,7 @@ struct thread_info {
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
_TIF_NEED_RESCHED) _TIF_NEED_RESCHED | _TIF_NOTIFY_SIGNAL)
#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ #define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
_TIF_BLOCKSTEP | _TIF_SYSCALL_AUDIT | \ _TIF_BLOCKSTEP | _TIF_SYSCALL_AUDIT | \
_TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT) _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)

View file

@ -603,7 +603,8 @@ do_signal(struct pt_regs *regs, long in_syscall)
void do_notify_resume(struct pt_regs *regs, long in_syscall) void do_notify_resume(struct pt_regs *regs, long in_syscall)
{ {
if (test_thread_flag(TIF_SIGPENDING)) if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL))
do_signal(regs, in_syscall); do_signal(regs, in_syscall);
if (test_thread_flag(TIF_NOTIFY_RESUME)) if (test_thread_flag(TIF_NOTIFY_RESUME))

View file

@ -90,6 +90,7 @@ void arch_setup_new_exec(void);
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_SIGNAL 3 /* signal notifications exist */
#define TIF_SYSCALL_EMU 4 /* syscall emulation active */ #define TIF_SYSCALL_EMU 4 /* syscall emulation active */
#define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */
#define TIF_PATCH_PENDING 6 /* pending live patching update */ #define TIF_PATCH_PENDING 6 /* pending live patching update */
@ -115,6 +116,7 @@ void arch_setup_new_exec(void);
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_32BIT (1<<TIF_32BIT) #define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_RESTORE_TM (1<<TIF_RESTORE_TM) #define _TIF_RESTORE_TM (1<<TIF_RESTORE_TM)
@ -136,7 +138,8 @@ void arch_setup_new_exec(void);
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_NOTIFY_RESUME | _TIF_UPROBE | \ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
_TIF_RESTORE_TM | _TIF_PATCH_PENDING) _TIF_RESTORE_TM | _TIF_PATCH_PENDING | \
_TIF_NOTIFY_SIGNAL)
#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR)
/* Bits in local_flags */ /* Bits in local_flags */

View file

@ -318,7 +318,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
if (thread_info_flags & _TIF_PATCH_PENDING) if (thread_info_flags & _TIF_PATCH_PENDING)
klp_update_patch_state(current); klp_update_patch_state(current);
if (thread_info_flags & _TIF_SIGPENDING) { if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
BUG_ON(regs != current->thread.regs); BUG_ON(regs != current->thread.regs);
do_signal(current); do_signal(current);
} }

View file

@ -74,6 +74,7 @@ struct thread_info {
#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing */
#define TIF_SECCOMP 8 /* syscall secure computing */ #define TIF_SECCOMP 8 /* syscall secure computing */
#define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@ -82,9 +83,11 @@ struct thread_info {
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED) (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_NOTIFY_SIGNAL)
#define _TIF_SYSCALL_WORK \ #define _TIF_SYSCALL_WORK \
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT | \ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT | \

View file

@ -310,7 +310,7 @@ asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
unsigned long thread_info_flags) unsigned long thread_info_flags)
{ {
/* Handle pending signal delivery */ /* Handle pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) if (thread_info_flags & _TIF_NOTIFY_RESUME)

View file

@ -65,6 +65,7 @@ void arch_setup_new_exec(void);
#define TIF_GUARDED_STORAGE 4 /* load guarded storage control block */ #define TIF_GUARDED_STORAGE 4 /* load guarded storage control block */
#define TIF_PATCH_PENDING 5 /* pending live patching update */ #define TIF_PATCH_PENDING 5 /* pending live patching update */
#define TIF_PGSTE 6 /* New mm's will use 4K page tables */ #define TIF_PGSTE 6 /* New mm's will use 4K page tables */
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_ISOLATE_BP 8 /* Run process with isolated BP */ #define TIF_ISOLATE_BP 8 /* Run process with isolated BP */
#define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */ #define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */
@ -82,6 +83,7 @@ void arch_setup_new_exec(void);
#define TIF_SYSCALL_TRACEPOINT 27 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 27 /* syscall tracepoint instrumentation */
#define _TIF_NOTIFY_RESUME BIT(TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME BIT(TIF_NOTIFY_RESUME)
#define _TIF_NOTIFY_SIGNAL BIT(TIF_NOTIFY_SIGNAL)
#define _TIF_SIGPENDING BIT(TIF_SIGPENDING) #define _TIF_SIGPENDING BIT(TIF_SIGPENDING)
#define _TIF_NEED_RESCHED BIT(TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED BIT(TIF_NEED_RESCHED)
#define _TIF_UPROBE BIT(TIF_UPROBE) #define _TIF_UPROBE BIT(TIF_UPROBE)

View file

@ -52,7 +52,8 @@ STACK_SIZE = 1 << STACK_SHIFT
STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
_TIF_WORK = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_WORK = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_UPROBE | _TIF_GUARDED_STORAGE | _TIF_PATCH_PENDING) _TIF_UPROBE | _TIF_GUARDED_STORAGE | _TIF_PATCH_PENDING | \
_TIF_NOTIFY_SIGNAL)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT) _TIF_SYSCALL_TRACEPOINT)
_CIF_WORK = (_CIF_FPU) _CIF_WORK = (_CIF_FPU)
@ -486,8 +487,8 @@ ENTRY(system_call)
#endif #endif
TSTMSK __PT_FLAGS(%r11),_PIF_SYSCALL_RESTART TSTMSK __PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
jo .Lsysc_syscall_restart jo .Lsysc_syscall_restart
TSTMSK __TI_flags(%r12),_TIF_SIGPENDING TSTMSK __TI_flags(%r12),(_TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL)
jo .Lsysc_sigpending jnz .Lsysc_sigpending
TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lsysc_notify_resume jo .Lsysc_notify_resume
j .Lsysc_return j .Lsysc_return
@ -865,8 +866,8 @@ ENTRY(io_int_handler)
TSTMSK __TI_flags(%r12),_TIF_PATCH_PENDING TSTMSK __TI_flags(%r12),_TIF_PATCH_PENDING
jo .Lio_patch_pending jo .Lio_patch_pending
#endif #endif
TSTMSK __TI_flags(%r12),_TIF_SIGPENDING TSTMSK __TI_flags(%r12),(_TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL)
jo .Lio_sigpending jnz .Lio_sigpending
TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lio_notify_resume jo .Lio_notify_resume
TSTMSK __TI_flags(%r12),_TIF_GUARDED_STORAGE TSTMSK __TI_flags(%r12),_TIF_GUARDED_STORAGE

View file

@ -472,7 +472,7 @@ void do_signal(struct pt_regs *regs)
current->thread.system_call = current->thread.system_call =
test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0; test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
if (get_signal(&ksig)) { if (test_thread_flag(TIF_SIGPENDING) && get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (current->thread.system_call) { if (current->thread.system_call) {
regs->int_code = current->thread.system_call; regs->int_code = current->thread.system_call;

View file

@ -105,6 +105,7 @@ extern void init_thread_xstate(void);
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_SIGNAL 3 /* signal notifications exist */
#define TIF_SINGLESTEP 4 /* singlestepping active */ #define TIF_SINGLESTEP 4 /* singlestepping active */
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SECCOMP 6 /* secure computing */ #define TIF_SECCOMP 6 /* secure computing */
@ -116,6 +117,7 @@ extern void init_thread_xstate(void);
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
@ -132,7 +134,7 @@ extern void init_thread_xstate(void);
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
_TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \ _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \
_TIF_SYSCALL_TRACEPOINT) _TIF_SYSCALL_TRACEPOINT | _TIF_NOTIFY_SIGNAL)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \ #define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \

View file

@ -499,7 +499,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
unsigned long thread_info_flags) unsigned long thread_info_flags)
{ {
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs, save_r0); do_signal(regs, save_r0);
if (thread_info_flags & _TIF_NOTIFY_RESUME) if (thread_info_flags & _TIF_NOTIFY_RESUME)

View file

@ -104,6 +104,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_USEDFPU 8 /* FPU was used by this task #define TIF_USEDFPU 8 /* FPU was used by this task
* this quantum (SMP) */ * this quantum (SMP) */
#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling #define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling
@ -115,11 +116,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING) _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)
#define is_32bit_task() (1) #define is_32bit_task() (1)

View file

@ -180,7 +180,7 @@ extern struct thread_info *current_thread_info(void);
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
/* flag bit 4 is available */ #define TIF_NOTIFY_SIGNAL 4 /* signal notifications exist */
#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */
#define TIF_UPROBE 6 /* breakpointed or singlestepped */ #define TIF_UPROBE 6 /* breakpointed or singlestepped */
#define TIF_32BIT 7 /* 32-bit binary */ #define TIF_32BIT 7 /* 32-bit binary */
@ -200,6 +200,7 @@ extern struct thread_info *current_thread_info(void);
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_UNALIGNED (1<<TIF_UNALIGNED) #define _TIF_UNALIGNED (1<<TIF_UNALIGNED)
#define _TIF_UPROBE (1<<TIF_UPROBE) #define _TIF_UPROBE (1<<TIF_UPROBE)
#define _TIF_32BIT (1<<TIF_32BIT) #define _TIF_32BIT (1<<TIF_32BIT)
@ -213,7 +214,8 @@ extern struct thread_info *current_thread_info(void);
_TIF_DO_NOTIFY_RESUME_MASK | \ _TIF_DO_NOTIFY_RESUME_MASK | \
_TIF_NEED_RESCHED) _TIF_NEED_RESCHED)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING | _TIF_UPROBE) _TIF_SIGPENDING | _TIF_UPROBE | \
_TIF_NOTIFY_SIGNAL)
#define is_32bit_task() (test_thread_flag(TIF_32BIT)) #define is_32bit_task() (test_thread_flag(TIF_32BIT))

View file

@ -521,7 +521,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
unsigned long thread_info_flags) unsigned long thread_info_flags)
{ {
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs, orig_i0); do_signal(regs, orig_i0);
if (thread_info_flags & _TIF_NOTIFY_RESUME) if (thread_info_flags & _TIF_NOTIFY_RESUME)
tracehook_notify_resume(regs); tracehook_notify_resume(regs);

View file

@ -549,7 +549,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
user_exit(); user_exit();
if (thread_info_flags & _TIF_UPROBE) if (thread_info_flags & _TIF_UPROBE)
uprobe_notify_resume(regs); uprobe_notify_resume(regs);
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs, orig_i0); do_signal(regs, orig_i0);
if (thread_info_flags & _TIF_NOTIFY_RESUME) if (thread_info_flags & _TIF_NOTIFY_RESUME)
tracehook_notify_resume(regs); tracehook_notify_resume(regs);

View file

@ -57,6 +57,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_SIGNAL 3 /* signal notifications exist */
#define TIF_RESTART_BLOCK 4 #define TIF_RESTART_BLOCK 4
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 6 #define TIF_SYSCALL_AUDIT 6
@ -67,6 +68,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)

View file

@ -99,7 +99,8 @@ void interrupt_end(void)
if (need_resched()) if (need_resched())
schedule(); schedule();
if (test_thread_flag(TIF_SIGPENDING)) if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (test_thread_flag(TIF_NOTIFY_RESUME)) if (test_thread_flag(TIF_NOTIFY_RESUME))
tracehook_notify_resume(regs); tracehook_notify_resume(regs);

View file

@ -111,18 +111,21 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
#define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
#define TIF_DB_DISABLED 8 /* debug trap disabled for syscall */ #define TIF_DB_DISABLED 8 /* debug trap disabled for syscall */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */ #define TIF_SECCOMP 10 /* secure computing */
#define TIF_MEMDIE 11 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)

View file

@ -500,8 +500,8 @@ common_exception_return:
*/ */
_bbsi.l a4, TIF_NEED_RESCHED, 3f _bbsi.l a4, TIF_NEED_RESCHED, 3f
_bbsi.l a4, TIF_NOTIFY_RESUME, 2f movi a2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL
_bbci.l a4, TIF_SIGPENDING, 5f bnone a4, a2, 5f
2: l32i a4, a1, PT_DEPC 2: l32i a4, a1, PT_DEPC
bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f

View file

@ -498,7 +498,8 @@ static void do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SIGPENDING)) if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (test_thread_flag(TIF_NOTIFY_RESUME)) if (test_thread_flag(TIF_NOTIFY_RESUME))

View file

@ -1996,7 +1996,7 @@ static struct io_kiocb *io_req_find_next(struct io_kiocb *req)
return __io_req_find_next(req); return __io_req_find_next(req);
} }
static int io_req_task_work_add(struct io_kiocb *req, bool twa_signal_ok) static int io_req_task_work_add(struct io_kiocb *req)
{ {
struct task_struct *tsk = req->task; struct task_struct *tsk = req->task;
struct io_ring_ctx *ctx = req->ctx; struct io_ring_ctx *ctx = req->ctx;
@ -2013,7 +2013,7 @@ static int io_req_task_work_add(struct io_kiocb *req, bool twa_signal_ok)
* will do the job. * will do the job.
*/ */
notify = TWA_NONE; notify = TWA_NONE;
if (!(ctx->flags & IORING_SETUP_SQPOLL) && twa_signal_ok) if (!(ctx->flags & IORING_SETUP_SQPOLL))
notify = TWA_SIGNAL; notify = TWA_SIGNAL;
ret = task_work_add(tsk, &req->task_work, notify); ret = task_work_add(tsk, &req->task_work, notify);
@ -2075,7 +2075,7 @@ static void io_req_task_queue(struct io_kiocb *req)
init_task_work(&req->task_work, io_req_task_submit); init_task_work(&req->task_work, io_req_task_submit);
percpu_ref_get(&req->ctx->refs); percpu_ref_get(&req->ctx->refs);
ret = io_req_task_work_add(req, true); ret = io_req_task_work_add(req);
if (unlikely(ret)) { if (unlikely(ret)) {
struct task_struct *tsk; struct task_struct *tsk;
@ -2197,7 +2197,7 @@ static void io_free_req_deferred(struct io_kiocb *req)
int ret; int ret;
init_task_work(&req->task_work, io_put_req_deferred_cb); init_task_work(&req->task_work, io_put_req_deferred_cb);
ret = io_req_task_work_add(req, true); ret = io_req_task_work_add(req);
if (unlikely(ret)) { if (unlikely(ret)) {
struct task_struct *tsk; struct task_struct *tsk;
@ -3305,7 +3305,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
/* submit ref gets dropped, acquire a new one */ /* submit ref gets dropped, acquire a new one */
refcount_inc(&req->refs); refcount_inc(&req->refs);
ret = io_req_task_work_add(req, true); ret = io_req_task_work_add(req);
if (unlikely(ret)) { if (unlikely(ret)) {
struct task_struct *tsk; struct task_struct *tsk;
@ -4859,7 +4859,6 @@ struct io_poll_table {
static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll, static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,
__poll_t mask, task_work_func_t func) __poll_t mask, task_work_func_t func)
{ {
bool twa_signal_ok;
int ret; int ret;
/* for instances that support it check for an event match first: */ /* for instances that support it check for an event match first: */
@ -4874,21 +4873,13 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,
init_task_work(&req->task_work, func); init_task_work(&req->task_work, func);
percpu_ref_get(&req->ctx->refs); percpu_ref_get(&req->ctx->refs);
/*
* If we using the signalfd wait_queue_head for this wakeup, then
* it's not safe to use TWA_SIGNAL as we could be recursing on the
* tsk->sighand->siglock on doing the wakeup. Should not be needed
* either, as the normal wakeup will suffice.
*/
twa_signal_ok = (poll->head != &req->task->sighand->signalfd_wqh);
/* /*
* If this fails, then the task is exiting. When a task exits, the * If this fails, then the task is exiting. When a task exits, the
* work gets canceled, so just cancel this request as well instead * work gets canceled, so just cancel this request as well instead
* of executing it. We can't safely execute it anyway, as we may not * of executing it. We can't safely execute it anyway, as we may not
* have the needed state needed for it anyway. * have the needed state needed for it anyway.
*/ */
ret = io_req_task_work_add(req, twa_signal_ok); ret = io_req_task_work_add(req);
if (unlikely(ret)) { if (unlikely(ret)) {
struct task_struct *tsk; struct task_struct *tsk;
@ -6862,13 +6853,8 @@ static int io_run_task_work_sig(void)
return 1; return 1;
if (!signal_pending(current)) if (!signal_pending(current))
return 0; return 0;
if (current->jobctl & JOBCTL_TASK_WORK) { if (test_tsk_thread_flag(current, TIF_NOTIFY_SIGNAL))
spin_lock_irq(&current->sighand->siglock); return -ERESTARTSYS;
current->jobctl &= ~JOBCTL_TASK_WORK;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
return 1;
}
return -EINTR; return -EINTR;
} }

View file

@ -21,10 +21,6 @@
# define _TIF_UPROBE (0) # define _TIF_UPROBE (0)
#endif #endif
#ifndef _TIF_NOTIFY_SIGNAL
# define _TIF_NOTIFY_SIGNAL (0)
#endif
/* /*
* SYSCALL_WORK flags handled in syscall_enter_from_user_mode() * SYSCALL_WORK flags handled in syscall_enter_from_user_mode()
*/ */

View file

@ -19,7 +19,6 @@ struct task_struct;
#define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */
#define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */
#define JOBCTL_TRAP_FREEZE_BIT 23 /* trap for cgroup freezer */ #define JOBCTL_TRAP_FREEZE_BIT 23 /* trap for cgroup freezer */
#define JOBCTL_TASK_WORK_BIT 24 /* set by TWA_SIGNAL */
#define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) #define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT)
#define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) #define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT)
@ -29,10 +28,9 @@ struct task_struct;
#define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) #define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT)
#define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT)
#define JOBCTL_TRAP_FREEZE (1UL << JOBCTL_TRAP_FREEZE_BIT) #define JOBCTL_TRAP_FREEZE (1UL << JOBCTL_TRAP_FREEZE_BIT)
#define JOBCTL_TASK_WORK (1UL << JOBCTL_TASK_WORK_BIT)
#define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY)
#define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK | JOBCTL_TASK_WORK) #define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK)
extern bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask); extern bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask);
extern void task_clear_jobctl_trapping(struct task_struct *task); extern void task_clear_jobctl_trapping(struct task_struct *task);

View file

@ -361,7 +361,6 @@ static inline int task_sigpending(struct task_struct *p)
static inline int signal_pending(struct task_struct *p) static inline int signal_pending(struct task_struct *p)
{ {
#if defined(TIF_NOTIFY_SIGNAL)
/* /*
* TIF_NOTIFY_SIGNAL isn't really a signal, but it requires the same * TIF_NOTIFY_SIGNAL isn't really a signal, but it requires the same
* behavior in terms of ensuring that we break out of wait loops * behavior in terms of ensuring that we break out of wait loops
@ -369,7 +368,6 @@ static inline int signal_pending(struct task_struct *p)
*/ */
if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL))) if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL)))
return 1; return 1;
#endif
return task_sigpending(p); return task_sigpending(p);
} }

View file

@ -206,12 +206,10 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
*/ */
static inline void tracehook_notify_signal(void) static inline void tracehook_notify_signal(void)
{ {
#if defined(TIF_NOTIFY_SIGNAL)
clear_thread_flag(TIF_NOTIFY_SIGNAL); clear_thread_flag(TIF_NOTIFY_SIGNAL);
smp_mb__after_atomic(); smp_mb__after_atomic();
if (current->task_works) if (current->task_works)
task_work_run(); task_work_run();
#endif
} }
/* /*
@ -219,11 +217,9 @@ static inline void tracehook_notify_signal(void)
*/ */
static inline void set_notify_signal(struct task_struct *task) static inline void set_notify_signal(struct task_struct *task)
{ {
#if defined(TIF_NOTIFY_SIGNAL)
if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) && if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) &&
!wake_up_state(task, TASK_INTERRUPTIBLE)) !wake_up_state(task, TASK_INTERRUPTIBLE))
kick_process(task); kick_process(task);
#endif
} }
#endif /* <linux/tracehook.h> */ #endif /* <linux/tracehook.h> */

View file

@ -2555,14 +2555,12 @@ bool get_signal(struct ksignal *ksig)
* that the arch handlers don't all have to do it. If we get here * that the arch handlers don't all have to do it. If we get here
* without TIF_SIGPENDING, just exit after running signal work. * without TIF_SIGPENDING, just exit after running signal work.
*/ */
#ifdef TIF_NOTIFY_SIGNAL
if (!IS_ENABLED(CONFIG_GENERIC_ENTRY)) { if (!IS_ENABLED(CONFIG_GENERIC_ENTRY)) {
if (test_thread_flag(TIF_NOTIFY_SIGNAL)) if (test_thread_flag(TIF_NOTIFY_SIGNAL))
tracehook_notify_signal(); tracehook_notify_signal();
if (!task_sigpending(current)) if (!task_sigpending(current))
return false; return false;
} }
#endif
if (unlikely(uprobe_deny_signal())) if (unlikely(uprobe_deny_signal()))
return false; return false;
@ -2576,26 +2574,6 @@ bool get_signal(struct ksignal *ksig)
relock: relock:
spin_lock_irq(&sighand->siglock); spin_lock_irq(&sighand->siglock);
/*
* Make sure we can safely read ->jobctl() in task_work add. As Oleg
* states:
*
* It pairs with mb (implied by cmpxchg) before READ_ONCE. So we
* roughly have
*
* task_work_add: get_signal:
* STORE(task->task_works, new_work); STORE(task->jobctl);
* mb(); mb();
* LOAD(task->jobctl); LOAD(task->task_works);
*
* and we can rely on STORE-MB-LOAD [ in task_work_add].
*/
smp_store_mb(current->jobctl, current->jobctl & ~JOBCTL_TASK_WORK);
if (unlikely(current->task_works)) {
spin_unlock_irq(&sighand->siglock);
task_work_run();
goto relock;
}
/* /*
* Every stopped thread goes here after wakeup. Check to see if * Every stopped thread goes here after wakeup. Check to see if

View file

@ -5,34 +5,6 @@
static struct callback_head work_exited; /* all we need is ->next == NULL */ static struct callback_head work_exited; /* all we need is ->next == NULL */
/*
* TWA_SIGNAL signaling - use TIF_NOTIFY_SIGNAL, if available, as it's faster
* than TIF_SIGPENDING as there's no dependency on ->sighand. The latter is
* shared for threads, and can cause contention on sighand->lock. Even for
* the non-threaded case TIF_NOTIFY_SIGNAL is more efficient, as no locking
* or IRQ disabling is involved for notification (or running) purposes.
*/
static void task_work_notify_signal(struct task_struct *task)
{
#if defined(TIF_NOTIFY_SIGNAL)
set_notify_signal(task);
#else
unsigned long flags;
/*
* Only grab the sighand lock if we don't already have some
* task_work pending. This pairs with the smp_store_mb()
* in get_signal(), see comment there.
*/
if (!(READ_ONCE(task->jobctl) & JOBCTL_TASK_WORK) &&
lock_task_sighand(task, &flags)) {
task->jobctl |= JOBCTL_TASK_WORK;
signal_wake_up(task, 0);
unlock_task_sighand(task, &flags);
}
#endif
}
/** /**
* task_work_add - ask the @task to execute @work->func() * task_work_add - ask the @task to execute @work->func()
* @task: the task which should run the callback * @task: the task which should run the callback
@ -76,7 +48,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
set_notify_resume(task); set_notify_resume(task);
break; break;
case TWA_SIGNAL: case TWA_SIGNAL:
task_work_notify_signal(task); set_notify_signal(task);
break; break;
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);