Re: [PATCH] mmc: vub300: never tear the host down from the inactivity timer

From: Yogesh Gaur

Date: Wed Sep 09 2026 - 05:27:16 EST


On Wed, Sep 9, 2026 at 12:23 PM Johan Hovold <johan@xxxxxxxxxx> wrote:
>
> On Tue, Sep 08, 2026 at 10:20:50PM +0530, Yogesh Gaur wrote:
> > vub300_probe() takes a second kref reference on behalf of the inactivity
> > timer and arms it:
> >
> > kref_init(&vub300->kref);
> > ...
> > kref_get(&vub300->kref);
> > timer_setup(&vub300->inactivity_timer,
> > vub300_inactivity_timer_expired, 0);
> > vub300->inactivity_timer.expires = jiffies + HZ;
> > add_timer(&vub300->inactivity_timer);
> >
> > and expects the timer to release that reference from its own expiry
> > function, once it observes that vub300->interface has been cleared:
> >
> > if (!vub300->interface) {
> > kref_put(&vub300->kref, vub300_delete);
> > } else if (vub300->cmd) {
> >
> > That is wrong in both directions, because the expiry function runs in
> > softirq context.
> >
> > If the timer happens to hold the last reference, the kref_put() runs
> > vub300_delete() -> mmc_free_host() -> cancel_delayed_work_sync(), which
> > sleeps. The ->probe() error path arranges exactly that: it clears
> > ->interface and drops only its own reference, leaving the timer armed
> > and owning the last one.
> >
> > BUG: sleeping function called from invalid context at kernel/workqueue.c:4487
> > in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 191, name: kworker/0:2
> > Call Trace:
> > <IRQ>
> > __might_resched.cold+0x1ec/0x232 kernel/sched/core.c:9197
> > __cancel_work_sync kernel/workqueue.c:4487 [inline]
> > cancel_delayed_work_sync+0xb8/0xf0 kernel/workqueue.c:4568
> > mmc_free_host+0x19/0x30 drivers/mmc/core/host.c:700
> > vub300_delete drivers/mmc/host/vub300.c:379 [inline]
> > kref_put include/linux/kref.h:65 [inline]
> > vub300_inactivity_timer_expired drivers/mmc/host/vub300.c:747
> > call_timer_fn+0x11f/0x610 kernel/time/timer.c:1745
> > </IRQ>
>
> > Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver")
> > Reported-by: syzbot+f4a0159ce6802a0a4774@xxxxxxxxxxxxxxxxxxxxxxxxx
> > Closes: https://syzkaller.appspot.com/bug?extid=f4a0159ce6802a0a4774
> > Reported-by: syzbot+1ee4f3b9228e35f14677@xxxxxxxxxxxxxxxxxxxxxxxxx
> > Closes: https://syzkaller.appspot.com/bug?extid=1ee4f3b9228e35f14677
> > Signed-off-by: Yogesh Gaur <yogeshgaur.83@xxxxxxxxx>
>
> You forgot to add an Assisted-by tag.
>
> Several people have already proposed (LLM generated) fixes for this.
> Please search the lists.
>
Thanks.

v2 adds the Assisted-by tag.

On the lists: the closest prior posting is syzbot's own AI RFC [1],
which fixes the sleeping report by deferring vub300_delete() to the
dead work queue.
v2 cites it and takes diff approach, because that one leaves the timer
inside the reference counting and so does not close the second report
(f4a0159c) - the mod_timer() calls in the command and
dead work threads can still rearm the timer. Shutting the timer down
closes both.

[1] https://lore.kernel.org/all/49982079-95f4-4e8c-bbbc-bcb127e2f378@xxxxxxxxxxxxxxx

Yogesh

>
> Johan