]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
blk-wbt: factor out a helper wbt_set_lat()
authorYu Kuai <yukuai@fnnas.com>
Mon, 2 Feb 2026 08:05:16 +0000 (16:05 +0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 2 Feb 2026 14:05:19 +0000 (07:05 -0700)
To move implementation details inside blk-wbt.c, prepare to fix possible
deadlock to call wbt_init() while queue is frozen in the next patch.

Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Yu Kuai <yukuai@fnnas.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-sysfs.c
block/blk-wbt.c
block/blk-wbt.h

index e0a70d26972b3b29c0413542f43d4d513ac206e4..a580688c3ad51ebb6209182fe630d2fb3a15a46e 100644 (file)
@@ -636,11 +636,8 @@ out:
 static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page,
                                  size_t count)
 {
-       struct request_queue *q = disk->queue;
-       struct rq_qos *rqos;
        ssize_t ret;
        s64 val;
-       unsigned int memflags;
 
        ret = queue_var_store64(&val, page);
        if (ret < 0)
@@ -648,40 +645,8 @@ static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page,
        if (val < -1)
                return -EINVAL;
 
-       /*
-        * Ensure that the queue is idled, in case the latency update
-        * ends up either enabling or disabling wbt completely. We can't
-        * have IO inflight if that happens.
-        */
-       memflags = blk_mq_freeze_queue(q);
-
-       rqos = wbt_rq_qos(q);
-       if (!rqos) {
-               ret = wbt_init(disk);
-               if (ret)
-                       goto out;
-       }
-
-       ret = count;
-       if (val == -1)
-               val = wbt_default_latency_nsec(q);
-       else if (val >= 0)
-               val *= 1000ULL;
-
-       if (wbt_get_min_lat(q) == val)
-               goto out;
-
-       blk_mq_quiesce_queue(q);
-
-       mutex_lock(&disk->rqos_state_mutex);
-       wbt_set_min_lat(q, val);
-       mutex_unlock(&disk->rqos_state_mutex);
-
-       blk_mq_unquiesce_queue(q);
-out:
-       blk_mq_unfreeze_queue(q, memflags);
-
-       return ret;
+       ret = wbt_set_lat(disk, val);
+       return ret ? ret : count;
 }
 
 QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec");
index 8e025834f2fbbc7f0be1318f2d82617f5aaaa383..0a37d97bda75d809366cbf35ec5a5f494cf3f7ee 100644 (file)
@@ -93,6 +93,8 @@ struct rq_wb {
        struct rq_depth rq_depth;
 };
 
+static int wbt_init(struct gendisk *disk);
+
 static inline struct rq_wb *RQWB(struct rq_qos *rqos)
 {
        return container_of(rqos, struct rq_wb, rqos);
@@ -506,7 +508,7 @@ u64 wbt_get_min_lat(struct request_queue *q)
        return RQWB(rqos)->min_lat_nsec;
 }
 
-void wbt_set_min_lat(struct request_queue *q, u64 val)
+static void wbt_set_min_lat(struct request_queue *q, u64 val)
 {
        struct rq_qos *rqos = wbt_rq_qos(q);
        if (!rqos)
@@ -741,7 +743,7 @@ void wbt_init_enable_default(struct gendisk *disk)
                WARN_ON_ONCE(wbt_init(disk));
 }
 
-u64 wbt_default_latency_nsec(struct request_queue *q)
+static u64 wbt_default_latency_nsec(struct request_queue *q)
 {
        /*
         * We default to 2msec for non-rotational storage, and 75msec
@@ -901,7 +903,7 @@ static const struct rq_qos_ops wbt_rqos_ops = {
 #endif
 };
 
-int wbt_init(struct gendisk *disk)
+static int wbt_init(struct gendisk *disk)
 {
        struct request_queue *q = disk->queue;
        struct rq_wb *rwb;
@@ -948,3 +950,45 @@ err_free:
        return ret;
 
 }
+
+int wbt_set_lat(struct gendisk *disk, s64 val)
+{
+       struct request_queue *q = disk->queue;
+       unsigned int memflags;
+       struct rq_qos *rqos;
+       int ret = 0;
+
+       /*
+        * Ensure that the queue is idled, in case the latency update
+        * ends up either enabling or disabling wbt completely. We can't
+        * have IO inflight if that happens.
+        */
+       memflags = blk_mq_freeze_queue(q);
+
+       rqos = wbt_rq_qos(q);
+       if (!rqos) {
+               ret = wbt_init(disk);
+               if (ret)
+                       goto out;
+       }
+
+       if (val == -1)
+               val = wbt_default_latency_nsec(q);
+       else if (val >= 0)
+               val *= 1000ULL;
+
+       if (wbt_get_min_lat(q) == val)
+               goto out;
+
+       blk_mq_quiesce_queue(q);
+
+       mutex_lock(&disk->rqos_state_mutex);
+       wbt_set_min_lat(q, val);
+       mutex_unlock(&disk->rqos_state_mutex);
+
+       blk_mq_unquiesce_queue(q);
+out:
+       blk_mq_unfreeze_queue(q, memflags);
+
+       return ret;
+}
index 925f2247573834fc7f4e384f1ac97f4bfbc24a55..6e39da17218b461b2991e3e4e6f1e8a3fd13848e 100644 (file)
@@ -4,16 +4,13 @@
 
 #ifdef CONFIG_BLK_WBT
 
-int wbt_init(struct gendisk *disk);
 void wbt_init_enable_default(struct gendisk *disk);
 void wbt_disable_default(struct gendisk *disk);
 void wbt_enable_default(struct gendisk *disk);
 
 u64 wbt_get_min_lat(struct request_queue *q);
-void wbt_set_min_lat(struct request_queue *q, u64 val);
-bool wbt_disabled(struct request_queue *);
-
-u64 wbt_default_latency_nsec(struct request_queue *);
+bool wbt_disabled(struct request_queue *q);
+int wbt_set_lat(struct gendisk *disk, s64 val);
 
 #else