[PATCH v15 3/4] xhci: sideband: add api to trace sideband usage

Guan-Yu Lin posted 4 patches 2 months ago
There is a newer version of this series
[PATCH v15 3/4] xhci: sideband: add api to trace sideband usage
Posted by Guan-Yu Lin 2 months ago
The existing sideband driver only registers sidebands without tracking
their active usage. To address this, sideband will now record its active
usage when it creates/removes interrupters. In addition, a new api is
introduced to provide a means for other dirvers to fetch sideband
activity information on a USB host controller.

Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
---
 drivers/usb/host/Kconfig          | 11 +++++++++
 drivers/usb/host/xhci-sideband.c  | 38 +++++++++++++++++++++++++++++++
 include/linux/usb/xhci-sideband.h |  9 ++++++++
 3 files changed, 58 insertions(+)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 109100cc77a3..49b9cdc11298 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -113,6 +113,17 @@ config USB_XHCI_SIDEBAND
 	  xHCI USB endpoints directly, allowing CPU to sleep while playing
 	  audio.
 
+config USB_XHCI_SIDEBAND_SUSPEND
+	  bool "xHCI support for sideband during system suspend"
+	  depends on USB_XHCI_SIDEBAND
+	  depends on USB_XHCI_PLATFORM
+	  depends on SUSPEND
+	  help
+	    Say 'Y' to enable the support for the xHCI sideband capability
+	    after system suspended. In addition to USB_XHCI_SIDEBAND, this
+	    config allows endpoints and interrupters associated with the
+	    sideband function when system is suspended.
+
 config USB_XHCI_TEGRA
 	tristate "xHCI support for NVIDIA Tegra SoCs"
 	depends on PHY_TEGRA_XUSB
diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
index d49f9886dd84..15d72c23c0e0 100644
--- a/drivers/usb/host/xhci-sideband.c
+++ b/drivers/usb/host/xhci-sideband.c
@@ -266,6 +266,33 @@ xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
 
+#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND)
+/**
+ * xhci_sideband_check - check the existence of active sidebands
+ * @hcd: the host controller driver associated with the target host controller
+ *
+ * Allow other drivers, such as usb controller driver, to check if there are
+ * any sideband activity on the host controller. This information could be used
+ * for power management or other forms of resource management. The caller should
+ * ensure downstream usb devices are all either suspended or marked as
+ * "offload_at_suspend" to ensure the correctness of the return value.
+ *
+ * Returns true on any active sideband existence, false otherwise.
+ */
+bool xhci_sideband_check(struct usb_hcd *hcd)
+{
+	struct usb_device *udev = hcd->self.root_hub;
+	bool active;
+
+	usb_lock_device(udev);
+	active = usb_offload_check(udev);
+	usb_unlock_device(udev);
+
+	return active;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_check);
+#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */
+
 /**
  * xhci_sideband_create_interrupter - creates a new interrupter for this sideband
  * @sb: sideband instance for this usb device
@@ -286,6 +313,7 @@ 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;
@@ -304,6 +332,9 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
 		goto out;
 	}
 
+	udev = sb->vdev->udev;
+	ret = usb_offload_get(udev);
+
 	sb->ir->ip_autoclear = ip_autoclear;
 
 out:
@@ -323,6 +354,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
 void
 xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
 {
+	struct usb_device *udev;
+
 	if (!sb || !sb->ir)
 		return;
 
@@ -330,6 +363,11 @@ 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);
+
 	mutex_unlock(&sb->mutex);
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sideband.h
index 45288c392f6e..5174cc5afc98 100644
--- a/include/linux/usb/xhci-sideband.h
+++ b/include/linux/usb/xhci-sideband.h
@@ -11,6 +11,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #define	EP_CTX_PER_DEV		31	/* FIXME defined twice, from xhci.h */
 
@@ -83,6 +84,14 @@ xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
 				  struct usb_host_endpoint *host_ep);
 struct sg_table *
 xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
+
+#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND)
+bool xhci_sideband_check(struct usb_hcd *hcd);
+#else
+static inline bool xhci_sideband_check(struct usb_hcd *hcd)
+{ return false; }
+#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */
+
 int
 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
 				 bool ip_autoclear, u32 imod_interval, int intr_num);
