diff options
Diffstat (limited to 'kernel/task_work.c')
| -rw-r--r-- | kernel/task_work.c | 8 | 
1 files changed, 2 insertions, 6 deletions
| diff --git a/kernel/task_work.c b/kernel/task_work.c index d513051fcca2..836a72a66fba 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -96,20 +96,16 @@ void task_work_run(void)  		 * work->func() can do task_work_add(), do not set  		 * work_exited unless the list is empty.  		 */ +		raw_spin_lock_irq(&task->pi_lock);  		do {  			work = READ_ONCE(task->task_works);  			head = !work && (task->flags & PF_EXITING) ?  				&work_exited : NULL;  		} while (cmpxchg(&task->task_works, work, head) != work); +		raw_spin_unlock_irq(&task->pi_lock);  		if (!work)  			break; -		/* -		 * Synchronize with task_work_cancel(). It can't remove -		 * the first entry == work, cmpxchg(task_works) should -		 * fail, but it can play with *work and other entries. -		 */ -		raw_spin_unlock_wait(&task->pi_lock);  		do {  			next = work->next; |