[RFC PATCH 4/8] blk-iocost: dispatch cost calculation to registered BPF model

From: Tao Cui

Date: Tue Sep 08 2026 - 06:48:37 EST


From: Tao Cui <cuitao@xxxxxxxxxx>

Add the bpf_cost_model field to struct ioc and the dispatch hook in
calc_vtime_cost(): when a BPF model is registered and the device has
opted in (bpf_cost_model set), call the model's calc_cost instead of
the builtin formula. If no model is registered anymore the builtin
formula is used as fallback.

The user interface to set bpf_cost_model follows.

Signed-off-by: Tao Cui <cuitao@xxxxxxxxxx>
---
block/blk-iocost.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index c24daa9d72ee9..bdb4bab86a116 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -177,6 +177,7 @@
#include <linux/timer.h>
#include <linux/time64.h>
#include <linux/parser.h>
+#include <linux/blk-iocost.h>
#include <linux/sched/signal.h>
#include <asm/local.h>
#include <asm/local64.h>
@@ -445,6 +446,7 @@ struct ioc {
int autop_idx;
bool user_qos_params:1;
bool user_cost_model:1;
+ bool bpf_cost_model;
};

struct iocg_pcpu_stat {
@@ -2578,6 +2580,23 @@ static u64 calc_vtime_cost(struct bio *bio, struct ioc_gq *iocg, bool is_merge)
{
u64 cost;

+#ifdef CONFIG_BLK_CGROUP_IOCOST_BPF
+ struct ioc *ioc = iocg->ioc;
+
+ if (READ_ONCE(ioc->bpf_cost_model)) {
+ u64 bpf_cost;
+
+ if (iocost_bpf_calc_cost(bio_op(bio),
+ bio->bi_iter.bi_size,
+ bio->bi_iter.bi_sector,
+ iocg->cursor,
+ iocg_to_blkg(iocg)->blkcg->css.id,
+ is_merge ? IOCOST_COST_F_MERGE : 0,
+ &bpf_cost))
+ return bpf_cost;
+ }
+#endif
+
calc_vtime_cost_builtin(bio, iocg, is_merge, &cost);
return cost;
}
--
2.43.0