On 06/29, Andy Lutomirski wrote: > > I pushed that change to my tree (seems to work well enough to boot > without warnings as long as I don't unmount XFS, but not particularly > well tested). Want to refresh your patch on top?
Please see the trivial fix below. Compile tested, but looks obvious. Btw, why free_thread_stack() calls vfree() with irqs disabled? Doesn't look good and perhaps even wrong; at least vmap_debug_free_range() does flush_tlb_kernel_range() and smp_call_function() can deadlock? ------------------------------------------------------------------------------- Subject: [PATCH] kthread: to_live_kthread() needs try_get_task_stack() get_task_struct(tsk) no longer pins tsk->stack so all users of to_live_kthread() should do try_get_task_stack/put_task_stack to protect "struct kthread" which lives on kthread's stack. TODO: Kill to_live_kthread(), perhaps we can even kill "struct kthread" too, and rework kthread_stop(), it can use task_work_add() to sync with the exiting kernel thread. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/kthread.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 9ff173d..4ab4c37 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -64,7 +64,7 @@ static inline struct kthread *to_kthread(struct task_struct *k) static struct kthread *to_live_kthread(struct task_struct *k) { struct completion *vfork = ACCESS_ONCE(k->vfork_done); - if (likely(vfork)) + if (likely(vfork) && try_get_task_stack(k)) return __to_kthread(vfork); return NULL; } @@ -425,8 +425,10 @@ void kthread_unpark(struct task_struct *k) { struct kthread *kthread = to_live_kthread(k); - if (kthread) + if (kthread) { __kthread_unpark(k, kthread); + put_task_stack(k); + } } EXPORT_SYMBOL_GPL(kthread_unpark); @@ -455,6 +457,7 @@ int kthread_park(struct task_struct *k) wait_for_completion(&kthread->parked); } } + put_task_stack(k); ret = 0; } return ret; @@ -490,6 +493,7 @@ int kthread_stop(struct task_struct *k) __kthread_unpark(k, kthread); wake_up_process(k); wait_for_completion(&kthread->exited); + put_task_stack(k); } ret = k->exit_code; put_task_struct(k); -- 2.5.0