Re: [PATCH] block: fix a crash in do_task_dead()

From: Oleg Nesterov
Date: Mon Jun 10 2019 - 10:51:27 EST


On 06/10, Gaurav Kohli wrote:
>
> >@@ -1991,6 +1991,28 @@ try_to_wake_up(struct task_struct *p, un
> > unsigned long flags;
> > int cpu, success = 0;
> >+ if (p == current) {
> >+ /*
> >+ * We're waking current, this means 'p->on_rq' and 'task_cpu(p)
> >+ * == smp_processor_id()'. Together this means we can special
> >+ * case the whole 'p->on_rq && ttwu_remote()' case below
> >+ * without taking any locks.
> >+ *
> >+ * In particular:
> >+ * - we rely on Program-Order guarantees for all the ordering,
> >+ * - we're serialized against set_special_state() by virtue of
> >+ * it disabling IRQs (this allows not taking ->pi_lock).
> >+ */
> >+ if (!(p->state & state))
> >+ return false;
> >+
>
> Hi Peter, Jen,
>
> As we are not taking pi_lock here , is there possibility of same task dead
> call comes as this point of time for current thread, bcoz of which we have
> seen earlier issue after this commit 0619317ff8ba
> [T114538] do_task_dead+0xf0/0xf8
> [T114538] do_exit+0xd5c/0x10fc
> [T114538] do_group_exit+0xf4/0x110
> [T114538] get_signal+0x280/0xdd8
> [T114538] do_notify_resume+0x720/0x968
> [T114538] work_pending+0x8/0x10
>
> Is there a chance of TASK_DEAD set at this point of time?

In this case try_to_wake_up(current, TASK_NORMAL) will do nothing, see the
if (!(p->state & state)) above.

See also the comment about set_special_state() above. It disables irqs and
this is enough to ensure that try_to_wake_up(current) from irq can't race
with set_special_state(TASK_DEAD).

Oleg.