diff options
| author | Linus Torvalds <[email protected]> | 2020-07-02 14:56:22 -0700 | 
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2020-07-02 14:56:22 -0700 | 
| commit | c93493b7cd40c20708e3373a7cc8e8049460d7ce (patch) | |
| tree | 72e472420baacf2168d484bbeaf521423115c049 /kernel/signal.c | |
| parent | cd77006e01b3198c75fb7819b3d0ff89709539bb (diff) | |
| parent | ce593a6c480a22acba08795be313c0c6d49dd35d (diff) | |
Merge tag 'io_uring-5.8-2020-07-01' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe:
 "One fix in here, for a regression in 5.7 where a task is waiting in
  the kernel for a condition, but that condition won't become true until
  task_work is run. And the task_work can't be run exactly because the
  task is waiting in the kernel, so we'll never make any progress.
  One example of that is registering an eventfd and queueing io_uring
  work, and then the task goes and waits in eventfd read with the
  expectation that it'll get woken (and read an event) when the io_uring
  request completes. The io_uring request is finished through task_work,
  which won't get run while the task is looping in eventfd read"
* tag 'io_uring-5.8-2020-07-01' of git://git.kernel.dk/linux-block:
  io_uring: use signal based task_work running
  task_work: teach task_work_add() to do signal_wake_up()
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 10 | 
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 5ca48cc5da76..ee22ec78fd6d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2529,9 +2529,6 @@ bool get_signal(struct ksignal *ksig)  	struct signal_struct *signal = current->signal;  	int signr; -	if (unlikely(current->task_works)) -		task_work_run(); -  	if (unlikely(uprobe_deny_signal()))  		return false; @@ -2544,6 +2541,13 @@ bool get_signal(struct ksignal *ksig)  relock:  	spin_lock_irq(&sighand->siglock); +	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  	 * we should notify the parent, prepare_signal(SIGCONT) encodes  |