-- 
2.50.1.565.gc32cd1483b-goog
Re: [PATCH v15 3/4] xhci: sideband: add api to trace sideband usage
Posted by Greg KH 1 month, 3 weeks ago
On Fri, Aug 01, 2025 at 03:39:32AM +0000, Guan-Yu Lin wrote:
> The existing sideband driver only registers sidebands without tracking
> their active usage. To address this, sideband will now record its active
> usage when it creates/removes interrupters. In addition, a new api is
> introduced to provide a means for other dirvers to fetch sideband
> activity information on a USB host controller.
> 
> Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
> ---
>  drivers/usb/host/Kconfig          | 11 +++++++++
>  drivers/usb/host/xhci-sideband.c  | 38 +++++++++++++++++++++++++++++++
>  include/linux/usb/xhci-sideband.h |  9 ++++++++
>  3 files changed, 58 insertions(+)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 109100cc77a3..49b9cdc11298 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -113,6 +113,17 @@ config USB_XHCI_SIDEBAND
>  	  xHCI USB endpoints directly, allowing CPU to sleep while playing
>  	  audio.
>  
> +config USB_XHCI_SIDEBAND_SUSPEND
> +	  bool "xHCI support for sideband during system suspend"
> +	  depends on USB_XHCI_SIDEBAND
> +	  depends on USB_XHCI_PLATFORM
> +	  depends on SUSPEND
> +	  help
> +	    Say 'Y' to enable the support for the xHCI sideband capability
> +	    after system suspended. In addition to USB_XHCI_SIDEBAND, this
> +	    config allows endpoints and interrupters associated with the
> +	    sideband function when system is suspended.

Again, why is a new config option needed here?  Why can't we just use
the existing one?  Why would you ever want one and not the other?


> +
>  config USB_XHCI_TEGRA
>  	tristate "xHCI support for NVIDIA Tegra SoCs"
>  	depends on PHY_TEGRA_XUSB
> diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
> index d49f9886dd84..15d72c23c0e0 100644
> --- a/drivers/usb/host/xhci-sideband.c
> +++ b/drivers/usb/host/xhci-sideband.c
> @@ -266,6 +266,33 @@ xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
>  }
>  EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
>  
> +#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND)
> +/**
> + * xhci_sideband_check - check the existence of active sidebands
> + * @hcd: the host controller driver associated with the target host controller
> + *
> + * Allow other drivers, such as usb controller driver, to check if there are
> + * any sideband activity on the host controller. This information could be used
> + * for power management or other forms of resource management. The caller should
> + * ensure downstream usb devices are all either suspended or marked as
> + * "offload_at_suspend" to ensure the correctness of the return value.
> + *
> + * Returns true on any active sideband existence, false otherwise.
> + */
> +bool xhci_sideband_check(struct usb_hcd *hcd)
> +{
> +	struct usb_device *udev = hcd->self.root_hub;
> +	bool active;
> +
> +	usb_lock_device(udev);
> +	active = usb_offload_check(udev);
> +	usb_unlock_device(udev);
> +
> +	return active;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_check);
> +#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */

#ifdef in .c files is generally not a good idea, is it really needed
here?  Maybe it is, it's hard to unwind...

thanks,

greg k-h
Re: [PATCH v15 3/4] xhci: sideband: add api to trace sideband usage
Posted by Guan-Yu Lin 1 month, 1 week ago
On Wed, Aug 13, 2025 at 10:51 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Fri, Aug 01, 2025 at 03:39:32AM +0000, Guan-Yu Lin wrote:
> > +config USB_XHCI_SIDEBAND_SUSPEND
>
> Again, why is a new config option needed here?  Why can't we just use
> the existing one?  Why would you ever want one and not the other?
>
USB_XHCI_SIDEBAND focuses on the normal use case where the system is
active, while USB_XHCI_SIDEBAND_SUSPEND enables the sideband during
system sleep (Suspend-to-RAM). The design allows the user to determine
the degree of support for the sideband in the system. We could add the
"select" keyword to automatically enable USB_XHCI_SIDEBAND once
USB_XHCI_SIDEBAND_SUSPEND is enabled.
>
> > +EXPORT_SYMBOL_GPL(xhci_sideband_check);
> > +#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */
>
> #ifdef in .c files is generally not a good idea, is it really needed
> here?  Maybe it is, it's hard to unwind...
>
> thanks,
>
> greg k-h

Given that CONFIG_USB_XHCI_SIDEBAND_SUSPEND depends on
CONFIG_USB_XHCI_SIDEBAND and adds only a single function, I think it
is preferable to place the new code in the same file. This approach
prevents unnecessary code fragmentation and improves maintainability
by keeping related functions together.

