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

block: protect read_ahead_kb using q->limits_lock

The bdi->ra_pages could be updated under q->limits_lock because it's
usually calculated from the queue limits by queue_limits_commit_update.
So protect reading/writing the sysfs attribute read_ahead_kb using
q->limits_lock instead of q->sysfs_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-8-nilay@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Nilay Shroff and committed by
Jens Axboe
5e40f445 245618f8

+13 -6
+10 -6
block/blk-sysfs.c
··· 93 93 { 94 94 ssize_t ret; 95 95 96 - mutex_lock(&disk->queue->sysfs_lock); 96 + mutex_lock(&disk->queue->limits_lock); 97 97 ret = queue_var_show(disk->bdi->ra_pages << (PAGE_SHIFT - 10), page); 98 - mutex_unlock(&disk->queue->sysfs_lock); 98 + mutex_unlock(&disk->queue->limits_lock); 99 99 100 100 return ret; 101 101 } ··· 111 111 ret = queue_var_store(&ra_kb, page, count); 112 112 if (ret < 0) 113 113 return ret; 114 - 115 - mutex_lock(&q->sysfs_lock); 114 + /* 115 + * ->ra_pages is protected by ->limits_lock because it is usually 116 + * calculated from the queue limits by queue_limits_commit_update. 117 + */ 118 + mutex_lock(&q->limits_lock); 116 119 memflags = blk_mq_freeze_queue(q); 117 120 disk->bdi->ra_pages = ra_kb >> (PAGE_SHIFT - 10); 121 + mutex_unlock(&q->limits_lock); 118 122 blk_mq_unfreeze_queue(q, memflags); 119 - mutex_unlock(&q->sysfs_lock); 120 123 121 124 return ret; 122 125 } ··· 673 670 &queue_dma_alignment_entry.attr, 674 671 675 672 /* 676 - * Attributes which are protected with q->sysfs_lock. 673 + * Attributes which require some form of locking other than 674 + * q->sysfs_lock. 677 675 */ 678 676 &queue_ra_entry.attr, 679 677
+3
include/linux/blkdev.h
··· 571 571 struct mutex elevator_lock; 572 572 573 573 struct mutex sysfs_lock; 574 + /* 575 + * Protects queue limits and also sysfs attribute read_ahead_kb. 576 + */ 574 577 struct mutex limits_lock; 575 578 576 579 /*