public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Guan-Yu Lin <guanyulin@google.com>, Greg KH <gregkh@linuxfoundation.org>
Cc: mathias.nyman@intel.com, stern@rowland.harvard.edu,
	wesley.cheng@oss.qualcomm.com, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [RFC PATCH] usb: host: xhci-sideband: fix deadlock in unregister path
Date: Tue, 3 Feb 2026 16:14:00 +0200	[thread overview]
Message-ID: <6acaaae2-4e93-46f5-8170-277bc369f922@linux.intel.com> (raw)
In-Reply-To: <CAOuDEK0o2jqqOUZVUdi9JDcyXRQHEuL9GCBrU0VQhWAfDtJnUg@mail.gmail.com>

On 2/2/26 12:03, Guan-Yu Lin wrote:
> On Sat, Jan 31, 2026 at 8:15 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>>
>> On Fri, Jan 30, 2026 at 07:47:46AM +0000, Guan-Yu Lin wrote:
>>> When a USB device is disconnected or a driver is unbound, the USB core
>>> invokes the driver's disconnect callback while holding the udev device
>>> lock. If the driver calls xhci_sideband_unregister(), it eventually
>>> reaches usb_offload_put(), which attempts to acquire the same udev
>>> lock, resulting in a self-deadlock.
>>>
>>> Introduce lockless variants __usb_offload_get() and __usb_offload_put()
>>> to allow modifying the offload usage count when the device lock is
>>> already held. These helpers use device_lock_assert() to ensure callers
>>> meet the locking requirements.
>>
>> Ugh.  Didn't I warn about this when the original functions were added?
>>
>> Adding functions with __ is a mess, please make these names, if you
>> _REALLY_ need them, obvious that this is a no lock function.
>>
>> And now that you added the lockless functions, are there any in-kernel
>> users of the locked versions?  At a quick glance I didn't see them, did
>> I miss it somewhere?
>>
>> thanks,
>>
>> greg k-h
> 
> Hi Greg,
> 
> You are right; xhci-sideband.c is the only in-kernel user of the
> locked versions. I will rename the __ functions to usb_offload_* and
> remove the locked variants in the next version to clean up the API.
> 
> Regarding the deadlock fix itself, we have analyzed two potential
> solutions. The core issue is that xhci_sideband_unregister() (and
> xhci_sideband_remove_interrupter()) needs to decrement the offload
> usage count (which requires the USB device lock), but it is called
> from the disconnect path where that lock is already held.
> 
> Option A: Fix the Callers of xhci_sideband functions
> In this approach, we keep the usb_offload calls inside the
> xhci_sideband functions but replace the internal usb_lock_device()
> with device_lock_assert(). We then update callers in
> qc_audio_offload.c to explicitly acquire the lock.
> This ensures the offload count remains tightly coupled with the
> interrupter's lifecycle, though it effectively changes the API
> contract: calling xHCI sideband functions now requires holding the USB
> device lock.
> 
> Option B: Decouple usb_offload functions from xhci_sideband functions
> In this approach, we strip the usb_offload calls out of xhci_sideband
> functions entirely. The client driver (qc_audio_offload) becomes
> responsible for the full transaction: acquiring the lock, managing
> usb_offload_get/put(), and creating/removing the interrupter. This
> restores clean encapsulation (xHCI functions only handle hardware),
> but it places the burden on the client driver to correctly balance the
> usb_offload calls.
> 
> I lean towards Option A to ensure the offload count implies an active
> interrupter by design, but please let me know if you prefer the
> cleaner separation of Option B.

I would prefer option B
Decouple the offload from sideband.

The secondary interrupter in sideband was specifically createad for
qc_audio_offload.

Vendors using the xHCI hardware Audio sideband Capability (xHCI 7.9)
won't use a secondary interrupter, but might sill want to prevent suspending
the device. So it shuold be better to make this decision in the class driver.

The offload count shoudn't be that complicated. Isn't it binary at the moment?
We don't allow more than one sideband per device, and it can only have one
interrupter.

I unfortunately couldn't participate in the review and development of
drivers/usb/core/offload.c, but my original idea before it was implemented
was to keep usb core out of sideband as much as possible as its not really
a part of usb specification.

This is also why I added the sideband pointer to struct xhci_virt_device.
It allows us to figure out if a device is dedicated for sideband use.

so xhci_sideband_check() could be something like

bool xhci_sideband_check(struct xhci_hcd *xhci)
{
	guard(spinlock_irqsave)(&xhci->lock);

	for (int i = 1; i < HC_MAX_SLOTS; i++) {
	if (xhci->devs[i] && xhci->devs[i]->sideband)
		return true;
	}
	return false;
}

Thanks
Mathias

  reply	other threads:[~2026-02-03 14:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-30  7:47 [RFC PATCH] usb: host: xhci-sideband: fix deadlock in unregister path Guan-Yu Lin
2026-01-31 12:15 ` Greg KH
2026-02-02 10:03   ` Guan-Yu Lin
2026-02-03 14:14     ` Mathias Nyman [this message]
2026-02-04  9:15       ` Guan-Yu Lin
2026-02-04  9:53         ` Mathias Nyman

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=6acaaae2-4e93-46f5-8170-277bc369f922@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=guanyulin@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=wesley.cheng@oss.qualcomm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox