Skip to content

Commit 2751b90

Browse files
hailan94axboe
authored andcommitted
blk-wbt: factor out a helper wbt_set_lat()
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>
1 parent 06564ba commit 2751b90

3 files changed

Lines changed: 51 additions & 45 deletions

File tree

block/blk-sysfs.c

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -636,52 +636,17 @@ static ssize_t queue_wb_lat_show(struct gendisk *disk, char *page)
636636
static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page,
637637
size_t count)
638638
{
639-
struct request_queue *q = disk->queue;
640-
struct rq_qos *rqos;
641639
ssize_t ret;
642640
s64 val;
643-
unsigned int memflags;
644641

645642
ret = queue_var_store64(&val, page);
646643
if (ret < 0)
647644
return ret;
648645
if (val < -1)
649646
return -EINVAL;
650647

651-
/*
652-
* Ensure that the queue is idled, in case the latency update
653-
* ends up either enabling or disabling wbt completely. We can't
654-
* have IO inflight if that happens.
655-
*/
656-
memflags = blk_mq_freeze_queue(q);
657-
658-
rqos = wbt_rq_qos(q);
659-
if (!rqos) {
660-
ret = wbt_init(disk);
661-
if (ret)
662-
goto out;
663-
}
664-
665-
ret = count;
666-
if (val == -1)
667-
val = wbt_default_latency_nsec(q);
668-
else if (val >= 0)
669-
val *= 1000ULL;
670-
671-
if (wbt_get_min_lat(q) == val)
672-
goto out;
673-
674-
blk_mq_quiesce_queue(q);
675-
676-
mutex_lock(&disk->rqos_state_mutex);
677-
wbt_set_min_lat(q, val);
678-
mutex_unlock(&disk->rqos_state_mutex);
679-
680-
blk_mq_unquiesce_queue(q);
681-
out:
682-
blk_mq_unfreeze_queue(q, memflags);
683-
684-
return ret;
648+
ret = wbt_set_lat(disk, val);
649+
return ret ? ret : count;
685650
}
686651

687652
QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec");

block/blk-wbt.c

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ struct rq_wb {
9393
struct rq_depth rq_depth;
9494
};
9595

96+
static int wbt_init(struct gendisk *disk);
97+
9698
static inline struct rq_wb *RQWB(struct rq_qos *rqos)
9799
{
98100
return container_of(rqos, struct rq_wb, rqos);
@@ -506,7 +508,7 @@ u64 wbt_get_min_lat(struct request_queue *q)
506508
return RQWB(rqos)->min_lat_nsec;
507509
}
508510

509-
void wbt_set_min_lat(struct request_queue *q, u64 val)
511+
static void wbt_set_min_lat(struct request_queue *q, u64 val)
510512
{
511513
struct rq_qos *rqos = wbt_rq_qos(q);
512514
if (!rqos)
@@ -741,7 +743,7 @@ void wbt_init_enable_default(struct gendisk *disk)
741743
WARN_ON_ONCE(wbt_init(disk));
742744
}
743745

744-
u64 wbt_default_latency_nsec(struct request_queue *q)
746+
static u64 wbt_default_latency_nsec(struct request_queue *q)
745747
{
746748
/*
747749
* We default to 2msec for non-rotational storage, and 75msec
@@ -901,7 +903,7 @@ static const struct rq_qos_ops wbt_rqos_ops = {
901903
#endif
902904
};
903905

904-
int wbt_init(struct gendisk *disk)
906+
static int wbt_init(struct gendisk *disk)
905907
{
906908
struct request_queue *q = disk->queue;
907909
struct rq_wb *rwb;
@@ -948,3 +950,45 @@ int wbt_init(struct gendisk *disk)
948950
return ret;
949951

950952
}
953+
954+
int wbt_set_lat(struct gendisk *disk, s64 val)
955+
{
956+
struct request_queue *q = disk->queue;
957+
unsigned int memflags;
958+
struct rq_qos *rqos;
959+
int ret = 0;
960+
961+
/*
962+
* Ensure that the queue is idled, in case the latency update
963+
* ends up either enabling or disabling wbt completely. We can't
964+
* have IO inflight if that happens.
965+
*/
966+
memflags = blk_mq_freeze_queue(q);
967+
968+
rqos = wbt_rq_qos(q);
969+
if (!rqos) {
970+
ret = wbt_init(disk);
971+
if (ret)
972+
goto out;
973+
}
974+
975+
if (val == -1)
976+
val = wbt_default_latency_nsec(q);
977+
else if (val >= 0)
978+
val *= 1000ULL;
979+
980+
if (wbt_get_min_lat(q) == val)
981+
goto out;
982+
983+
blk_mq_quiesce_queue(q);
984+
985+
mutex_lock(&disk->rqos_state_mutex);
986+
wbt_set_min_lat(q, val);
987+
mutex_unlock(&disk->rqos_state_mutex);
988+
989+
blk_mq_unquiesce_queue(q);
990+
out:
991+
blk_mq_unfreeze_queue(q, memflags);
992+
993+
return ret;
994+
}

block/blk-wbt.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44

55
#ifdef CONFIG_BLK_WBT
66

7-
int wbt_init(struct gendisk *disk);
87
void wbt_init_enable_default(struct gendisk *disk);
98
void wbt_disable_default(struct gendisk *disk);
109
void wbt_enable_default(struct gendisk *disk);
1110

1211
u64 wbt_get_min_lat(struct request_queue *q);
13-
void wbt_set_min_lat(struct request_queue *q, u64 val);
14-
bool wbt_disabled(struct request_queue *);
15-
16-
u64 wbt_default_latency_nsec(struct request_queue *);
12+
bool wbt_disabled(struct request_queue *q);
13+
int wbt_set_lat(struct gendisk *disk, s64 val);
1714

1815
#else
1916

0 commit comments

Comments
 (0)