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: move q->sysfs_lock and queue-freeze under show/store method

In preparation to further simplify and group sysfs attributes which
don't require locking or require some form of locking other than q->
limits_lock, move acquire/release of q->sysfs_lock and queue freeze/
unfreeze under each attributes' respective show/store method.

While we are at it, also remove ->load_module() as it's used to load
the module before queue is freezed. Now as we moved queue-freeze under
->store(), we could load module directly from the attributes' store
method before we actually start freezing the queue. Currently, the
->load_module() is only used by "scheduler" attribute, so we now load
the relevant elevator module before we start freezing the queue in
elv_iosched_store().

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-3-nilay@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Nilay Shroff and committed by
Jens Axboe
b07a889e 6e51a127

+162 -68
+144 -66
block/blk-sysfs.c
··· 28 28 ssize_t (*store)(struct gendisk *disk, const char *page, size_t count); 29 29 int (*store_limit)(struct gendisk *disk, const char *page, 30 30 size_t count, struct queue_limits *lim); 31 - 32 - void (*load_module)(struct gendisk *disk, const char *page, size_t count); 33 31 }; 34 32 35 33 static ssize_t ··· 53 55 54 56 static ssize_t queue_requests_show(struct gendisk *disk, char *page) 55 57 { 56 - return queue_var_show(disk->queue->nr_requests, page); 58 + ssize_t ret; 59 + 60 + mutex_lock(&disk->queue->sysfs_lock); 61 + ret = queue_var_show(disk->queue->nr_requests, page); 62 + mutex_unlock(&disk->queue->sysfs_lock); 63 + return ret; 57 64 } 58 65 59 66 static ssize_t ··· 66 63 { 67 64 unsigned long nr; 68 65 int ret, err; 66 + unsigned int memflags; 67 + struct request_queue *q = disk->queue; 69 68 70 - if (!queue_is_mq(disk->queue)) 69 + if (!queue_is_mq(q)) 71 70 return -EINVAL; 72 71 73 72 ret = queue_var_store(&nr, page, count); 74 73 if (ret < 0) 75 74 return ret; 76 75 76 + mutex_lock(&q->sysfs_lock); 77 + memflags = blk_mq_freeze_queue(q); 77 78 if (nr < BLKDEV_MIN_RQ) 78 79 nr = BLKDEV_MIN_RQ; 79 80 80 81 err = blk_mq_update_nr_requests(disk->queue, nr); 81 82 if (err) 82 - return err; 83 - 83 + ret = err; 84 + blk_mq_unfreeze_queue(q, memflags); 85 + mutex_unlock(&q->sysfs_lock); 84 86 return ret; 85 87 } 86 88 87 89 static ssize_t queue_ra_show(struct gendisk *disk, char *page) 88 90 { 89 - return queue_var_show(disk->bdi->ra_pages << (PAGE_SHIFT - 10), page); 91 + ssize_t ret; 92 + 93 + mutex_lock(&disk->queue->sysfs_lock); 94 + ret = queue_var_show(disk->bdi->ra_pages << (PAGE_SHIFT - 10), page); 95 + mutex_unlock(&disk->queue->sysfs_lock); 96 + 97 + return ret; 90 98 } 91 99 92 100 static ssize_t ··· 105 91 { 106 92 unsigned long ra_kb; 107 93 ssize_t ret; 94 + unsigned int memflags; 95 + struct request_queue *q = disk->queue; 108 96 109 97 ret = queue_var_store(&ra_kb, page, count); 110 98 if (ret < 0) 111 99 return ret; 100 + 101 + mutex_lock(&q->sysfs_lock); 102 + memflags = blk_mq_freeze_queue(q); 112 103 disk->bdi->ra_pages = ra_kb >> (PAGE_SHIFT - 10); 104 + blk_mq_unfreeze_queue(q, memflags); 105 + mutex_unlock(&q->sysfs_lock); 106 + 113 107 return ret; 114 108 } 115 109 ··· 172 150 #define QUEUE_SYSFS_SHOW_CONST(_name, _val) \ 173 151 static ssize_t queue_##_name##_show(struct gendisk *disk, char *page) \ 174 152 { \ 175 - return sysfs_emit(page, "%d\n", _val); \ 153 + ssize_t ret; \ 154 + \ 155 + mutex_lock(&disk->queue->sysfs_lock); \ 156 + ret = sysfs_emit(page, "%d\n", _val); \ 157 + mutex_unlock(&disk->queue->sysfs_lock); \ 158 + return ret; \ 176 159 } 177 160 178 161 /* deprecated fields */ ··· 266 239 267 240 static ssize_t queue_poll_show(struct gendisk *disk, char *page) 268 241 { 269 - if (queue_is_mq(disk->queue)) 270 - return sysfs_emit(page, "%u\n", blk_mq_can_poll(disk->queue)); 271 - return sysfs_emit(page, "%u\n", 272 - !!(disk->queue->limits.features & BLK_FEAT_POLL)); 242 + ssize_t ret; 243 + 244 + mutex_lock(&disk->queue->sysfs_lock); 245 + if (queue_is_mq(disk->queue)) { 246 + ret = sysfs_emit(page, "%u\n", blk_mq_can_poll(disk->queue)); 247 + } else { 248 + ret = sysfs_emit(page, "%u\n", 249 + !!(disk->queue->limits.features & BLK_FEAT_POLL)); 250 + } 251 + mutex_unlock(&disk->queue->sysfs_lock); 252 + return ret; 273 253 } 274 254 275 255 static ssize_t queue_zoned_show(struct gendisk *disk, char *page) ··· 288 254 289 255 static ssize_t queue_nr_zones_show(struct gendisk *disk, char *page) 290 256 { 291 - return queue_var_show(disk_nr_zones(disk), page); 257 + ssize_t ret; 258 + 259 + mutex_lock(&disk->queue->sysfs_lock); 260 + ret = queue_var_show(disk_nr_zones(disk), page); 261 + mutex_unlock(&disk->queue->sysfs_lock); 262 + return ret; 292 263 } 293 264 294 265 static ssize_t queue_iostats_passthrough_show(struct gendisk *disk, char *page) ··· 320 281 321 282 static ssize_t queue_nomerges_show(struct gendisk *disk, char *page) 322 283 { 323 - return queue_var_show((blk_queue_nomerges(disk->queue) << 1) | 284 + ssize_t ret; 285 + 286 + mutex_lock(&disk->queue->sysfs_lock); 287 + ret = queue_var_show((blk_queue_nomerges(disk->queue) << 1) | 324 288 blk_queue_noxmerges(disk->queue), page); 289 + mutex_unlock(&disk->queue->sysfs_lock); 290 + return ret; 325 291 } 326 292 327 293 static ssize_t queue_nomerges_store(struct gendisk *disk, const char *page, 328 294 size_t count) 329 295 { 330 296 unsigned long nm; 297 + unsigned int memflags; 298 + struct request_queue *q = disk->queue; 331 299 ssize_t ret = queue_var_store(&nm, page, count); 332 300 333 301 if (ret < 0) 334 302 return ret; 335 303 336 - blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, disk->queue); 337 - blk_queue_flag_clear(QUEUE_FLAG_NOXMERGES, disk->queue); 304 + mutex_lock(&q->sysfs_lock); 305 + memflags = blk_mq_freeze_queue(q); 306 + blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, q); 307 + blk_queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); 338 308 if (nm == 2) 339 - blk_queue_flag_set(QUEUE_FLAG_NOMERGES, disk->queue); 309 + blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q); 340 310 else if (nm) 341 - blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, disk->queue); 311 + blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q); 312 + blk_mq_unfreeze_queue(q, memflags); 313 + mutex_unlock(&q->sysfs_lock); 342 314 343 315 return ret; 344 316 } 345 317 346 318 static ssize_t queue_rq_affinity_show(struct gendisk *disk, char *page) 347 319 { 348 - bool set = test_bit(QUEUE_FLAG_SAME_COMP, &disk->queue->queue_flags); 349 - bool force = test_bit(QUEUE_FLAG_SAME_FORCE, &disk->queue->queue_flags); 320 + ssize_t ret; 321 + bool set, force; 350 322 351 - return queue_var_show(set << force, page); 323 + mutex_lock(&disk->queue->sysfs_lock); 324 + set = test_bit(QUEUE_FLAG_SAME_COMP, &disk->queue->queue_flags); 325 + force = test_bit(QUEUE_FLAG_SAME_FORCE, &disk->queue->queue_flags); 326 + ret = queue_var_show(set << force, page); 327 + mutex_unlock(&disk->queue->sysfs_lock); 328 + return ret; 352 329 } 353 330 354 331 static ssize_t ··· 374 319 #ifdef CONFIG_SMP 375 320 struct request_queue *q = disk->queue; 376 321 unsigned long val; 322 + unsigned int memflags; 377 323 378 324 ret = queue_var_store(&val, page, count); 379 325 if (ret < 0) 380 326 return ret; 381 327 328 + mutex_lock(&q->sysfs_lock); 329 + memflags = blk_mq_freeze_queue(q); 382 330 if (val == 2) { 383 331 blk_queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 384 332 blk_queue_flag_set(QUEUE_FLAG_SAME_FORCE, q); ··· 392 334 blk_queue_flag_clear(QUEUE_FLAG_SAME_COMP, q); 393 335 blk_queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q); 394 336 } 337 + blk_mq_unfreeze_queue(q, memflags); 338 + mutex_unlock(&q->sysfs_lock); 395 339 #endif 396 340 return ret; 397 341 } ··· 407 347 static ssize_t queue_poll_store(struct gendisk *disk, const char *page, 408 348 size_t count) 409 349 { 410 - if (!(disk->queue->limits.features & BLK_FEAT_POLL)) 411 - return -EINVAL; 350 + unsigned int memflags; 351 + ssize_t ret = count; 352 + struct request_queue *q = disk->queue; 353 + 354 + mutex_lock(&q->sysfs_lock); 355 + memflags = blk_mq_freeze_queue(q); 356 + if (!(q->limits.features & BLK_FEAT_POLL)) { 357 + ret = -EINVAL; 358 + goto out; 359 + } 412 360 pr_info_ratelimited("writes to the poll attribute are ignored.\n"); 413 361 pr_info_ratelimited("please use driver specific parameters instead.\n"); 414 - return count; 362 + out: 363 + blk_mq_unfreeze_queue(q, memflags); 364 + mutex_unlock(&q->sysfs_lock); 365 + 366 + return ret; 415 367 } 416 368 417 369 static ssize_t queue_io_timeout_show(struct gendisk *disk, char *page) 418 370 { 419 - return sysfs_emit(page, "%u\n", jiffies_to_msecs(disk->queue->rq_timeout)); 371 + ssize_t ret; 372 + 373 + mutex_lock(&disk->queue->sysfs_lock); 374 + ret = sysfs_emit(page, "%u\n", 375 + jiffies_to_msecs(disk->queue->rq_timeout)); 376 + mutex_unlock(&disk->queue->sysfs_lock); 377 + return ret; 420 378 } 421 379 422 380 static ssize_t queue_io_timeout_store(struct gendisk *disk, const char *page, 423 381 size_t count) 424 382 { 425 - unsigned int val; 383 + unsigned int val, memflags; 426 384 int err; 385 + struct request_queue *q = disk->queue; 427 386 428 387 err = kstrtou32(page, 10, &val); 429 388 if (err || val == 0) 430 389 return -EINVAL; 431 390 432 - blk_queue_rq_timeout(disk->queue, msecs_to_jiffies(val)); 391 + mutex_lock(&q->sysfs_lock); 392 + memflags = blk_mq_freeze_queue(q); 393 + blk_queue_rq_timeout(q, msecs_to_jiffies(val)); 394 + blk_mq_unfreeze_queue(q, memflags); 395 + mutex_unlock(&q->sysfs_lock); 433 396 434 397 return count; 435 398 } ··· 511 428 .store_limit = _prefix##_store, \ 512 429 } 513 430 514 - #define QUEUE_RW_LOAD_MODULE_ENTRY(_prefix, _name) \ 515 - static struct queue_sysfs_entry _prefix##_entry = { \ 516 - .attr = { .name = _name, .mode = 0644 }, \ 517 - .show = _prefix##_show, \ 518 - .load_module = _prefix##_load_module, \ 519 - .store = _prefix##_store, \ 520 - } 521 - 522 431 QUEUE_RW_ENTRY(queue_requests, "nr_requests"); 523 432 QUEUE_RW_ENTRY(queue_ra, "read_ahead_kb"); 524 433 QUEUE_LIM_RW_ENTRY(queue_max_sectors, "max_sectors_kb"); ··· 518 443 QUEUE_LIM_RO_ENTRY(queue_max_segments, "max_segments"); 519 444 QUEUE_LIM_RO_ENTRY(queue_max_integrity_segments, "max_integrity_segments"); 520 445 QUEUE_LIM_RO_ENTRY(queue_max_segment_size, "max_segment_size"); 521 - QUEUE_RW_LOAD_MODULE_ENTRY(elv_iosched, "scheduler"); 446 + QUEUE_RW_ENTRY(elv_iosched, "scheduler"); 522 447 523 448 QUEUE_LIM_RO_ENTRY(queue_logical_block_size, "logical_block_size"); 524 449 QUEUE_LIM_RO_ENTRY(queue_physical_block_size, "physical_block_size"); ··· 587 512 588 513 static ssize_t queue_wb_lat_show(struct gendisk *disk, char *page) 589 514 { 590 - if (!wbt_rq_qos(disk->queue)) 591 - return -EINVAL; 515 + ssize_t ret; 516 + struct request_queue *q = disk->queue; 592 517 593 - if (wbt_disabled(disk->queue)) 594 - return sysfs_emit(page, "0\n"); 518 + mutex_lock(&q->sysfs_lock); 519 + if (!wbt_rq_qos(q)) { 520 + ret = -EINVAL; 521 + goto out; 522 + } 595 523 596 - return sysfs_emit(page, "%llu\n", 597 - div_u64(wbt_get_min_lat(disk->queue), 1000)); 524 + if (wbt_disabled(q)) { 525 + ret = sysfs_emit(page, "0\n"); 526 + goto out; 527 + } 528 + 529 + ret = sysfs_emit(page, "%llu\n", div_u64(wbt_get_min_lat(q), 1000)); 530 + out: 531 + mutex_unlock(&q->sysfs_lock); 532 + return ret; 598 533 } 599 534 600 535 static ssize_t queue_wb_lat_store(struct gendisk *disk, const char *page, ··· 614 529 struct rq_qos *rqos; 615 530 ssize_t ret; 616 531 s64 val; 532 + unsigned int memflags; 617 533 618 534 ret = queue_var_store64(&val, page); 619 535 if (ret < 0) ··· 622 536 if (val < -1) 623 537 return -EINVAL; 624 538 539 + mutex_lock(&q->sysfs_lock); 540 + memflags = blk_mq_freeze_queue(q); 541 + 625 542 rqos = wbt_rq_qos(q); 626 543 if (!rqos) { 627 544 ret = wbt_init(disk); 628 545 if (ret) 629 - return ret; 546 + goto out; 630 547 } 631 548 549 + ret = count; 632 550 if (val == -1) 633 551 val = wbt_default_latency_nsec(q); 634 552 else if (val >= 0) 635 553 val *= 1000ULL; 636 554 637 555 if (wbt_get_min_lat(q) == val) 638 - return count; 556 + goto out; 639 557 640 558 /* 641 559 * Ensure that the queue is idled, in case the latency update ··· 651 561 wbt_set_min_lat(q, val); 652 562 653 563 blk_mq_unquiesce_queue(q); 564 + out: 565 + blk_mq_unfreeze_queue(q, memflags); 566 + mutex_unlock(&q->sysfs_lock); 654 567 655 - return count; 568 + return ret; 656 569 } 657 570 658 571 QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec"); ··· 777 684 { 778 685 struct queue_sysfs_entry *entry = to_queue(attr); 779 686 struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); 780 - ssize_t res; 781 687 782 688 if (!entry->show && !entry->show_limit) 783 689 return -EIO; 784 690 785 691 if (entry->show_limit) { 692 + ssize_t res; 693 + 786 694 mutex_lock(&disk->queue->limits_lock); 787 695 res = entry->show_limit(disk, page); 788 696 mutex_unlock(&disk->queue->limits_lock); 789 697 return res; 790 698 } 791 699 792 - mutex_lock(&disk->queue->sysfs_lock); 793 - res = entry->show(disk, page); 794 - mutex_unlock(&disk->queue->sysfs_lock); 795 - return res; 700 + return entry->show(disk, page); 796 701 } 797 702 798 703 static ssize_t ··· 800 709 struct queue_sysfs_entry *entry = to_queue(attr); 801 710 struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); 802 711 struct request_queue *q = disk->queue; 803 - unsigned int memflags; 804 - ssize_t res; 805 712 806 713 if (!entry->store_limit && !entry->store) 807 714 return -EIO; 808 715 809 - /* 810 - * If the attribute needs to load a module, do it before freezing the 811 - * queue to ensure that the module file can be read when the request 812 - * queue is the one for the device storing the module file. 813 - */ 814 - if (entry->load_module) 815 - entry->load_module(disk, page, length); 816 - 817 716 if (entry->store_limit) { 717 + ssize_t res; 718 + 818 719 struct queue_limits lim = queue_limits_start_update(q); 819 720 820 721 res = entry->store_limit(disk, page, length, &lim); ··· 821 738 return length; 822 739 } 823 740 824 - mutex_lock(&q->sysfs_lock); 825 - memflags = blk_mq_freeze_queue(q); 826 - res = entry->store(disk, page, length); 827 - blk_mq_unfreeze_queue(q, memflags); 828 - mutex_unlock(&q->sysfs_lock); 829 - return res; 741 + return entry->store(disk, page, length); 830 742 } 831 743 832 744 static const struct sysfs_ops queue_sysfs_ops = {
+18 -2
block/elevator.c
··· 723 723 { 724 724 char elevator_name[ELV_NAME_MAX]; 725 725 int ret; 726 + unsigned int memflags; 727 + struct request_queue *q = disk->queue; 726 728 729 + /* 730 + * If the attribute needs to load a module, do it before freezing the 731 + * queue to ensure that the module file can be read when the request 732 + * queue is the one for the device storing the module file. 733 + */ 734 + elv_iosched_load_module(disk, buf, count); 727 735 strscpy(elevator_name, buf, sizeof(elevator_name)); 728 - ret = elevator_change(disk->queue, strstrip(elevator_name)); 736 + 737 + mutex_lock(&q->sysfs_lock); 738 + memflags = blk_mq_freeze_queue(q); 739 + ret = elevator_change(q, strstrip(elevator_name)); 729 740 if (!ret) 730 - return count; 741 + ret = count; 742 + blk_mq_unfreeze_queue(q, memflags); 743 + mutex_unlock(&q->sysfs_lock); 731 744 return ret; 732 745 } 733 746 ··· 751 738 struct elevator_type *cur = NULL, *e; 752 739 int len = 0; 753 740 741 + mutex_lock(&q->sysfs_lock); 754 742 if (!q->elevator) { 755 743 len += sprintf(name+len, "[none] "); 756 744 } else { ··· 769 755 spin_unlock(&elv_list_lock); 770 756 771 757 len += sprintf(name+len, "\n"); 758 + mutex_unlock(&q->sysfs_lock); 759 + 772 760 return len; 773 761 } 774 762