From nobody Mon Jun 22 13:25:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CCC22C433F5 for ; Wed, 23 Mar 2022 14:56:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244951AbiCWO5o (ORCPT ); Wed, 23 Mar 2022 10:57:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244941AbiCWO5i (ORCPT ); Wed, 23 Mar 2022 10:57:38 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BC4B8165C for ; Wed, 23 Mar 2022 07:56:09 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id qa43so3328662ejc.12 for ; Wed, 23 Mar 2022 07:56:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4ocZ020biSSlMCzLyHzrYyXSRMNycQFiAPnqhwZV8Jo=; b=ToXuI8M/+8sDxN7w3MxP2P8OJelARc/TEu7LTms49PxLD3X8ufyrk6AZFIJYptu97f t718JP97xCJnh5iU+PKgahb5HYzvQaNodRYaspB53ZW5Szp69qqAYj5u1/WAlEmTky3J pu0TJ4VcwtC4yHyk7FCC2Jj0NseTlZevPA7RQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4ocZ020biSSlMCzLyHzrYyXSRMNycQFiAPnqhwZV8Jo=; b=o+5H46c2LJeKcycfuCqzISBQph0ASsDE4gUiiQZ9RTNCx1Nx8AJ33RCo2Mg98iR2UL jmzaipnW4xY8aeF+yKNrYp4nzfbDEs0BUyQWBeSRJle+TTUQ+iKb6eFwPkalHbrCyhDy pMqM62coMa3g1ZWNKHy74U+g7AiXz1TjvGts1KMHdJFuzK4O5SY9mPM4GcqmLIyJzfG5 w86Peg6Xl6Bq/WOx+eeX4HggAzq1M+ZqGBF9NxubvNZZsheqNfJS+OyoA4qLlT+eCWpz 0vJOpzla7LbmBaSNAJZXJXr2J0LwovALwejwuCT8TQGTRnBh+VDXL2wQ+0ZlILqzbn8g tuww== X-Gm-Message-State: AOAM533wEBicc/zjutKZq4uONW7GsS4IlsblH2iSRh03F+ZJVi+9zEon EXYBreSBc6ij4JAcpQmkwvpt2A== X-Google-Smtp-Source: ABdhPJxCumSHokPvg0VDPchzYbIyB8Shhfo0ruu/8TYZEwJYtl/jJX8JvRe7KF4Av1voNThfaQcD5A== X-Received: by 2002:a17:907:2d13:b0:6df:a061:8141 with SMTP id gs19-20020a1709072d1300b006dfa0618141mr325151ejc.663.1648047367675; Wed, 23 Mar 2022 07:56:07 -0700 (PDT) Received: from prevas-ravi.tritech.se ([80.208.64.233]) by smtp.gmail.com with ESMTPSA id p14-20020a05640210ce00b00413211746d4sm77256edu.51.2022.03.23.07.56.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Mar 2022 07:56:06 -0700 (PDT) From: Rasmus Villemoes To: Tejun Heo , Lai Jiangshan Cc: =?UTF-8?q?Andr=C3=A9=20Pribil?= , Steven Walter , Oleksij Rempel , Esben Haabendal , Jiri Slaby , Pengutronix Kernel Team , Peter Hurley , linux-rt-users@vger.kernel.org, Rasmus Villemoes , linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/2] workqueue: allow use of realtime scheduling policies Date: Wed, 23 Mar 2022 15:55:59 +0100 Message-Id: <20220323145600.2156689-2-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220323145600.2156689-1-linux@rasmusvillemoes.dk> References: <20220323145600.2156689-1-linux@rasmusvillemoes.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Prepare for allowing the administrator to set RT scheduling policies, rather than just tweaking the nice value, of workqueues exposed via sysfs. Subsystems that currently use, say, system_unbound_wq, can be updated to create a separate workqueue (possibly depending on a CONFIG_ knob or boottime parameter). This patch merely updates the internal interfaces. The next patch will expose a sysfs knob. Signed-off-by: Rasmus Villemoes --- include/linux/workqueue.h | 17 +++++++++++++++-- kernel/workqueue.c | 20 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 7fee9b6cfede..a69bdd877120 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -131,9 +131,22 @@ struct rcu_work { */ struct workqueue_attrs { /** - * @nice: nice level + * @policy: scheduling policy (SCHED_NORMAL, SCHED_FIFO, SCHED_RR) */ - int nice; + int policy; + + /** + * @nice: nice level (SCHED_NORMAL) + * @priority: priority (SCHED_FIFO, SCHED_RR) + * + * Letting these two fields occupy the same word simplifies + * copying, hashing and equality testing of struct + * workqueue_attrs. + */ + union { + int nice; + int priority; + }; =20 /** * @cpumask: allowed CPUs diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 33f1106b4f99..9eb2ff7bcc04 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -51,6 +51,7 @@ #include #include #include +#include =20 #include "workqueue_internal.h" =20 @@ -1969,7 +1970,13 @@ static struct worker *create_worker(struct worker_po= ol *pool) if (IS_ERR(worker->task)) goto fail; =20 - set_user_nice(worker->task, pool->attrs->nice); + if (pool->attrs->policy =3D=3D SCHED_NORMAL) { + set_user_nice(worker->task, pool->attrs->nice); + } else { + struct sched_param sp =3D { .sched_priority =3D pool->attrs->priority }; + + sched_setscheduler(worker->task, pool->attrs->policy, &sp); + } kthread_bind_mask(worker->task, pool->attrs->cpumask); =20 /* successful, attach the worker to the pool */ @@ -3402,6 +3409,12 @@ struct workqueue_attrs *alloc_workqueue_attrs(void) { struct workqueue_attrs *attrs; =20 + /* + * A zeroed structure has ->policy=3D=3DSCHED_NORMAL and + * ->nice=3D=3D0. + */ + static_assert(SCHED_NORMAL =3D=3D 0); + attrs =3D kzalloc(sizeof(*attrs), GFP_KERNEL); if (!attrs) goto fail; @@ -3418,6 +3431,7 @@ struct workqueue_attrs *alloc_workqueue_attrs(void) static void copy_workqueue_attrs(struct workqueue_attrs *to, const struct workqueue_attrs *from) { + to->policy =3D from->policy; to->nice =3D from->nice; cpumask_copy(to->cpumask, from->cpumask); /* @@ -3433,7 +3447,7 @@ static u32 wqattrs_hash(const struct workqueue_attrs = *attrs) { u32 hash =3D 0; =20 - hash =3D jhash_1word(attrs->nice, hash); + hash =3D jhash_2words(attrs->policy, attrs->nice, hash); hash =3D jhash(cpumask_bits(attrs->cpumask), BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long), hash); return hash; @@ -3443,6 +3457,8 @@ static u32 wqattrs_hash(const struct workqueue_attrs = *attrs) static bool wqattrs_equal(const struct workqueue_attrs *a, const struct workqueue_attrs *b) { + if (a->policy !=3D b->policy) + return false; if (a->nice !=3D b->nice) return false; if (!cpumask_equal(a->cpumask, b->cpumask)) --=20 2.31.1 From nobody Mon Jun 22 13:25:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC70DC4332F for ; Wed, 23 Mar 2022 14:56:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244961AbiCWO5q (ORCPT ); Wed, 23 Mar 2022 10:57:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244933AbiCWO5k (ORCPT ); Wed, 23 Mar 2022 10:57:40 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 895767DE23 for ; Wed, 23 Mar 2022 07:56:10 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id bi12so3393163ejb.3 for ; Wed, 23 Mar 2022 07:56:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xxpZ0iiJJ0ZwZEvYkcJ55MAH2/mjQ7Nkl8lEGJi9pe8=; b=LABB1GCxIPlD3luxLyc/Nvl+Hx/y317qPwHAgq23XvnHF9qpUBg7Oj4qKR9m2oKy9Z nLHPjFsSVxbqnfMNTml3G5XFtYhv8f8ntalWyDLPzFpp/dHrB+gFda+AuFQOaMhvDpOG lVJ8tx+kfAFLsN1d7jnDqXAnP4HnCw5VLTupQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xxpZ0iiJJ0ZwZEvYkcJ55MAH2/mjQ7Nkl8lEGJi9pe8=; b=g61D0WCUVUGFeF9yAvYF4FjVAeiAriee/cn6pNH+I4V5OxaqVwTpiGEpoNYBUAinaP BPE5y66s7LvlP8JgHbv+0EEzoEoGgMA0dHctM5y+EgSIHoFXetu3S7tP+3Dw/BbGd290 z2A5X/bFuKWqXQ+Hv6Jl0PTJw4h776l7dU5NcFCCRRTs6hTR6xqF6vCgLVFRpwwKzIEt 7OEpKFV98pKn0Xf5AazN42TlR97l8xw12JAJsN04PhM9zPF7sCNWLJAq5ujxlOXbYmw/ LNt1hzlbYXy5ePqW006YkqgLbIHjXXQwGHu6izasyU7+FU1sNVw4/cWzyRx9+mLXsXFD XLIg== X-Gm-Message-State: AOAM531uCQy2RMmJZ8jywsIMMY5SXau8890Mv8CNO/ikI8B6sQ5Uq9Sj 5Qj5xrLqZEl1D/QetM/luRhJFQ== X-Google-Smtp-Source: ABdhPJyFFyzCsMB02alxju10p2mtcDMblMiJlaXPaFNhnOhkRjAQ/fDW1gf6qTgwYf+nZz7WQmnLzQ== X-Received: by 2002:a17:906:57c1:b0:6d6:da73:e9c0 with SMTP id u1-20020a17090657c100b006d6da73e9c0mr363734ejr.45.1648047369103; Wed, 23 Mar 2022 07:56:09 -0700 (PDT) Received: from prevas-ravi.tritech.se ([80.208.64.233]) by smtp.gmail.com with ESMTPSA id p14-20020a05640210ce00b00413211746d4sm77256edu.51.2022.03.23.07.56.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Mar 2022 07:56:08 -0700 (PDT) From: Rasmus Villemoes To: Tejun Heo , Lai Jiangshan Cc: =?UTF-8?q?Andr=C3=A9=20Pribil?= , Steven Walter , Oleksij Rempel , Esben Haabendal , Jiri Slaby , Pengutronix Kernel Team , Peter Hurley , linux-rt-users@vger.kernel.org, Rasmus Villemoes , linux-kernel@vger.kernel.org Subject: [RFC PATCH 2/2] workqueue: update sysfs handlers, allow setting RT policies Date: Wed, 23 Mar 2022 15:56:00 +0100 Message-Id: <20220323145600.2156689-3-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220323145600.2156689-1-linux@rasmusvillemoes.dk> References: <20220323145600.2156689-1-linux@rasmusvillemoes.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" For this POC, this (ab)uses the "nice" attribute. It's of course not exactly pretty, but it avoids the problem of "what to show in the xyz file when using SCHED_NORMAL, and what to show in the nice file when using SCHED_RR/SCHED_FIFO". It's backwards-compatible, in that a bare integer is interpreted as a nice value, while an integer prefixed by "fifo:" or "rr:" chooses that RT scheduling policy with the associated value as the priority. The show method of course reflects what the store method accepts. Signed-off-by: Rasmus Villemoes --- kernel/workqueue.c | 54 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 9eb2ff7bcc04..a97f1aff809e 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5538,13 +5538,34 @@ static ssize_t wq_nice_show(struct device *dev, str= uct device_attribute *attr, char *buf) { struct workqueue_struct *wq =3D dev_to_wq(dev); - int written; + struct workqueue_attrs *wqattrs; + const char *pfx; + int val; =20 mutex_lock(&wq->mutex); - written =3D scnprintf(buf, PAGE_SIZE, "%d\n", wq->unbound_attrs->nice); + wqattrs =3D wq->unbound_attrs; + switch (wqattrs->policy) { + case SCHED_NORMAL: + pfx =3D ""; + val =3D wqattrs->nice; + break; + case SCHED_FIFO: + pfx =3D "fifo:"; + val =3D wqattrs->priority; + break; + case SCHED_RR: + pfx =3D "rr:"; + val =3D wqattrs->priority; + break; + default: + /* Shouldn't happen. */ + pfx =3D NULL; + } mutex_unlock(&wq->mutex); =20 - return written; + if (!pfx) + return -EIO; + return scnprintf(buf, PAGE_SIZE, "%s%d\n", pfx, val); } =20 /* prepare workqueue_attrs for sysfs store operations */ @@ -5568,6 +5589,24 @@ static ssize_t wq_nice_store(struct device *dev, str= uct device_attribute *attr, struct workqueue_struct *wq =3D dev_to_wq(dev); struct workqueue_attrs *attrs; int ret =3D -ENOMEM; + int policy, val; + + if (sscanf(buf, "fifo:%d", &val) =3D=3D 1) + policy =3D SCHED_FIFO; + else if (sscanf(buf, "rr:%d", &val) =3D=3D 1) + policy =3D SCHED_RR; + else if (sscanf(buf, "%d", &val) =3D=3D 1) + policy =3D SCHED_NORMAL; + else + return -EINVAL; + + if (policy =3D=3D SCHED_NORMAL) { + if (val < MIN_NICE || val > MAX_NICE) + return -EINVAL; + } else { + if (val <=3D 0 || val >=3D MAX_RT_PRIO) + return -EINVAL; + } =20 apply_wqattrs_lock(); =20 @@ -5575,11 +5614,12 @@ static ssize_t wq_nice_store(struct device *dev, st= ruct device_attribute *attr, if (!attrs) goto out_unlock; =20 - if (sscanf(buf, "%d", &attrs->nice) =3D=3D 1 && - attrs->nice >=3D MIN_NICE && attrs->nice <=3D MAX_NICE) - ret =3D apply_workqueue_attrs_locked(wq, attrs); + attrs->policy =3D policy; + if (policy =3D=3D SCHED_NORMAL) + attrs->nice =3D val; else - ret =3D -EINVAL; + attrs->priority =3D val; + ret =3D apply_workqueue_attrs_locked(wq, attrs); =20 out_unlock: apply_wqattrs_unlock(); --=20 2.31.1