On 3 November 2026 10:54:40 GMT, Aamir Ahmed <[email protected]> wrote: >Since commit e1fad12dcb66 ("sched/fair: Switch to task based throttle >model"), a throttled task is only dequeued when TWA_RESUME task_work >runs on its way back to user mode. > >vhost workers never return to user mode, and vhost_task_fn() only runs >task_work via get_signal() when a signal is pending. A busy vhost worker >therefore ignores its cgroup's cpu.max, while its runtime is still >charged to the group, throttling the group's other tasks (typically the >VM's vCPUs) harder. > >This also fixes memory.high and block cgroup throttling for vhost >workers, which are handled in resume_user_mode_work() as well. > >Run pending notify-resume work at the top of the worker loop, as io-wq >does in io_run_task_work(). Commit 12013e3d4695 ("KVM: powerpc: Use >generic xfer to guest work function") fixed the same problem for KVM. > >Fixes: e1fad12dcb66 ("sched/fair: Switch to task based throttle model") >Cc: [email protected] # 6.18+ >Reviewed-by: Shakeel Butt <[email protected]> >Tested-by: Shakeel Butt <[email protected]>
Reviewed-by: Bradley Morgan <[email protected]> >Assisted-by: LLM >Signed-off-by: Aamir Ahmed <[email protected]> >--- >v2: >- Also describe the memory.high and block cgroup throttling fixes > (Shakeel) >- Add Shakeel's Reviewed-by and Tested-by >- Update the code comment to match >- v1: >https://lore.kernel.org/as8p251mb00012469e6ecbea2b7d87bb0c8...@as8p251mb0001.eurp251.prod.outlook.com > >Tested on x86_64 with a vhost_task-based reproducer: in a 0.2-CPU cgroup >a busy worker drops from 100% to 19% of a CPU. Reproducer available on >request. > > kernel/vhost_task.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c >index 3717885a599..f63ac005214 100644 >--- a/kernel/vhost_task.c >+++ b/kernel/vhost_task.c >@@ -6,6 +6,7 @@ > #include <linux/completion.h> > #include <linux/sched/task.h> > #include <linux/sched/vhost_task.h> >+#include <linux/resume_user_mode.h> > #include <linux/sched/signal.h> > > enum vhost_task_flags { >@@ -31,6 +32,14 @@ static int vhost_task_fn(void *data) > for (;;) { > bool did_work; > >+ /* >+ * We never return to user mode, so TWA_RESUME task_work and >+ * memory.high/blkcg throttling would otherwise never run. Run >+ * them here, where no locks are held, like io-wq workers do. >+ */ >+ if (test_thread_flag(TIF_NOTIFY_RESUME)) >+ resume_user_mode_work(NULL); >+ > if (signal_pending(current)) { > struct ksignal ksig; > > >base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222 > --- Thanks!
