mirror of
https://github.com/torvalds/linux.git
synced 2026-03-07 23:04:33 +01:00
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>
This commit is contained in:
parent
06564bae93
commit
2751b90051
3 changed files with 51 additions and 45 deletions
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue