From nobody Thu Apr 9 10:32:02 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3D643A7F6C for ; Mon, 9 Mar 2026 13:15:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773062146; cv=none; b=KNf7svMHcbFJHxDDVuj53CfRBFppIMqpz2II3TRC9fHYn7C9i1frfN+Q4uJD1hIclHgJyqscXXs36BQCqYYEH6wvhhi9DixWYwiqKSgJtWHmG7NhNGDwVvr6dIp/rLE4GMhcVfU19De2a1I2afu83S3Ackpd3XPD3vSNlefAmgs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773062146; c=relaxed/simple; bh=BY1/1hp3CvV35LwwwhtRC4YXIBz66GBAS48lJAO1fjY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=NY/4Zqn5TuYLg7bplZe/jMtEjYkCsg3jGs6f3wLJHPGCcDrtFdA6cSwUpVwWhUZBy68/Sg6pW1oBcqw9r8P7IPCPDprrdWOuKkDvkO3A7ebaPNIJNAxUpjnwX15MwV+x9ySn0WTnM99IUX9M5/A8+ne3oecoxtPUB+ypMn5MMzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=Sn0jsYUi; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="Sn0jsYUi" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-485409ab264so2442005e9.1 for ; Mon, 09 Mar 2026 06:15:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1773062143; x=1773666943; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=AtBFcXwc2eoI8EoRfY74dBFgCRdq0qdLWaznXZ9Hy9Q=; b=Sn0jsYUi4KbICHdUxq8IERJPL6q4ogq1g/VoMOY24pd49xaMWjgqQDve5wDHLNRZ4O TfFprU5Uh0pMB+LWoJZwCDHN2T40S4pbDjBEeZtDtlukuXZJBm1AmRsZ9tOFZZ/nYksU dTCKKLdsC2I7YE/1ZiqLoem88SD1uQY7ZDYl0JOzdyTJ7vGjuVv6C0ImCD8lNLlJ0/ZK seS3KTlP/K25unMI7ms+QXEXhYHEvMEmN/0+Vx+sJ6b6INQ+xLIRoLuy5K1/WSdEwkzg NgM3z12g7b2Ac8lBYBbBXZSUbvXZmJL30silSphsh2Z1zqZFV/ixbB0eAFZe+pgQfvuq hJGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773062143; x=1773666943; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=AtBFcXwc2eoI8EoRfY74dBFgCRdq0qdLWaznXZ9Hy9Q=; b=FG6/6h44kHj9LtMUszJNTlZ3H/ufMCrYmMhjFl7wliJtru1sKvsc3SJb+vdWb1PmTP bo6T0fjGhloPDPztZK7J/a04el+EMothcYwX6tl6qhPkJOYeBgil99+SSk3zyZBg419a 59yvluuQaU//oKy5Q8wrQsS4cyqIGgDJacWQUOELH9nCC1b4IHojJL2fgBbzCzfOOdCU EvDY/ioSqiXWwrVidHKvGYVucdVQ1Unb02WyUInKLeASnPrhe9PcsxiCgSDb3tsdESn5 dygOZTqIngU9WRtYYZJ4DjHpIv3vCLK0jckQ7Jg/8XyUmaFqWPsc7+52KjgQyGZLns4i R06g== X-Gm-Message-State: AOJu0YzoDLYoO5dY2Tz8OojjK/VAnjaP6Oe/XsN4UDXiocsb9DEC+KoK 7GvNCQ53zgzjS5mnQHe931td3GzlbHIeWKNVoVARXM2MX/UvG+rJ6An7Kg3Ei+6KnMFqAItl4Zf mAquS X-Gm-Gg: ATEYQzwZH2ISDgZT0GLnDC3FYPclIwByaUxrOFZ5w0U0hu9avQgJFkJZtL3BnTg7E/Y L2uM00r8909mCr0hVo56oRFoTR4L3R2s7Qph91O1VhOux0HwMC3taZvf9lbuTrVkCkiztqUtdwc Z8biiIIsiYXCv6MkFWy0kvEDG9ex6JhZsVp6XoFg67hfyvSBG2X7kUMJ6F8aDH3maTMMPMiA7HR BJn2uM6OolqZNquUqN45ioDpwVqN0F4La/FBXqG6sAdbGDoOVHWmwS+aVNyeXoAPg02Q8z61xul ZIgUhy8ghMlfmKTdgeX52P2EOGhFybJoYmOLQW24Xg4JQtzUgiy1tIQoo0abSPYWVZwi+eNJyRc 4xqCY14O0gkNAoB0Moz4J9MKHze4eANluItIJC98eomrKwVn/fzhxDXxvLFjWh7o0nrF2ks5Psw vJcnkyRAvJwI3xhzfdKi0RGrlKb9FylqRcggV+6xs= X-Received: by 2002:a05:600c:350a:b0:485:3cef:d6ea with SMTP id 5b1f17b1804b1-4853cefd8famr34865765e9.13.1773062142703; Mon, 09 Mar 2026 06:15:42 -0700 (PDT) Received: from linux.fritz.box ([2a00:6d43:105:c401:e307:1a37:2e76:ce91]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853a310b8fsm106330865e9.11.2026.03.09.06.15.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 06:15:42 -0700 (PDT) From: Marco Crivellari To: linux-kernel@vger.kernel.org Cc: Tejun Heo , Lai Jiangshan , Frederic Weisbecker , Sebastian Andrzej Siewior , Marco Crivellari , Michal Hocko Subject: [PATCH RFC] workqueue: Add system_dfl_long_wq for long unbound works Date: Mon, 9 Mar 2026 14:15:28 +0100 Message-ID: <20260309131528.221654-1-marco.crivellari@suse.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently there are users of queue_delayed_work() who specify system_long_wq, the per-cpu workqueue. This workqueue should be used for long per-cpu works, but queue_delayed_work() queue the work using: queue_delayed_work_on(WORK_CPU_UNBOUND, ...); This would end up calling __queue_delayed_work() that does: if (housekeeping_enabled(HK_TYPE_TIMER)) { // [....] } else { if (likely(cpu =3D=3D WORK_CPU_UNBOUND)) add_timer_global(timer); else add_timer_on(timer, cpu); } So when cpu =3D=3D WORK_CPU_UNBOUND the timer is global and is not using a specific CPU. Later, when __queue_work() is called: if (req_cpu =3D=3D WORK_CPU_UNBOUND) { if (wq->flags & WQ_UNBOUND) cpu =3D wq_select_unbound_cpu(raw_smp_processor_id()); else cpu =3D raw_smp_processor_id(); } Because the wq is not unbound, it takes the CPU where the timer fired and enqueue the work on that CPU. The consequence of all of this is that the work can run anywhere, depending on where the timer fired. Introduce system_dfl_long_wq in order to change, in a future step, users that are still calling: queue_delayed_work(system_long_wq, ...); with the new system_dfl_long_wq instead, so that the work may benefit from scheduler task placement. Signed-off-by: Marco Crivellari --- include/linux/workqueue.h | 6 ++++++ kernel/workqueue.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index a4749f56398f..ab3853c54230 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -440,6 +440,9 @@ enum wq_consts { * system_long_wq is similar to system_percpu_wq but may host long running * works. Queue flushing might take relatively long. * + * system_dfl_long_wq is similar to system_dfl_wq but it may host long run= ning + * works. + * * system_dfl_wq is unbound workqueue. Workers are not bound to * any specific CPU, not concurrency managed, and all queued works are * executed immediately as long as max_active limit is not reached and @@ -468,6 +471,7 @@ extern struct workqueue_struct *system_power_efficient_= wq; extern struct workqueue_struct *system_freezable_power_efficient_wq; extern struct workqueue_struct *system_bh_wq; extern struct workqueue_struct *system_bh_highpri_wq; +extern struct workqueue_struct *system_dfl_long_wq; =20 void workqueue_softirq_action(bool highpri); void workqueue_softirq_dead(unsigned int cpu); @@ -783,6 +787,8 @@ extern void __warn_flushing_systemwide_wq(void) _wq =3D=3D system_highpri_wq) || \ (__builtin_constant_p(_wq =3D=3D system_long_wq) && \ _wq =3D=3D system_long_wq) || \ + (__builtin_constant_p(_wq =3D=3D system_dfl_long_wq) && \ + _wq =3D=3D system_dfl_long_wq) || \ (__builtin_constant_p(_wq =3D=3D system_dfl_wq) && \ _wq =3D=3D system_dfl_wq) || \ (__builtin_constant_p(_wq =3D=3D system_freezable_wq) && \ diff --git a/kernel/workqueue.c b/kernel/workqueue.c index aeaec79bc09c..cc137c907c31 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -530,6 +530,8 @@ struct workqueue_struct *system_bh_wq; EXPORT_SYMBOL_GPL(system_bh_wq); struct workqueue_struct *system_bh_highpri_wq; EXPORT_SYMBOL_GPL(system_bh_highpri_wq); +struct workqueue_struct *system_dfl_long_wq __ro_after_init; +EXPORT_SYMBOL_GPL(system_dfl_long_wq); =20 static int worker_thread(void *__worker); static void workqueue_sysfs_unregister(struct workqueue_struct *wq); @@ -7942,11 +7944,12 @@ void __init workqueue_init_early(void) system_bh_wq =3D alloc_workqueue("events_bh", WQ_BH | WQ_PERCPU, 0); system_bh_highpri_wq =3D alloc_workqueue("events_bh_highpri", WQ_BH | WQ_HIGHPRI | WQ_PERCPU, 0); + system_dfl_long_wq =3D alloc_workqueue("events_dfl_long", WQ_UNBOUND, WQ_= MAX_ACTIVE); BUG_ON(!system_wq || !system_percpu_wq|| !system_highpri_wq || !system_lo= ng_wq || !system_unbound_wq || !system_freezable_wq || !system_dfl_wq || !system_power_efficient_wq || !system_freezable_power_efficient_wq || - !system_bh_wq || !system_bh_highpri_wq); + !system_bh_wq || !system_bh_highpri_wq || !system_dfl_long_wq); } =20 static void __init wq_cpu_intensive_thresh_init(void) --=20 2.53.0