summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJason Xing <kerneljasonxing@linux.alibaba.com>2019-08-24 17:54:53 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-29 08:30:24 +0200
commit1e2528273532362bde1f42fb92c7e00a2f08f5fd (patch)
tree9ec09ebd6d39c6fe1b6a7dd558cb891e77f01cd6 /kernel
parentb9e0cc134d735e3599f119f57d2d988ba177c464 (diff)
downloadlinux-stable-1e2528273532362bde1f42fb92c7e00a2f08f5fd.tar.gz
linux-stable-1e2528273532362bde1f42fb92c7e00a2f08f5fd.tar.bz2
linux-stable-1e2528273532362bde1f42fb92c7e00a2f08f5fd.zip
psi: get poll_work to run when calling poll syscall next time
commit 7b2b55da1db10a5525460633ae4b6fb0be060c41 upstream. Only when calling the poll syscall the first time can user receive POLLPRI correctly. After that, user always fails to acquire the event signal. Reproduce case: 1. Get the monitor code in Documentation/accounting/psi.txt 2. Run it, and wait for the event triggered. 3. Kill and restart the process. The question is why we can end up with poll_scheduled = 1 but the work not running (which would reset it to 0). And the answer is because the scheduling side sees group->poll_kworker under RCU protection and then schedules it, but here we cancel the work and destroy the worker. The cancel needs to pair with resetting the poll_scheduled flag. Link: http://lkml.kernel.org/r/1566357985-97781-1-git-send-email-joseph.qi@linux.alibaba.com Signed-off-by: Jason Xing <kerneljasonxing@linux.alibaba.com> Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com> Reviewed-by: Caspar Zhang <caspar@linux.alibaba.com> Reviewed-by: Suren Baghdasaryan <surenb@google.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/psi.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
index 23fbbcc414d5..6e52b67b420e 100644
--- a/kernel/sched/psi.c
+++ b/kernel/sched/psi.c
@@ -1131,7 +1131,15 @@ static void psi_trigger_destroy(struct kref *ref)
* deadlock while waiting for psi_poll_work to acquire trigger_lock
*/
if (kworker_to_destroy) {
+ /*
+ * After the RCU grace period has expired, the worker
+ * can no longer be found through group->poll_kworker.
+ * But it might have been already scheduled before
+ * that - deschedule it cleanly before destroying it.
+ */
kthread_cancel_delayed_work_sync(&group->poll_work);
+ atomic_set(&group->poll_scheduled, 0);
+
kthread_destroy_worker(kworker_to_destroy);
}
kfree(t);