firmware/psci: psci_checker: Park kthreads before stopping them
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Mon, 10 Jun 2019 17:38:29 +0000 (18:38 +0100)
committerOlof Johansson <olof@lixom.net>
Mon, 17 Jun 2019 11:50:21 +0000 (04:50 -0700)
Since commit 85f1abe0019f ("kthread, sched/wait: Fix kthread_parkme()
completion issue"), kthreads that are bound to a CPU must be parked
before being stopped. At the moment the PSCI checker calls
kthread_stop() directly on the suspend kthread, which triggers the
following warning:

[    6.068288] WARNING: CPU: 1 PID: 1 at kernel/kthread.c:398 __kthread_bind_mask+0x20/0x78
               ...
[    6.190151] Call trace:
[    6.192566]  __kthread_bind_mask+0x20/0x78
[    6.196615]  kthread_unpark+0x74/0x80
[    6.200235]  kthread_stop+0x44/0x1d8
[    6.203769]  psci_checker+0x3bc/0x484
[    6.207389]  do_one_initcall+0x48/0x260
[    6.211180]  kernel_init_freeable+0x2c8/0x368
[    6.215488]  kernel_init+0x10/0x100
[    6.218935]  ret_from_fork+0x10/0x1c
[    6.222467] ---[ end trace e05e22863d043cd3 ]---

kthread_unpark() tries to bind the thread to its CPU and aborts with a
WARN() if the thread wasn't in TASK_PARKED state. Park the kthreads
before stopping them.

Fixes: 85f1abe0019f ("kthread, sched/wait: Fix kthread_parkme() completion issue")
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
drivers/firmware/psci/psci_checker.c

index 08c8509..f365944 100644 (file)
@@ -359,16 +359,16 @@ static int suspend_test_thread(void *arg)
        for (;;) {
                /* Needs to be set first to avoid missing a wakeup. */
                set_current_state(TASK_INTERRUPTIBLE);
-               if (kthread_should_stop()) {
-                       __set_current_state(TASK_RUNNING);
+               if (kthread_should_park())
                        break;
-               }
                schedule();
        }
 
        pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
                cpu, nb_suspend, nb_shallow_sleep, nb_err);
 
+       kthread_parkme();
+
        return nb_err;
 }
 
@@ -433,8 +433,10 @@ static int suspend_tests(void)
 
 
        /* Stop and destroy all threads, get return status. */
-       for (i = 0; i < nb_threads; ++i)
+       for (i = 0; i < nb_threads; ++i) {
+               err += kthread_park(threads[i]);
                err += kthread_stop(threads[i]);
+       }
  out:
        cpuidle_resume_and_unlock();
        kfree(threads);