aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/kernel/task_work.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2020-10-15 20:37:01 +0200
committerJiri Kosina <jkosina@suse.cz>2020-10-15 20:37:01 +0200
commit62b31a045757eac81fed94b19df47418a0818528 (patch)
tree285fda56df8304dff6ba929bad65ddfb4e4fd726 /kernel/task_work.c
parentMerge branch 'for-5.10/apple' into for-linus (diff)
parentHID: hid-debug: fix nonblocking read semantics wrt EIO/ERESTARTSYS (diff)
downloadwireguard-linux-62b31a045757eac81fed94b19df47418a0818528.tar.xz
wireguard-linux-62b31a045757eac81fed94b19df47418a0818528.zip
Merge branch 'for-5.10/core' into for-linus
- nonblocking read semantics fix for hid-debug
Diffstat (limited to 'kernel/task_work.c')
-rw-r--r--kernel/task_work.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/kernel/task_work.c b/kernel/task_work.c
index 5c0848ca1287..613b2d634af8 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -42,7 +42,13 @@ task_work_add(struct task_struct *task, struct callback_head *work, int notify)
set_notify_resume(task);
break;
case TWA_SIGNAL:
- if (lock_task_sighand(task, &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);