aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2022-06-24 03:14:49 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2022-07-19 22:09:26 +0200
commit1f95b638b0c612ea5d265fff7ad6a7161b168385 (patch)
tree88def83c1193a6f193ca53e666cb1ad108fc9c2a /include/linux
parentpowerpc/kvm: don't crash on missing rng, and use darn (diff)
downloadlinux-dev-1f95b638b0c612ea5d265fff7ad6a7161b168385.tar.xz
linux-dev-1f95b638b0c612ea5d265fff7ad6a7161b168385.zip
ath9k: let sleep be interrupted when unregistering hwrng
There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() instead of schedule_timeout_interruptible(). The fix is a simple moving to the correct function. At the same time, we should cleanup a common and useless dmesg splat in the same area. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. The solution here is to keep track of which thread is currently reading, and asleep, and signal that thread when it's time to unregister. There's a bit of book keeping required to prevent lifetime issues on current. Cc: Kalle Valo <kvalo@kernel.org> Cc: Rui Salvaterra <rsalvaterra@gmail.com> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Valentin Schneider <vschneid@redhat.com> Cc: stable@vger.kernel.org Reported-by: Gregory Erwin <gregerwin256@gmail.com> Tested-by: Gregory Erwin <gregerwin256@gmail.com> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/sched/signal.h2
2 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c46f3a63b758..f164098fb614 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1936,6 +1936,7 @@ extern struct task_struct *find_get_task_by_vpid(pid_t nr);
extern int wake_up_state(struct task_struct *tsk, unsigned int state);
extern int wake_up_process(struct task_struct *tsk);
+extern int wake_up_task_interruptible(struct task_struct *tsk);
extern void wake_up_new_task(struct task_struct *tsk);
#ifdef CONFIG_SMP
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index cafbe03eed01..56a15f35e7b3 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -364,7 +364,7 @@ static inline void clear_notify_signal(void)
static inline bool __set_notify_signal(struct task_struct *task)
{
return !test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) &&
- !wake_up_state(task, TASK_INTERRUPTIBLE);
+ !wake_up_task_interruptible(task);
}
/*