Linux block layer
 help / color / mirror / Atom feed
From: Costa Shulyupin <costa.shul@redhat.com>
To: ming.lei@redhat.com, "Jens Axboe" <axboe@kernel.dk>,
	"Waiman Long" <longman@redhat.com>,
	"Zefan Li" <lizefan.x@bytedance.com>, "Tejun Heo" <tj@kernel.org>,
	"Johannes Weiner" <hannes@cmpxchg.org>,
	"Michal Koutný" <mkoutny@suse.com>,
	linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
	cgroups@vger.kernel.org
Cc: Costa Shulyupin <costa.shul@redhat.com>
Subject: [RFC PATCH v1] blk-mq: isolate CPUs from hctx
Date: Fri,  8 Nov 2024 07:48:30 +0200	[thread overview]
Message-ID: <20241108054831.2094883-3-costa.shul@redhat.com> (raw)

The housekeeping CPU masks, set up by the "isolcpus" and "nohz_full"
boot command line options, are used at boot time to exclude selected
CPUs from running some kernel housekeeping subsystems to minimize
disturbance to latency sensitive userspace applications such as DPDK.
This options can only be changed with a reboot. This is a problem for
containerized workloads running on OpenShift/Kubernetes where a
mix of low latency and "normal" workloads can be created/destroyed
dynamically and the number of CPUs allocated to each workload is often
not known at boot time.

Cgroups allow configuring isolated_cpus at runtime.
However, blk-mq may still use managed interrupts on the
newly isolated CPUs.

Rebuild hctx->cpumask considering isolated CPUs to avoid
managed interrupts on those CPUs and reclaim non-isolated ones.

The patch is based on
isolation: Exclude dynamically isolated CPUs from housekeeping masks:
https://lore.kernel.org/lkml/20240821142312.236970-1-longman@redhat.com/

Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---
 block/blk-mq.c         | 30 ++++++++++++++++++++++++++++++
 include/linux/blk-mq.h |  1 +
 kernel/cgroup/cpuset.c |  2 ++
 3 files changed, 33 insertions(+)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 12ee37986331..d5786b953d17 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4145,6 +4145,36 @@ static void blk_mq_map_swqueue(struct request_queue *q)
 	}
 }
 
+/**
+ * blk_mq_isolate_cpus() - rebuild hctx->cpumask considering isolated CPUs
+ * to avoid managed interrupts on those CPUs.
+ */
+
+void blk_mq_isolate_cpus(const struct cpumask *isolcpus)
+{
+	struct class_dev_iter iter;
+	struct device *dev;
+
+	class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
+	while ((dev = class_dev_iter_next(&iter))) {
+		struct request_queue *q = bdev_get_queue(dev_to_bdev(dev));
+		struct blk_mq_hw_ctx *hctx;
+		unsigned long i;
+
+		if (!queue_is_mq(q))
+			continue;
+
+		blk_mq_map_swqueue(q);
+		/*
+		 * Postcondition:
+		 * cpumask must not intersect with isolated CPUs.
+		 */
+		queue_for_each_hw_ctx(q, hctx, i)
+			WARN_ON_ONCE(cpumask_intersects(hctx->cpumask, isolcpus));
+	}
+	class_dev_iter_exit(&iter);
+}
+
 /*
  * Caller needs to ensure that we're either frozen/quiesced, or that
  * the queue isn't live yet.
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 2035fad3131f..a1f57b5ad46d 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -924,6 +924,7 @@ void blk_freeze_queue_start_non_owner(struct request_queue *q);
 
 void blk_mq_map_queues(struct blk_mq_queue_map *qmap);
 void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues);
+void blk_mq_isolate_cpus(const struct cpumask *isolcpus);
 
 void blk_mq_quiesce_queue_nowait(struct request_queue *q);
 
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 5066397899c9..cad17f3f3315 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -41,6 +41,7 @@
 #include <linux/sched/isolation.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include <linux/blk-mq.h>
 
 #undef pr_fmt
 #define pr_fmt(fmt)    "%s:%d: %s " fmt, __FILE__, __LINE__, __func__
@@ -1317,6 +1318,7 @@ static void update_isolation_cpumasks(bool isolcpus_updated)
 		return;
 	ret = housekeeping_exlude_isolcpus(isolated_cpus, HOUSEKEEPING_FLAGS);
 	WARN_ON_ONCE((ret < 0) && (ret != -EOPNOTSUPP));
+	blk_mq_isolate_cpus(isolated_cpus);
 }
 
 /**
-- 
2.47.0


             reply	other threads:[~2024-11-08  5:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-08  5:48 Costa Shulyupin [this message]
2024-11-12  9:45 ` [RFC PATCH v1] blk-mq: isolate CPUs from hctx Daniel Wagner
2024-11-15 15:45 ` Michal Koutný
2024-11-15 20:16   ` Waiman Long
2024-11-15 20:25   ` Costa Shulyupin
2024-11-15 21:37     ` 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=20241108054831.2094883-3-costa.shul@redhat.com \
    --to=costa.shul@redhat.com \
    --cc=axboe@kernel.dk \
    --cc=cgroups@vger.kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan.x@bytedance.com \
    --cc=longman@redhat.com \
    --cc=ming.lei@redhat.com \
    --cc=mkoutny@suse.com \
    --cc=tj@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox