From: Guan-Yu Lin <guanyulin@google.com>
To: gregkh@linuxfoundation.org, mathias.nyman@intel.com,
perex@perex.cz, tiwai@suse.com, quic_wcheng@quicinc.com,
broonie@kernel.org, arnd@arndb.de,
christophe.jaillet@wanadoo.fr, xiaopei01@kylinos.cn,
wesley.cheng@oss.qualcomm.com
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-sound@vger.kernel.org, Guan-Yu Lin <guanyulin@google.com>,
stable@vger.kernel.org, Hailong Liu <hailong.liu@oppo.com>
Subject: [PATCH v2 1/2] usb: offload: move device locking to callers in offload.c
Date: Mon, 9 Mar 2026 02:22:04 +0000 [thread overview]
Message-ID: <20260309022205.28136-2-guanyulin@google.com> (raw)
In-Reply-To: <20260309022205.28136-1-guanyulin@google.com>
Update usb_offload_get() and usb_offload_put() to require that the
caller holds the USB device lock. Remove the internal call to
usb_lock_device() and add device_lock_assert() to ensure synchronization
is handled by the caller. These functions continue to manage the
device's power state via autoresume/autosuspend and update the
offload_usage counter.
Additionally, decouple the xHCI sideband interrupter lifecycle from the
offload usage counter by removing the calls to usb_offload_get() and
usb_offload_put() from the interrupter creation and removal paths. This
allows interrupters to be managed independently of the device's offload
activity status.
Cc: stable@vger.kernel.org
Fixes: ef82a4803aab ("xhci: sideband: add api to trace sideband usage")
Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
Tested-by: Hailong Liu <hailong.liu@oppo.com>
---
drivers/usb/core/offload.c | 34 +++++++++++---------------------
drivers/usb/host/xhci-sideband.c | 14 +------------
2 files changed, 13 insertions(+), 35 deletions(-)
diff --git a/drivers/usb/core/offload.c b/drivers/usb/core/offload.c
index 7c699f1b8d2b..e13a4c21d61b 100644
--- a/drivers/usb/core/offload.c
+++ b/drivers/usb/core/offload.c
@@ -20,6 +20,7 @@
* enabled on this usb_device; that is, another entity is actively handling USB
* transfers. This information allows the USB driver to adjust its power
* management policy based on offload activity.
+ * The caller must hold @udev's device lock.
*
* Return: 0 on success. A negative error code otherwise.
*/
@@ -27,31 +28,25 @@ int usb_offload_get(struct usb_device *udev)
{
int ret;
- usb_lock_device(udev);
- if (udev->state == USB_STATE_NOTATTACHED) {
- usb_unlock_device(udev);
+ device_lock_assert(&udev->dev);
+
+ if (udev->state == USB_STATE_NOTATTACHED)
return -ENODEV;
- }
if (udev->state == USB_STATE_SUSPENDED ||
- udev->offload_at_suspend) {
- usb_unlock_device(udev);
+ udev->offload_at_suspend)
return -EBUSY;
- }
/*
* offload_usage could only be modified when the device is active, since
* it will alter the suspend flow of the device.
*/
ret = usb_autoresume_device(udev);
- if (ret < 0) {
- usb_unlock_device(udev);
+ if (ret < 0)
return ret;
- }
udev->offload_usage++;
usb_autosuspend_device(udev);
- usb_unlock_device(udev);
return ret;
}
@@ -64,6 +59,7 @@ EXPORT_SYMBOL_GPL(usb_offload_get);
* The inverse operation of usb_offload_get, which drops the offload_usage of
* a USB device. This information allows the USB driver to adjust its power
* management policy based on offload activity.
+ * The caller must hold @udev's device lock.
*
* Return: 0 on success. A negative error code otherwise.
*/
@@ -71,33 +67,27 @@ int usb_offload_put(struct usb_device *udev)
{
int ret;
- usb_lock_device(udev);
- if (udev->state == USB_STATE_NOTATTACHED) {
- usb_unlock_device(udev);
+ device_lock_assert(&udev->dev);
+
+ if (udev->state == USB_STATE_NOTATTACHED)
return -ENODEV;
- }
if (udev->state == USB_STATE_SUSPENDED ||
- udev->offload_at_suspend) {
- usb_unlock_device(udev);
+ udev->offload_at_suspend)
return -EBUSY;
- }
/*
* offload_usage could only be modified when the device is active, since
* it will alter the suspend flow of the device.
*/
ret = usb_autoresume_device(udev);
- if (ret < 0) {
- usb_unlock_device(udev);
+ if (ret < 0)
return ret;
- }
/* Drop the count when it wasn't 0, ignore the operation otherwise. */
if (udev->offload_usage)
udev->offload_usage--;
usb_autosuspend_device(udev);
- usb_unlock_device(udev);
return ret;
}
diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
index 2bd77255032b..6fc0ad658d66 100644
--- a/drivers/usb/host/xhci-sideband.c
+++ b/drivers/usb/host/xhci-sideband.c
@@ -93,8 +93,6 @@ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *e
static void
__xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
{
- struct usb_device *udev;
-
lockdep_assert_held(&sb->mutex);
if (!sb->ir)
@@ -102,10 +100,6 @@ __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
sb->ir = NULL;
- udev = sb->vdev->udev;
-
- if (udev->state != USB_STATE_NOTATTACHED)
- usb_offload_put(udev);
}
/* sideband api functions */
@@ -328,9 +322,6 @@ int
xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
bool ip_autoclear, u32 imod_interval, int intr_num)
{
- int ret = 0;
- struct usb_device *udev;
-
if (!sb || !sb->xhci)
return -ENODEV;
@@ -348,12 +339,9 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
if (!sb->ir)
return -ENOMEM;
- udev = sb->vdev->udev;
- ret = usb_offload_get(udev);
-
sb->ir->ip_autoclear = ip_autoclear;
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
--
2.53.0.473.g4a7958ca14-goog
next prev parent reply other threads:[~2026-03-09 2:22 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 2:22 [PATCH v2 0/2] usb: offload: Decouple interrupter lifecycle and refactor usage tracking Guan-Yu Lin
2026-03-09 2:22 ` Guan-Yu Lin [this message]
2026-03-11 12:26 ` [PATCH v2 1/2] usb: offload: move device locking to callers in offload.c Greg KH
2026-03-12 17:23 ` Guan-Yu Lin
2026-03-17 21:17 ` Wesley Cheng
2026-03-18 23:21 ` Guan-Yu Lin
2026-03-19 0:24 ` Wesley Cheng
2026-03-09 2:22 ` [PATCH v2 2/2] ALSA: usb: qcom: manage offload device usage Guan-Yu Lin
2026-03-11 12:31 ` Greg KH
2026-03-12 17:24 ` Guan-Yu Lin
2026-03-17 20:45 ` Guan-Yu Lin
2026-03-18 5:58 ` Greg KH
2026-03-18 23:29 ` Guan-Yu Lin
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=20260309022205.28136-2-guanyulin@google.com \
--to=guanyulin@google.com \
--cc=arnd@arndb.de \
--cc=broonie@kernel.org \
--cc=christophe.jaillet@wanadoo.fr \
--cc=gregkh@linuxfoundation.org \
--cc=hailong.liu@oppo.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=perex@perex.cz \
--cc=quic_wcheng@quicinc.com \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.com \
--cc=wesley.cheng@oss.qualcomm.com \
--cc=xiaopei01@kylinos.cn \
/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.