All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Elvira Khabirova" <lineprinter0@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH v3 2/2] usb: musb: gadget: don't flush a waiting RX packet when queueing a request
Date: Sat, 07 Nov 2026 18:11:07 +0000	[thread overview]
Message-ID: <sashiko-outbox-203154@kernel.org> (raw)
In-Reply-To: <20261107173601.63095-3-lineprinter0@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] usb: musb: gadget: premature and unlocked rx_kick queueing in
  musb_resume()
--

commit c9ae36b9b6933c41b159c85ef258637f80341755
Author: Elvira Khabirova <lineprinter0@gmail.com>

usb: musb: gadget: don't flush a waiting RX packet when queueing a request

This commit replaces the RX FIFO flush in musb_ep_restart() with a
system_bh_wq work item (rx_kick) to process waiting RX packets when a
request is queued or after an in-progress giveback finishes.

> diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> index 73ac25f53698f..38469727acc6f 100644
> --- a/drivers/usb/musb/musb_core.c
> +++ b/drivers/usb/musb/musb_core.c
[ ... ]
> @@ -2866,6 +2868,7 @@ static int musb_resume(struct device *dev)
>  	if ((devctl & mask) != (musb->context.devctl & mask))
>  		musb->port1_status = 0;
>  
> +	musb_gadget_enable_rx_kicks(musb);
>  	musb_enable_interrupts(musb);
>  	musb_platform_enable(musb);
>  
> diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
> index b500e0d8b0bd3..08bb605aa0b31 100644
> --- a/drivers/usb/musb/musb_gadget.c
> +++ b/drivers/usb/musb/musb_gadget.c
[ ... ]
> +static void musb_g_enable_rx_kick(struct musb *musb, struct musb_ep *musb_ep)
> +{
> +	if (!musb_ep->rx_kick.func)
> +		return;
> +
> +	enable_work(&musb_ep->rx_kick);
> +	if (musb_ep->desc && !musb_ep->is_in) {
> +		pm_runtime_get_noresume(musb->controller);
> +		if (!queue_work(system_bh_wq, &musb_ep->rx_kick))
> +			pm_runtime_put_noidle(musb->controller);
> +	}
> +}
> +
> +void musb_gadget_enable_rx_kicks(struct musb *musb)
> +{
> +	int i;
> +
> +	for (i = 0; i < musb->nr_endpoints; i++) {
> +		musb_g_enable_rx_kick(musb, &musb->endpoints[i].ep_in);
> +		musb_g_enable_rx_kick(musb, &musb->endpoints[i].ep_out);
> +	}
> +}

[Severity: Medium]
Can calling musb_gadget_enable_rx_kicks() unlocked before
musb_enable_interrupts() and musb_platform_enable() in musb_resume()
wedge an OUT endpoint or race on endpoint and interrupt state?

During system suspend, musb_suspend() calls pm_runtime_get_sync() (leaving
musb->is_runtime_suspended at 0) and musb_disable_interrupts(), which
zeros musb->intrtxe, musb->intrrxe, MUSB_INTRTXE, and MUSB_INTRRXE.  On
resume, musb_restore_context() writes those zeroed masks back to hardware
before musb_gadget_enable_rx_kicks() queues rx_kick on system_bh_wq:

CPU0                                  CPU1 (system_bh_wq)
musb_resume()
  musb_restore_context()
    /* MUSB_INTRRXE is 0 */
  musb_gadget_enable_rx_kicks()
    queue_work(..., &musb_ep->rx_kick)
                                      musb_g_rx_kick()
                                        musb_g_rx()
                                          rxstate()
                                            /* clears RXPKTRDY */
                                      /* next host packet arrives while
                                       * MUSB_INTRRXE == 0 or platform
                                       * interrupts are still disabled
                                       * <-- IRQ lost, endpoint wedged */
  musb_enable_interrupts()
  musb_platform_enable()

In addition, musb_g_enable_rx_kick() inspects musb_ep->desc and
musb_ep->is_in without holding musb->lock, and if musb_g_rx_kick()
completes a request via musb_g_giveback() before musb_enable_interrupts()
runs, the gadget completion callback (or a thread it wakes) can call
usb_ep_enable() or usb_ep_disable() and modify musb->intrrxe,
musb->intrtxe, and musb_ep->desc concurrently with the unlocked loop in
musb_gadget_enable_rx_kicks() and musb_enable_interrupts().

Calling musb_gadget_enable_rx_kicks() under musb->lock (or splitting
enable_work() from queuing rx_kick under musb->lock) after
musb_enable_interrupts() and musb_platform_enable() would avoid this.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261107173601.63095-1-lineprinter0@gmail.com?part=2

  reply	other threads:[~2026-11-07 18:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 17:35 [PATCH v3 0/2] usb: musb: gadget: don't flush a waiting RX packet Elvira Khabirova
2026-11-07 17:36 ` [PATCH v3 1/2] usb: musb: gadget: count givebacks in busy Elvira Khabirova
2026-11-07 17:54   ` sashiko-bot
2026-11-07 17:36 ` [PATCH v3 2/2] usb: musb: gadget: don't flush a waiting RX packet when queueing a request Elvira Khabirova
2026-11-07 18:11   ` sashiko-bot [this message]
2026-11-07 18:23     ` Elvira Khabirova

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-203154@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=lineprinter0@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.