mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tao Cui <cui.tao@linux.dev>
To: tj@kernel.org, josef@toxicopanda.com, axboe@kernel.dk
Cc: cgroups@vger.kernel.org, linux-block@vger.kernel.org,
	linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
	andrii@kernel.org, ast@kernel.org, daniel@iogearbox.net,
	linux-kselftest@vger.kernel.org, cui.tao@linux.dev,
	Tao Cui <cuitao@kylinos.cn>
Subject: [RFC PATCH 2/8] blk-iocost: define iocost_model_ops cost model interface
Date: Tue,  8 Sep 2026 18:01:37 +0800	[thread overview]
Message-ID: <20260908100143.47598-3-cui.tao@linux.dev> (raw)
In-Reply-To: <20260908100143.47598-1-cui.tao@linux.dev>

From: Tao Cui <cuitao@kylinos.cn>

Define the interface for pluggable cost models: a struct_ops with a
single calc_cost(op, nbytes, sector, cursor, iocg_id, flags) callback
taking scalar arguments only.  The return value is vtime (2^37 per
second of device time), clamped to 1s per IO by the kernel.  A return
value of 0 delegates the IO back to the builtin formula, so a model
which only handles some IO types cannot make the rest free.

iocg_id is the id of the issuing cgroup, so a model can keep
per-cgroup state, e.g. for multi-stream sequentiality detection.
The id is only valid while the cgroup exists and is recycled after
removal, so models must treat it as a transient key; struct_ops
callback signatures are frozen once merged, so the identifier is
part of the initial interface.

The model is called from the IO submission path under RCU and must
not sleep.  Only the bio-level charging path consults the model; the
request-level sizing path keeps using the builtin formula.

This is a definition-only patch; the registration infrastructure and
dispatch hook follow in subsequent patches.

Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
 block/Kconfig              |  9 ++++++
 include/linux/blk-iocost.h | 56 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 include/linux/blk-iocost.h

diff --git a/block/Kconfig b/block/Kconfig
index 70e4a66d941ff..bf43be21e00bb 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -231,4 +231,13 @@ config BLK_ERROR_INJECTION
 
 source "block/Kconfig.iosched"
 
+config BLK_CGROUP_IOCOST_BPF
+	bool "Enable BPF pluggable cost model support for the cost IO controller"
+	depends on BLK_CGROUP_IOCOST && BPF_SYSCALL && BPF_JIT
+	help
+	 Enabling this option registers the "iocost_model_ops" BPF
+	 struct_ops type, which allows a BPF program to replace the
+	 builtin linear cost model on devices configured with
+	 "ctrl=bpf" through io.cost.model.
+
 endif # BLOCK
diff --git a/include/linux/blk-iocost.h b/include/linux/blk-iocost.h
new file mode 100644
index 0000000000000..7111b5c03dc36
--- /dev/null
+++ b/include/linux/blk-iocost.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_BLK_IOCOST_H
+#define _LINUX_BLK_IOCOST_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_BLK_CGROUP_IOCOST_BPF
+
+/*
+ * Pluggable cost model interface for blk-iocost.
+ *
+ * A BPF struct_ops implementation registered against "iocost_model_ops"
+ * replaces the builtin linear cost model on devices configured with
+ * "ctrl=bpf" through io.cost.model.  The model is a pure function of the
+ * arguments below and returns the cost of the IO in device time units,
+ * where 1 second of device time equals 2^37 (VTIME_PER_SEC).  The
+ * returned value is clamped by the kernel.  A cost of 0 delegates the
+ * IO back to the builtin formula, so a model which does not handle a
+ * given IO type cannot make it free.
+ *
+ * The iocg_id argument identifies the issuing cgroup (css id) so the
+ * model can keep per-cgroup state, e.g. for multi-stream sequentiality
+ * detection.  The id is only valid while the cgroup exists: css ids are
+ * recycled once the cgroup is removed, so models must treat it as a
+ * transient key and reset state when they observe it reused.  Whether
+ * the interface needs a release(iocg_id) callback for state cleanup is
+ * an open question.
+ *
+ * The model is called from the IO submission path under RCU and must
+ * not sleep.  Only the bio-level charging path consults the model;
+ * the request-level sizing path (calc_size_vtime_cost()) keeps using
+ * the builtin formula.
+ */
+
+/* flags for calc_cost() */
+#define IOCOST_COST_F_MERGE	(1ULL << 0)	/* called from merge path */
+
+struct iocost_model_ops {
+	/*
+	 * @op:		REQ_OP_* value (uapi blk_opf.h)
+	 * @nbytes:	IO size in bytes
+	 * @sector:	starting sector
+	 * @cursor:	iocg cursor sector, 0 if none (sequentiality hint)
+	 * @iocg_id:	css id of the issuing cgroup
+	 * @flags:	IOCOST_COST_F_*
+	 */
+	u64 (*calc_cost)(u64 op, u64 nbytes, u64 sector, u64 cursor,
+			 u64 iocg_id, u64 flags);
+};
+
+bool iocost_bpf_calc_cost(u64 op, u64 nbytes, u64 sector, u64 cursor,
+			  u64 iocg_id, u64 flags, u64 *costp);
+bool iocost_bpf_model_registered(void);
+
+#endif	/* CONFIG_BLK_CGROUP_IOCOST_BPF */
+#endif	/* _LINUX_BLK_IOCOST_H */
-- 
2.43.0


  parent reply	other threads:[~2026-09-08 10:02 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 10:01 [RFC PATCH 0/8] blk-iocost: BPF struct_ops cost model Tao Cui
2026-09-08 10:01 ` [RFC PATCH 1/8] blk-iocost: add iocost_ioc_tick tracepoint for per-period device summary Tao Cui
2026-09-08 10:01 ` Tao Cui [this message]
2026-09-08 20:31   ` [RFC PATCH 2/8] blk-iocost: define iocost_model_ops cost model interface Tejun Heo
2026-09-08 10:01 ` [RFC PATCH 3/8] blk-iocost: implement BPF struct_ops registration Tao Cui
2026-09-08 20:31   ` Tejun Heo
2026-09-08 10:01 ` [RFC PATCH 4/8] blk-iocost: dispatch cost calculation to registered BPF model Tao Cui
2026-09-08 20:31   ` Tejun Heo
2026-09-08 10:01 ` [RFC PATCH 5/8] blk-iocost: add ctrl=bpf per-device opt-in Tao Cui
2026-09-08 10:01 ` [RFC PATCH 6/8] selftests/bpf: add iocost cost model test Tao Cui
2026-09-08 20:31   ` Tejun Heo
2026-09-08 10:01 ` [RFC PATCH 7/8] selftests/bpf: add multi-stream sequentiality example model Tao Cui
2026-09-08 20:31   ` Tejun Heo
2026-09-08 10:01 ` [RFC PATCH 8/8] docs: cgroup-v2: document io.cost ctrl=bpf option Tao Cui
2026-09-08 20:31 ` [RFC PATCH 0/8] blk-iocost: BPF struct_ops cost model Tejun Heo
2026-09-09 13:12   ` Tao Cui

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=20260908100143.47598-3-cui.tao@linux.dev \
    --to=cui.tao@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=bpf@vger.kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=cuitao@kylinos.cn \
    --cc=daniel@iogearbox.net \
    --cc=josef@toxicopanda.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --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

all inboxes | Powered by JetHome®