Regards,
Guan-Yu
Re: [PATCH v15 3/4] xhci: sideband: add api to trace sideband usage
Posted by Greg KH 4 weeks, 1 day ago
On Tue, Aug 26, 2025 at 12:37:00PM +0800, Guan-Yu Lin wrote:
> On Wed, Aug 13, 2025 at 10:51 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Fri, Aug 01, 2025 at 03:39:32AM +0000, Guan-Yu Lin wrote:
> > > +config USB_XHCI_SIDEBAND_SUSPEND
> >
> > Again, why is a new config option needed here?  Why can't we just use
> > the existing one?  Why would you ever want one and not the other?
> >
> USB_XHCI_SIDEBAND focuses on the normal use case where the system is
> active, while USB_XHCI_SIDEBAND_SUSPEND enables the sideband during
> system sleep (Suspend-to-RAM). The design allows the user to determine
> the degree of support for the sideband in the system. We could add the
> "select" keyword to automatically enable USB_XHCI_SIDEBAND once
> USB_XHCI_SIDEBAND_SUSPEND is enabled.

But why would you want only one of these options and not both?  The
whole goal of this feature is for power savings, which means that
suspend is needed by everyone.  Don't increase the config variable
combinations for no good reason.

> > > +EXPORT_SYMBOL_GPL(xhci_sideband_check);
> > > +#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */
> >
> > #ifdef in .c files is generally not a good idea, is it really needed
> > here?  Maybe it is, it's hard to unwind...
> >
> > thanks,
> >
> > greg k-h
> 
> Given that CONFIG_USB_XHCI_SIDEBAND_SUSPEND depends on
> CONFIG_USB_XHCI_SIDEBAND and adds only a single function, I think it
> is preferable to place the new code in the same file. This approach
> prevents unnecessary code fragmentation and improves maintainability
> by keeping related functions together.

We put #ifdefs in .h files.  That's a long-time-rule for decades to
ensure that we can maintain this codebase for even more decades to come.
Please do not break that rule just to keep things close if it's not
required.

thanks,

greg k-h
Re: [PATCH v15 3/4] xhci: sideband: add api to trace sideband usage
Posted by Guan-Yu Lin 3 weeks, 3 days ago
On Sat, Sep 6, 2025 at 9:11 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Tue, Aug 26, 2025 at 12:37:00PM +0800, Guan-Yu Lin wrote:
> > On Wed, Aug 13, 2025 at 10:51 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> > >
> > > On Fri, Aug 01, 2025 at 03:39:32AM +0000, Guan-Yu Lin wrote:
> > > > +config USB_XHCI_SIDEBAND_SUSPEND
> > >
> > > Again, why is a new config option needed here?  Why can't we just use
> > > the existing one?  Why would you ever want one and not the other?
> > >
> > USB_XHCI_SIDEBAND focuses on the normal use case where the system is
> > active, while USB_XHCI_SIDEBAND_SUSPEND enables the sideband during
> > system sleep (Suspend-to-RAM). The design allows the user to determine
> > the degree of support for the sideband in the system. We could add the
> > "select" keyword to automatically enable USB_XHCI_SIDEBAND once
> > USB_XHCI_SIDEBAND_SUSPEND is enabled.
>
> But why would you want only one of these options and not both?  The
> whole goal of this feature is for power savings, which means that
> suspend is needed by everyone.  Don't increase the config variable
> combinations for no good reason.
>

Thanks for the suggestions. I'll remove USB_XHCI_SIDEBAND_SUSPEND in
the next version.

> > > > +EXPORT_SYMBOL_GPL(xhci_sideband_check);
> > > > +#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND_SUSPEND) */
> > >
> > > #ifdef in .c files is generally not a good idea, is it really needed
> > > here?  Maybe it is, it's hard to unwind...
> > >
> > > thanks,
> > >
> > > greg k-h
> >
> > Given that CONFIG_USB_XHCI_SIDEBAND_SUSPEND depends on
> > CONFIG_USB_XHCI_SIDEBAND and adds only a single function, I think it
> > is preferable to place the new code in the same file. This approach
> > prevents unnecessary code fragmentation and improves maintainability
> > by keeping related functions together.
>
> We put #ifdefs in .h files.  That's a long-time-rule for decades to
> ensure that we can maintain this codebase for even more decades to come.
> Please do not break that rule just to keep things close if it's not
> required.
>
> thanks,
>
> greg k-h

Thanks for the suggestions. This concern would be addressed once we
use only CONFIG_USB_XHCI_SIDEBAND to control all features.

Regards,
Guan-Yu