From: Frederic Weisbecker <frederic@kernel.org>
To: Waiman Long <longman@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mathias Nyman <mathias.nyman@linux.intel.com>,
Alan Stern <stern@rowland.harvard.edu>,
Kuen-Han Tsai <khtsai@google.com>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
Vratislav Bendel <vbendel@redhat.com>
Subject: Re: [PATCH] usb: hub: Make usb_hub_wq type depend on isolcpus/nohz_full setting
Date: Wed, 27 May 2026 16:21:33 +0200 [thread overview]
Message-ID: <ahb97cx_4dqPayDW@localhost.localdomain> (raw)
In-Reply-To: <20260521170659.984284-1-longman@redhat.com>
Le Thu, May 21, 2026 at 01:06:59PM -0400, Waiman Long a écrit :
> A Red Hat customer reports a kernel stability problem where hung tasks
> are reported with occasional kernel panics. Analysis of the core dump
> indicates that USB work items are running on isolcpus+nohz_full cores
> competing with RT-class tasks running on those core while holding
> usb_hub device mutex transitively blocking other kworkers waiting for
> the same mutex leading to hung_task reports.
>
> As the usb_hub_wq uses the WQ_PERCPU flag, it will run the work items on
> the same CPU that queues them. For many use cases, it is a more efficient
> setup leading to higher throughput as it reduces cacheline bouncing.
>
> It is a different story if the system needs to run latency sensitive RT
> workload on dedicated isolated CPUs. Having the kworkers processing work
> items on the same set of isolated CPUs will likely break the low latency
> requirements of the RT tasks. As the RT tasks have higher priority,
> not much CPU time will be left running the kworkers to process work
> items which, in turn, will block other tasks that have dependency on
> the completion of those work items. In this case, using a WQ_UNBOUND
> workqueue to avoid running on isolated CPUs will be more beneficial.
>
> One solution to get the best of both worlds is to make the workqueue
> type depending on whether the "isolcpus" or "nohz_full" boot command
> line options have been specified. If at least one of those options are
> present, usb_hub_wq will be created as an unbound workqueue. Otherwise,
> it will remain as a percpu workqueue.
>
> Signed-off-by: Waiman Long <longman@redhat.com>
> ---
> drivers/usb/core/hub.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 24960ba9caa9..f79e5edd627a 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -33,6 +33,7 @@
> #include <linux/random.h>
> #include <linux/pm_qos.h>
> #include <linux/kobject.h>
> +#include <linux/sched/isolation.h>
>
> #include <linux/bitfield.h>
> #include <linux/uaccess.h>
> @@ -6066,6 +6067,8 @@ static struct usb_driver hub_driver = {
>
> int usb_hub_init(void)
> {
> + unsigned int wq_flags;
> +
> if (usb_register(&hub_driver) < 0) {
> printk(KERN_ERR "%s: can't register hub driver\n",
> usbcore_name);
> @@ -6077,8 +6080,17 @@ int usb_hub_init(void)
> * USB-PERSIST port handover. Otherwise it might see that a full-speed
> * device was gone before the EHCI controller had handed its port
> * over to the companion full-speed controller.
> + *
> + * Create WQ_UNBOUND workqueue instead of WQ_PERCPU if either isolcpus
> + * or nohz_full boot option is specified.
> */
> - hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE | WQ_PERCPU, 0);
> + if (housekeeping_enabled(HK_TYPE_DOMAIN) ||
> + housekeeping_enabled(HK_TYPE_KERNEL_NOISE))
HK_TYPE_DOMAIN is supposed to be a subset of HK_TYPE_KERNEL_NOISE anyway so
the first should be enough.
> + wq_flags = WQ_UNBOUND;
> + else
> + wq_flags = WQ_PERCPU;
> +
> + hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE | wq_flags, 0);
But then what happens if no isolcpus= is passed but later cpuset creates
an isolated partition?
Tejun and Marco thought about introducing a WQ_PREFER_PERCPU flag that would
do what you want above. And the workqueue code should also handle dynamic
isolation, that is switch from per-cpu workqueues to unbound ones or vice-versa
dynamically.
Marco is working on it.
Thanks.
> if (hub_wq)
> return 0;
>
> --
> 2.54.0
>
>
--
Frederic Weisbecker
SUSE Labs
next prev parent reply other threads:[~2026-05-27 14:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-21 17:06 [PATCH] usb: hub: Make usb_hub_wq type depend on isolcpus/nohz_full setting Waiman Long
2026-05-27 14:21 ` Frederic Weisbecker [this message]
2026-06-05 18:05 ` Waiman Long
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=ahb97cx_4dqPayDW@localhost.localdomain \
--to=frederic@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=khtsai@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mathias.nyman@linux.intel.com \
--cc=stern@rowland.harvard.edu \
--cc=vbendel@redhat.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 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.