@@ -3249,6 +3249,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
}
memflags = blk_mq_freeze_queue(disk->queue);
+ mutex_lock(&disk->queue->elevator_lock);
blk_mq_quiesce_queue(disk->queue);
spin_lock_irq(&ioc->lock);
@@ -3356,6 +3357,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
spin_unlock_irq(&ioc->lock);
blk_mq_unquiesce_queue(disk->queue);
+ mutex_unlock(&disk->queue->elevator_lock);
blk_mq_unfreeze_queue(disk->queue, memflags);
ret = -EINVAL;
@@ -557,7 +557,7 @@ static ssize_t queue_wb_lat_show(struct gendisk *disk, char *page)
ssize_t ret;
struct request_queue *q = disk->queue;
- mutex_lock(&q->sysfs_lock);
+ mutex_lock(&q->elevator_lock);
if (!wbt_rq_qos(q)) {
ret = -EINVAL;
goto out;
@@ -570,7 +570,7 @@ static ssize_t queue_wb_lat_show(struct gendisk *disk, char *page)
ret = sysfs_emit(page, "%llu\n", div_u64(wbt_get_min_lat(q), 1000));
out:
- mutex_unlock(&q->sysfs_lock);
+ mutex_unlock(&q->elevator_lock);
return ret;
}
@@ -589,8 +589,8 @@ static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page,
if (val < -1)
return -EINVAL;
- mutex_lock(&q->sysfs_lock);
memflags = blk_mq_freeze_queue(q);
+ mutex_lock(&q->elevator_lock);
rqos = wbt_rq_qos(q);
if (!rqos) {
@@ -619,8 +619,8 @@ static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page,
blk_mq_unquiesce_queue(q);
out:
+ mutex_unlock(&q->elevator_lock);
blk_mq_unfreeze_queue(q, memflags);
- mutex_unlock(&q->sysfs_lock);
return ret;
}
@@ -701,7 +701,9 @@ static struct attribute *blk_mq_queue_attrs[] = {
*/
&elv_iosched_entry.attr,
&queue_requests_entry.attr,
-
+#ifdef CONFIG_BLK_WBT
+ &queue_wb_lat_entry.attr,
+#endif
/*
* Attributes which don't require locking.
*/
@@ -882,10 +884,10 @@ int blk_register_queue(struct gendisk *disk)
goto out_crypto_sysfs_unregister;
}
}
+ wbt_enable_default(disk);
mutex_unlock(&q->elevator_lock);
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
- wbt_enable_default(disk);
/* Now everything is ready and send out KOBJ_ADD uevent */
kobject_uevent(&disk->queue_kobj, KOBJ_ADD);
@@ -563,8 +563,8 @@ struct request_queue {
/*
* Protects against I/O scheduler switching, particularly when
* updating q->elevator. Since the elevator update code path may
- * also modify q->nr_requests, this lock also protects the sysfs
- * attribute nr_requests.
+ * also modify q->nr_requests and wbt latency, this lock also
+ * protects the sysfs attributes nr_requests and wbt_lat_usec.
* To ensure proper locking order during an elevator update, first
* freeze the queue, then acquire ->elevator_lock.
*/