Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: protect wbt_lat_usec using q->elevator_lock

The wbt latency and state could be updated while initializing the
elevator or exiting the elevator. It could be also updated while
configuring IO latency QoS parameters using cgroup. The elevator
code path is now protected with q->elevator_lock. So we should
protect the access to sysfs attribute wbt_lat_usec using q->elevator
_lock instead of q->sysfs_lock. White we're at it, also protect
ioc_qos_write(), which configures wbt parameters via cgroup, using
q->elevator_lock.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
Link: https://lore.kernel.org/r/20250304102551.2533767-7-nilay@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Nilay Shroff and committed by
Jens Axboe
245618f8 3efe7571

+12 -14
+2
block/blk-iocost.c
··· 3248 3248 } 3249 3249 3250 3250 memflags = blk_mq_freeze_queue(disk->queue); 3251 + mutex_lock(&disk->queue->elevator_lock); 3251 3252 blk_mq_quiesce_queue(disk->queue); 3252 3253 3253 3254 spin_lock_irq(&ioc->lock); ··· 3356 3355 spin_unlock_irq(&ioc->lock); 3357 3356 3358 3357 blk_mq_unquiesce_queue(disk->queue); 3358 + mutex_unlock(&disk->queue->elevator_lock); 3359 3359 blk_mq_unfreeze_queue(disk->queue, memflags); 3360 3360 3361 3361 ret = -EINVAL;
+8 -12
block/blk-sysfs.c
··· 557 557 ssize_t ret; 558 558 struct request_queue *q = disk->queue; 559 559 560 - mutex_lock(&q->sysfs_lock); 560 + mutex_lock(&q->elevator_lock); 561 561 if (!wbt_rq_qos(q)) { 562 562 ret = -EINVAL; 563 563 goto out; ··· 570 570 571 571 ret = sysfs_emit(page, "%llu\n", div_u64(wbt_get_min_lat(q), 1000)); 572 572 out: 573 - mutex_unlock(&q->sysfs_lock); 573 + mutex_unlock(&q->elevator_lock); 574 574 return ret; 575 575 } 576 576 ··· 589 589 if (val < -1) 590 590 return -EINVAL; 591 591 592 - mutex_lock(&q->sysfs_lock); 593 592 memflags = blk_mq_freeze_queue(q); 593 + mutex_lock(&q->elevator_lock); 594 594 595 595 rqos = wbt_rq_qos(q); 596 596 if (!rqos) { ··· 619 619 620 620 blk_mq_unquiesce_queue(q); 621 621 out: 622 + mutex_unlock(&q->elevator_lock); 622 623 blk_mq_unfreeze_queue(q, memflags); 623 - mutex_unlock(&q->sysfs_lock); 624 624 625 625 return ret; 626 626 } ··· 690 690 /* Request-based queue attributes that are not relevant for bio-based queues. */ 691 691 static struct attribute *blk_mq_queue_attrs[] = { 692 692 /* 693 - * Attributes which are protected with q->sysfs_lock. 694 - */ 695 - #ifdef CONFIG_BLK_WBT 696 - &queue_wb_lat_entry.attr, 697 - #endif 698 - /* 699 693 * Attributes which require some form of locking other than 700 694 * q->sysfs_lock. 701 695 */ 702 696 &elv_iosched_entry.attr, 703 697 &queue_requests_entry.attr, 704 - 698 + #ifdef CONFIG_BLK_WBT 699 + &queue_wb_lat_entry.attr, 700 + #endif 705 701 /* 706 702 * Attributes which don't require locking. 707 703 */ ··· 878 882 goto out_crypto_sysfs_unregister; 879 883 } 880 884 } 885 + wbt_enable_default(disk); 881 886 mutex_unlock(&q->elevator_lock); 882 887 883 888 blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q); 884 - wbt_enable_default(disk); 885 889 886 890 /* Now everything is ready and send out KOBJ_ADD uevent */ 887 891 kobject_uevent(&disk->queue_kobj, KOBJ_ADD);
+2 -2
include/linux/blkdev.h
··· 563 563 /* 564 564 * Protects against I/O scheduler switching, particularly when 565 565 * updating q->elevator. Since the elevator update code path may 566 - * also modify q->nr_requests, this lock also protects the sysfs 567 - * attribute nr_requests. 566 + * also modify q->nr_requests and wbt latency, this lock also 567 + * protects the sysfs attributes nr_requests and wbt_lat_usec. 568 568 * To ensure proper locking order during an elevator update, first 569 569 * freeze the queue, then acquire ->elevator_lock. 570 570 */