Commit 92e074ac authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Olof Johansson
Browse files

firmware/psci: psci_checker: Park kthreads before stopping them



Since commit 85f1abe0 ("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: 85f1abe0 ("kthread, sched/wait: Fix kthread_parkme() completion issue")
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Reviewed-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Acked-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parent 5ec47cda
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -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);