18324aa91SJens Axboe /* 28324aa91SJens Axboe * Functions related to sysfs handling 38324aa91SJens Axboe */ 48324aa91SJens Axboe #include <linux/kernel.h> 55a0e3ad6STejun Heo #include <linux/slab.h> 68324aa91SJens Axboe #include <linux/module.h> 78324aa91SJens Axboe #include <linux/bio.h> 88324aa91SJens Axboe #include <linux/blkdev.h> 98324aa91SJens Axboe #include <linux/blktrace_api.h> 10320ae51fSJens Axboe #include <linux/blk-mq.h> 118324aa91SJens Axboe 128324aa91SJens Axboe #include "blk.h" 135efd6113STejun Heo #include "blk-cgroup.h" 14*3edcc0ceSMing Lei #include "blk-mq.h" 158324aa91SJens Axboe 168324aa91SJens Axboe struct queue_sysfs_entry { 178324aa91SJens Axboe struct attribute attr; 188324aa91SJens Axboe ssize_t (*show)(struct request_queue *, char *); 198324aa91SJens Axboe ssize_t (*store)(struct request_queue *, const char *, size_t); 208324aa91SJens Axboe }; 218324aa91SJens Axboe 228324aa91SJens Axboe static ssize_t 239cb308ceSXiaotian Feng queue_var_show(unsigned long var, char *page) 248324aa91SJens Axboe { 259cb308ceSXiaotian Feng return sprintf(page, "%lu\n", var); 268324aa91SJens Axboe } 278324aa91SJens Axboe 288324aa91SJens Axboe static ssize_t 298324aa91SJens Axboe queue_var_store(unsigned long *var, const char *page, size_t count) 308324aa91SJens Axboe { 31b1f3b64dSDave Reisner int err; 32b1f3b64dSDave Reisner unsigned long v; 338324aa91SJens Axboe 34ed751e68SJingoo Han err = kstrtoul(page, 10, &v); 35b1f3b64dSDave Reisner if (err || v > UINT_MAX) 36b1f3b64dSDave Reisner return -EINVAL; 37b1f3b64dSDave Reisner 38b1f3b64dSDave Reisner *var = v; 39b1f3b64dSDave Reisner 408324aa91SJens Axboe return count; 418324aa91SJens Axboe } 428324aa91SJens Axboe 438324aa91SJens Axboe static ssize_t queue_requests_show(struct request_queue *q, char *page) 448324aa91SJens Axboe { 458324aa91SJens Axboe return queue_var_show(q->nr_requests, (page)); 468324aa91SJens Axboe } 478324aa91SJens Axboe 488324aa91SJens Axboe static ssize_t 498324aa91SJens Axboe queue_requests_store(struct request_queue *q, const char *page, size_t count) 508324aa91SJens Axboe { 51a051661cSTejun Heo struct request_list *rl; 528324aa91SJens Axboe unsigned long nr; 53b8a9ae77SJens Axboe int ret; 54b8a9ae77SJens Axboe 55b8a9ae77SJens Axboe if (!q->request_fn) 56b8a9ae77SJens Axboe return -EINVAL; 57b8a9ae77SJens Axboe 58b8a9ae77SJens Axboe ret = queue_var_store(&nr, page, count); 59b1f3b64dSDave Reisner if (ret < 0) 60b1f3b64dSDave Reisner return ret; 61b1f3b64dSDave Reisner 628324aa91SJens Axboe if (nr < BLKDEV_MIN_RQ) 638324aa91SJens Axboe nr = BLKDEV_MIN_RQ; 648324aa91SJens Axboe 658324aa91SJens Axboe spin_lock_irq(q->queue_lock); 668324aa91SJens Axboe q->nr_requests = nr; 678324aa91SJens Axboe blk_queue_congestion_threshold(q); 688324aa91SJens Axboe 69a051661cSTejun Heo /* congestion isn't cgroup aware and follows root blkcg for now */ 70a051661cSTejun Heo rl = &q->root_rl; 71a051661cSTejun Heo 721faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q)) 731faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_SYNC); 741faa16d2SJens Axboe else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q)) 751faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_SYNC); 768324aa91SJens Axboe 771faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q)) 781faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_ASYNC); 791faa16d2SJens Axboe else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q)) 801faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_ASYNC); 818324aa91SJens Axboe 82a051661cSTejun Heo blk_queue_for_each_rl(rl, q) { 831faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= q->nr_requests) { 845b788ce3STejun Heo blk_set_rl_full(rl, BLK_RW_SYNC); 8560735b63STao Ma } else { 865b788ce3STejun Heo blk_clear_rl_full(rl, BLK_RW_SYNC); 871faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_SYNC]); 888324aa91SJens Axboe } 898324aa91SJens Axboe 901faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) { 915b788ce3STejun Heo blk_set_rl_full(rl, BLK_RW_ASYNC); 9260735b63STao Ma } else { 935b788ce3STejun Heo blk_clear_rl_full(rl, BLK_RW_ASYNC); 941faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_ASYNC]); 958324aa91SJens Axboe } 96a051661cSTejun Heo } 97a051661cSTejun Heo 988324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 998324aa91SJens Axboe return ret; 1008324aa91SJens Axboe } 1018324aa91SJens Axboe 1028324aa91SJens Axboe static ssize_t queue_ra_show(struct request_queue *q, char *page) 1038324aa91SJens Axboe { 1049cb308ceSXiaotian Feng unsigned long ra_kb = q->backing_dev_info.ra_pages << 1059cb308ceSXiaotian Feng (PAGE_CACHE_SHIFT - 10); 1068324aa91SJens Axboe 1078324aa91SJens Axboe return queue_var_show(ra_kb, (page)); 1088324aa91SJens Axboe } 1098324aa91SJens Axboe 1108324aa91SJens Axboe static ssize_t 1118324aa91SJens Axboe queue_ra_store(struct request_queue *q, const char *page, size_t count) 1128324aa91SJens Axboe { 1138324aa91SJens Axboe unsigned long ra_kb; 1148324aa91SJens Axboe ssize_t ret = queue_var_store(&ra_kb, page, count); 1158324aa91SJens Axboe 116b1f3b64dSDave Reisner if (ret < 0) 117b1f3b64dSDave Reisner return ret; 118b1f3b64dSDave Reisner 1198324aa91SJens Axboe q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); 1208324aa91SJens Axboe 1218324aa91SJens Axboe return ret; 1228324aa91SJens Axboe } 1238324aa91SJens Axboe 1248324aa91SJens Axboe static ssize_t queue_max_sectors_show(struct request_queue *q, char *page) 1258324aa91SJens Axboe { 126ae03bf63SMartin K. Petersen int max_sectors_kb = queue_max_sectors(q) >> 1; 1278324aa91SJens Axboe 1288324aa91SJens Axboe return queue_var_show(max_sectors_kb, (page)); 1298324aa91SJens Axboe } 1308324aa91SJens Axboe 131c77a5710SMartin K. Petersen static ssize_t queue_max_segments_show(struct request_queue *q, char *page) 132c77a5710SMartin K. Petersen { 133c77a5710SMartin K. Petersen return queue_var_show(queue_max_segments(q), (page)); 134c77a5710SMartin K. Petersen } 135c77a5710SMartin K. Petersen 13613f05c8dSMartin K. Petersen static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *page) 13713f05c8dSMartin K. Petersen { 13813f05c8dSMartin K. Petersen return queue_var_show(q->limits.max_integrity_segments, (page)); 13913f05c8dSMartin K. Petersen } 14013f05c8dSMartin K. Petersen 141c77a5710SMartin K. Petersen static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) 142c77a5710SMartin K. Petersen { 143e692cb66SMartin K. Petersen if (blk_queue_cluster(q)) 144c77a5710SMartin K. Petersen return queue_var_show(queue_max_segment_size(q), (page)); 145c77a5710SMartin K. Petersen 146c77a5710SMartin K. Petersen return queue_var_show(PAGE_CACHE_SIZE, (page)); 147c77a5710SMartin K. Petersen } 148c77a5710SMartin K. Petersen 149e1defc4fSMartin K. Petersen static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) 150e68b903cSMartin K. Petersen { 151e1defc4fSMartin K. Petersen return queue_var_show(queue_logical_block_size(q), page); 152e68b903cSMartin K. Petersen } 153e68b903cSMartin K. Petersen 154c72758f3SMartin K. Petersen static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page) 155c72758f3SMartin K. Petersen { 156c72758f3SMartin K. Petersen return queue_var_show(queue_physical_block_size(q), page); 157c72758f3SMartin K. Petersen } 158c72758f3SMartin K. Petersen 159c72758f3SMartin K. Petersen static ssize_t queue_io_min_show(struct request_queue *q, char *page) 160c72758f3SMartin K. Petersen { 161c72758f3SMartin K. Petersen return queue_var_show(queue_io_min(q), page); 162c72758f3SMartin K. Petersen } 163c72758f3SMartin K. Petersen 164c72758f3SMartin K. Petersen static ssize_t queue_io_opt_show(struct request_queue *q, char *page) 165c72758f3SMartin K. Petersen { 166c72758f3SMartin K. Petersen return queue_var_show(queue_io_opt(q), page); 1678324aa91SJens Axboe } 1688324aa91SJens Axboe 16986b37281SMartin K. Petersen static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page) 17086b37281SMartin K. Petersen { 17186b37281SMartin K. Petersen return queue_var_show(q->limits.discard_granularity, page); 17286b37281SMartin K. Petersen } 17386b37281SMartin K. Petersen 17486b37281SMartin K. Petersen static ssize_t queue_discard_max_show(struct request_queue *q, char *page) 17586b37281SMartin K. Petersen { 176a934a00aSMartin K. Petersen return sprintf(page, "%llu\n", 177a934a00aSMartin K. Petersen (unsigned long long)q->limits.max_discard_sectors << 9); 17886b37281SMartin K. Petersen } 17986b37281SMartin K. Petersen 18098262f27SMartin K. Petersen static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) 18198262f27SMartin K. Petersen { 18298262f27SMartin K. Petersen return queue_var_show(queue_discard_zeroes_data(q), page); 18398262f27SMartin K. Petersen } 18498262f27SMartin K. Petersen 1854363ac7cSMartin K. Petersen static ssize_t queue_write_same_max_show(struct request_queue *q, char *page) 1864363ac7cSMartin K. Petersen { 1874363ac7cSMartin K. Petersen return sprintf(page, "%llu\n", 1884363ac7cSMartin K. Petersen (unsigned long long)q->limits.max_write_same_sectors << 9); 1894363ac7cSMartin K. Petersen } 1904363ac7cSMartin K. Petersen 1914363ac7cSMartin K. Petersen 1928324aa91SJens Axboe static ssize_t 1938324aa91SJens Axboe queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) 1948324aa91SJens Axboe { 1958324aa91SJens Axboe unsigned long max_sectors_kb, 196ae03bf63SMartin K. Petersen max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1, 1978324aa91SJens Axboe page_kb = 1 << (PAGE_CACHE_SHIFT - 10); 1988324aa91SJens Axboe ssize_t ret = queue_var_store(&max_sectors_kb, page, count); 1998324aa91SJens Axboe 200b1f3b64dSDave Reisner if (ret < 0) 201b1f3b64dSDave Reisner return ret; 202b1f3b64dSDave Reisner 2038324aa91SJens Axboe if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb) 2048324aa91SJens Axboe return -EINVAL; 2057c239517SWu Fengguang 2068324aa91SJens Axboe spin_lock_irq(q->queue_lock); 207c295fc05SNikanth Karthikesan q->limits.max_sectors = max_sectors_kb << 1; 2088324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 2098324aa91SJens Axboe 2108324aa91SJens Axboe return ret; 2118324aa91SJens Axboe } 2128324aa91SJens Axboe 2138324aa91SJens Axboe static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page) 2148324aa91SJens Axboe { 215ae03bf63SMartin K. Petersen int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1; 2168324aa91SJens Axboe 2178324aa91SJens Axboe return queue_var_show(max_hw_sectors_kb, (page)); 2188324aa91SJens Axboe } 2198324aa91SJens Axboe 220956bcb7cSJens Axboe #define QUEUE_SYSFS_BIT_FNS(name, flag, neg) \ 221956bcb7cSJens Axboe static ssize_t \ 222956bcb7cSJens Axboe queue_show_##name(struct request_queue *q, char *page) \ 223956bcb7cSJens Axboe { \ 224956bcb7cSJens Axboe int bit; \ 225956bcb7cSJens Axboe bit = test_bit(QUEUE_FLAG_##flag, &q->queue_flags); \ 226956bcb7cSJens Axboe return queue_var_show(neg ? !bit : bit, page); \ 227956bcb7cSJens Axboe } \ 228956bcb7cSJens Axboe static ssize_t \ 229956bcb7cSJens Axboe queue_store_##name(struct request_queue *q, const char *page, size_t count) \ 230956bcb7cSJens Axboe { \ 231956bcb7cSJens Axboe unsigned long val; \ 232956bcb7cSJens Axboe ssize_t ret; \ 233956bcb7cSJens Axboe ret = queue_var_store(&val, page, count); \ 234c678ef52SArnd Bergmann if (ret < 0) \ 235c678ef52SArnd Bergmann return ret; \ 236956bcb7cSJens Axboe if (neg) \ 237956bcb7cSJens Axboe val = !val; \ 238956bcb7cSJens Axboe \ 239956bcb7cSJens Axboe spin_lock_irq(q->queue_lock); \ 240956bcb7cSJens Axboe if (val) \ 241956bcb7cSJens Axboe queue_flag_set(QUEUE_FLAG_##flag, q); \ 242956bcb7cSJens Axboe else \ 243956bcb7cSJens Axboe queue_flag_clear(QUEUE_FLAG_##flag, q); \ 244956bcb7cSJens Axboe spin_unlock_irq(q->queue_lock); \ 245956bcb7cSJens Axboe return ret; \ 2461308835fSBartlomiej Zolnierkiewicz } 2471308835fSBartlomiej Zolnierkiewicz 248956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1); 249956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0); 250956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0); 251956bcb7cSJens Axboe #undef QUEUE_SYSFS_BIT_FNS 2521308835fSBartlomiej Zolnierkiewicz 253ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_show(struct request_queue *q, char *page) 254ac9fafa1SAlan D. Brunelle { 255488991e2SAlan D. Brunelle return queue_var_show((blk_queue_nomerges(q) << 1) | 256488991e2SAlan D. Brunelle blk_queue_noxmerges(q), page); 257ac9fafa1SAlan D. Brunelle } 258ac9fafa1SAlan D. Brunelle 259ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, 260ac9fafa1SAlan D. Brunelle size_t count) 261ac9fafa1SAlan D. Brunelle { 262ac9fafa1SAlan D. Brunelle unsigned long nm; 263ac9fafa1SAlan D. Brunelle ssize_t ret = queue_var_store(&nm, page, count); 264ac9fafa1SAlan D. Brunelle 265b1f3b64dSDave Reisner if (ret < 0) 266b1f3b64dSDave Reisner return ret; 267b1f3b64dSDave Reisner 268bf0f9702SJens Axboe spin_lock_irq(q->queue_lock); 269bf0f9702SJens Axboe queue_flag_clear(QUEUE_FLAG_NOMERGES, q); 270488991e2SAlan D. Brunelle queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); 271488991e2SAlan D. Brunelle if (nm == 2) 272488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOMERGES, q); 273488991e2SAlan D. Brunelle else if (nm) 274488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOXMERGES, q); 275bf0f9702SJens Axboe spin_unlock_irq(q->queue_lock); 2761308835fSBartlomiej Zolnierkiewicz 277ac9fafa1SAlan D. Brunelle return ret; 278ac9fafa1SAlan D. Brunelle } 279ac9fafa1SAlan D. Brunelle 280c7c22e4dSJens Axboe static ssize_t queue_rq_affinity_show(struct request_queue *q, char *page) 281c7c22e4dSJens Axboe { 2829cb308ceSXiaotian Feng bool set = test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags); 2835757a6d7SDan Williams bool force = test_bit(QUEUE_FLAG_SAME_FORCE, &q->queue_flags); 284c7c22e4dSJens Axboe 2855757a6d7SDan Williams return queue_var_show(set << force, page); 286c7c22e4dSJens Axboe } 287c7c22e4dSJens Axboe 288c7c22e4dSJens Axboe static ssize_t 289c7c22e4dSJens Axboe queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count) 290c7c22e4dSJens Axboe { 291c7c22e4dSJens Axboe ssize_t ret = -EINVAL; 2920a06ff06SChristoph Hellwig #ifdef CONFIG_SMP 293c7c22e4dSJens Axboe unsigned long val; 294c7c22e4dSJens Axboe 295c7c22e4dSJens Axboe ret = queue_var_store(&val, page, count); 296b1f3b64dSDave Reisner if (ret < 0) 297b1f3b64dSDave Reisner return ret; 298b1f3b64dSDave Reisner 299c7c22e4dSJens Axboe spin_lock_irq(q->queue_lock); 300e8037d49SEric Seppanen if (val == 2) { 301c7c22e4dSJens Axboe queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 3025757a6d7SDan Williams queue_flag_set(QUEUE_FLAG_SAME_FORCE, q); 303e8037d49SEric Seppanen } else if (val == 1) { 304e8037d49SEric Seppanen queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 305e8037d49SEric Seppanen queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q); 306e8037d49SEric Seppanen } else if (val == 0) { 307c7c22e4dSJens Axboe queue_flag_clear(QUEUE_FLAG_SAME_COMP, q); 3085757a6d7SDan Williams queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q); 3095757a6d7SDan Williams } 310c7c22e4dSJens Axboe spin_unlock_irq(q->queue_lock); 311c7c22e4dSJens Axboe #endif 312c7c22e4dSJens Axboe return ret; 313c7c22e4dSJens Axboe } 3148324aa91SJens Axboe 3158324aa91SJens Axboe static struct queue_sysfs_entry queue_requests_entry = { 3168324aa91SJens Axboe .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 3178324aa91SJens Axboe .show = queue_requests_show, 3188324aa91SJens Axboe .store = queue_requests_store, 3198324aa91SJens Axboe }; 3208324aa91SJens Axboe 3218324aa91SJens Axboe static struct queue_sysfs_entry queue_ra_entry = { 3228324aa91SJens Axboe .attr = {.name = "read_ahead_kb", .mode = S_IRUGO | S_IWUSR }, 3238324aa91SJens Axboe .show = queue_ra_show, 3248324aa91SJens Axboe .store = queue_ra_store, 3258324aa91SJens Axboe }; 3268324aa91SJens Axboe 3278324aa91SJens Axboe static struct queue_sysfs_entry queue_max_sectors_entry = { 3288324aa91SJens Axboe .attr = {.name = "max_sectors_kb", .mode = S_IRUGO | S_IWUSR }, 3298324aa91SJens Axboe .show = queue_max_sectors_show, 3308324aa91SJens Axboe .store = queue_max_sectors_store, 3318324aa91SJens Axboe }; 3328324aa91SJens Axboe 3338324aa91SJens Axboe static struct queue_sysfs_entry queue_max_hw_sectors_entry = { 3348324aa91SJens Axboe .attr = {.name = "max_hw_sectors_kb", .mode = S_IRUGO }, 3358324aa91SJens Axboe .show = queue_max_hw_sectors_show, 3368324aa91SJens Axboe }; 3378324aa91SJens Axboe 338c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segments_entry = { 339c77a5710SMartin K. Petersen .attr = {.name = "max_segments", .mode = S_IRUGO }, 340c77a5710SMartin K. Petersen .show = queue_max_segments_show, 341c77a5710SMartin K. Petersen }; 342c77a5710SMartin K. Petersen 34313f05c8dSMartin K. Petersen static struct queue_sysfs_entry queue_max_integrity_segments_entry = { 34413f05c8dSMartin K. Petersen .attr = {.name = "max_integrity_segments", .mode = S_IRUGO }, 34513f05c8dSMartin K. Petersen .show = queue_max_integrity_segments_show, 34613f05c8dSMartin K. Petersen }; 34713f05c8dSMartin K. Petersen 348c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segment_size_entry = { 349c77a5710SMartin K. Petersen .attr = {.name = "max_segment_size", .mode = S_IRUGO }, 350c77a5710SMartin K. Petersen .show = queue_max_segment_size_show, 351c77a5710SMartin K. Petersen }; 352c77a5710SMartin K. Petersen 3538324aa91SJens Axboe static struct queue_sysfs_entry queue_iosched_entry = { 3548324aa91SJens Axboe .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, 3558324aa91SJens Axboe .show = elv_iosched_show, 3568324aa91SJens Axboe .store = elv_iosched_store, 3578324aa91SJens Axboe }; 3588324aa91SJens Axboe 359e68b903cSMartin K. Petersen static struct queue_sysfs_entry queue_hw_sector_size_entry = { 360e68b903cSMartin K. Petersen .attr = {.name = "hw_sector_size", .mode = S_IRUGO }, 361e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 362e1defc4fSMartin K. Petersen }; 363e1defc4fSMartin K. Petersen 364e1defc4fSMartin K. Petersen static struct queue_sysfs_entry queue_logical_block_size_entry = { 365e1defc4fSMartin K. Petersen .attr = {.name = "logical_block_size", .mode = S_IRUGO }, 366e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 367e68b903cSMartin K. Petersen }; 368e68b903cSMartin K. Petersen 369c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_physical_block_size_entry = { 370c72758f3SMartin K. Petersen .attr = {.name = "physical_block_size", .mode = S_IRUGO }, 371c72758f3SMartin K. Petersen .show = queue_physical_block_size_show, 372c72758f3SMartin K. Petersen }; 373c72758f3SMartin K. Petersen 374c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_min_entry = { 375c72758f3SMartin K. Petersen .attr = {.name = "minimum_io_size", .mode = S_IRUGO }, 376c72758f3SMartin K. Petersen .show = queue_io_min_show, 377c72758f3SMartin K. Petersen }; 378c72758f3SMartin K. Petersen 379c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_opt_entry = { 380c72758f3SMartin K. Petersen .attr = {.name = "optimal_io_size", .mode = S_IRUGO }, 381c72758f3SMartin K. Petersen .show = queue_io_opt_show, 3828324aa91SJens Axboe }; 3838324aa91SJens Axboe 38486b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_granularity_entry = { 38586b37281SMartin K. Petersen .attr = {.name = "discard_granularity", .mode = S_IRUGO }, 38686b37281SMartin K. Petersen .show = queue_discard_granularity_show, 38786b37281SMartin K. Petersen }; 38886b37281SMartin K. Petersen 38986b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_max_entry = { 39086b37281SMartin K. Petersen .attr = {.name = "discard_max_bytes", .mode = S_IRUGO }, 39186b37281SMartin K. Petersen .show = queue_discard_max_show, 39286b37281SMartin K. Petersen }; 39386b37281SMartin K. Petersen 39498262f27SMartin K. Petersen static struct queue_sysfs_entry queue_discard_zeroes_data_entry = { 39598262f27SMartin K. Petersen .attr = {.name = "discard_zeroes_data", .mode = S_IRUGO }, 39698262f27SMartin K. Petersen .show = queue_discard_zeroes_data_show, 39798262f27SMartin K. Petersen }; 39898262f27SMartin K. Petersen 3994363ac7cSMartin K. Petersen static struct queue_sysfs_entry queue_write_same_max_entry = { 4004363ac7cSMartin K. Petersen .attr = {.name = "write_same_max_bytes", .mode = S_IRUGO }, 4014363ac7cSMartin K. Petersen .show = queue_write_same_max_show, 4024363ac7cSMartin K. Petersen }; 4034363ac7cSMartin K. Petersen 4041308835fSBartlomiej Zolnierkiewicz static struct queue_sysfs_entry queue_nonrot_entry = { 4051308835fSBartlomiej Zolnierkiewicz .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, 406956bcb7cSJens Axboe .show = queue_show_nonrot, 407956bcb7cSJens Axboe .store = queue_store_nonrot, 4081308835fSBartlomiej Zolnierkiewicz }; 4091308835fSBartlomiej Zolnierkiewicz 410ac9fafa1SAlan D. Brunelle static struct queue_sysfs_entry queue_nomerges_entry = { 411ac9fafa1SAlan D. Brunelle .attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR }, 412ac9fafa1SAlan D. Brunelle .show = queue_nomerges_show, 413ac9fafa1SAlan D. Brunelle .store = queue_nomerges_store, 414ac9fafa1SAlan D. Brunelle }; 415ac9fafa1SAlan D. Brunelle 416c7c22e4dSJens Axboe static struct queue_sysfs_entry queue_rq_affinity_entry = { 417c7c22e4dSJens Axboe .attr = {.name = "rq_affinity", .mode = S_IRUGO | S_IWUSR }, 418c7c22e4dSJens Axboe .show = queue_rq_affinity_show, 419c7c22e4dSJens Axboe .store = queue_rq_affinity_store, 420c7c22e4dSJens Axboe }; 421c7c22e4dSJens Axboe 422bc58ba94SJens Axboe static struct queue_sysfs_entry queue_iostats_entry = { 423bc58ba94SJens Axboe .attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR }, 424956bcb7cSJens Axboe .show = queue_show_iostats, 425956bcb7cSJens Axboe .store = queue_store_iostats, 426bc58ba94SJens Axboe }; 427bc58ba94SJens Axboe 428e2e1a148SJens Axboe static struct queue_sysfs_entry queue_random_entry = { 429e2e1a148SJens Axboe .attr = {.name = "add_random", .mode = S_IRUGO | S_IWUSR }, 430956bcb7cSJens Axboe .show = queue_show_random, 431956bcb7cSJens Axboe .store = queue_store_random, 432e2e1a148SJens Axboe }; 433e2e1a148SJens Axboe 4348324aa91SJens Axboe static struct attribute *default_attrs[] = { 4358324aa91SJens Axboe &queue_requests_entry.attr, 4368324aa91SJens Axboe &queue_ra_entry.attr, 4378324aa91SJens Axboe &queue_max_hw_sectors_entry.attr, 4388324aa91SJens Axboe &queue_max_sectors_entry.attr, 439c77a5710SMartin K. Petersen &queue_max_segments_entry.attr, 44013f05c8dSMartin K. Petersen &queue_max_integrity_segments_entry.attr, 441c77a5710SMartin K. Petersen &queue_max_segment_size_entry.attr, 4428324aa91SJens Axboe &queue_iosched_entry.attr, 443e68b903cSMartin K. Petersen &queue_hw_sector_size_entry.attr, 444e1defc4fSMartin K. Petersen &queue_logical_block_size_entry.attr, 445c72758f3SMartin K. Petersen &queue_physical_block_size_entry.attr, 446c72758f3SMartin K. Petersen &queue_io_min_entry.attr, 447c72758f3SMartin K. Petersen &queue_io_opt_entry.attr, 44886b37281SMartin K. Petersen &queue_discard_granularity_entry.attr, 44986b37281SMartin K. Petersen &queue_discard_max_entry.attr, 45098262f27SMartin K. Petersen &queue_discard_zeroes_data_entry.attr, 4514363ac7cSMartin K. Petersen &queue_write_same_max_entry.attr, 4521308835fSBartlomiej Zolnierkiewicz &queue_nonrot_entry.attr, 453ac9fafa1SAlan D. Brunelle &queue_nomerges_entry.attr, 454c7c22e4dSJens Axboe &queue_rq_affinity_entry.attr, 455bc58ba94SJens Axboe &queue_iostats_entry.attr, 456e2e1a148SJens Axboe &queue_random_entry.attr, 4578324aa91SJens Axboe NULL, 4588324aa91SJens Axboe }; 4598324aa91SJens Axboe 4608324aa91SJens Axboe #define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr) 4618324aa91SJens Axboe 4628324aa91SJens Axboe static ssize_t 4638324aa91SJens Axboe queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) 4648324aa91SJens Axboe { 4658324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4668324aa91SJens Axboe struct request_queue *q = 4678324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 4688324aa91SJens Axboe ssize_t res; 4698324aa91SJens Axboe 4708324aa91SJens Axboe if (!entry->show) 4718324aa91SJens Axboe return -EIO; 4728324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4733f3299d5SBart Van Assche if (blk_queue_dying(q)) { 4748324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4758324aa91SJens Axboe return -ENOENT; 4768324aa91SJens Axboe } 4778324aa91SJens Axboe res = entry->show(q, page); 4788324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4798324aa91SJens Axboe return res; 4808324aa91SJens Axboe } 4818324aa91SJens Axboe 4828324aa91SJens Axboe static ssize_t 4838324aa91SJens Axboe queue_attr_store(struct kobject *kobj, struct attribute *attr, 4848324aa91SJens Axboe const char *page, size_t length) 4858324aa91SJens Axboe { 4868324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4876728cb0eSJens Axboe struct request_queue *q; 4888324aa91SJens Axboe ssize_t res; 4898324aa91SJens Axboe 4908324aa91SJens Axboe if (!entry->store) 4918324aa91SJens Axboe return -EIO; 4926728cb0eSJens Axboe 4936728cb0eSJens Axboe q = container_of(kobj, struct request_queue, kobj); 4948324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4953f3299d5SBart Van Assche if (blk_queue_dying(q)) { 4968324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4978324aa91SJens Axboe return -ENOENT; 4988324aa91SJens Axboe } 4998324aa91SJens Axboe res = entry->store(q, page, length); 5008324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 5018324aa91SJens Axboe return res; 5028324aa91SJens Axboe } 5038324aa91SJens Axboe 504548bc8e1STejun Heo static void blk_free_queue_rcu(struct rcu_head *rcu_head) 505548bc8e1STejun Heo { 506548bc8e1STejun Heo struct request_queue *q = container_of(rcu_head, struct request_queue, 507548bc8e1STejun Heo rcu_head); 508548bc8e1STejun Heo kmem_cache_free(blk_requestq_cachep, q); 509548bc8e1STejun Heo } 510548bc8e1STejun Heo 5118324aa91SJens Axboe /** 512499337bbSAndrew Morton * blk_release_queue: - release a &struct request_queue when it is no longer needed 513499337bbSAndrew Morton * @kobj: the kobj belonging to the request queue to be released 5148324aa91SJens Axboe * 5158324aa91SJens Axboe * Description: 516499337bbSAndrew Morton * blk_release_queue is the pair to blk_init_queue() or 5178324aa91SJens Axboe * blk_queue_make_request(). It should be called when a request queue is 5188324aa91SJens Axboe * being released; typically when a block device is being de-registered. 5198324aa91SJens Axboe * Currently, its primary task it to free all the &struct request 5208324aa91SJens Axboe * structures that were allocated to the queue and the queue itself. 5218324aa91SJens Axboe * 5228324aa91SJens Axboe * Caveat: 5238324aa91SJens Axboe * Hopefully the low level driver will have finished any 5248324aa91SJens Axboe * outstanding requests first... 5258324aa91SJens Axboe **/ 5268324aa91SJens Axboe static void blk_release_queue(struct kobject *kobj) 5278324aa91SJens Axboe { 5288324aa91SJens Axboe struct request_queue *q = 5298324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 5308324aa91SJens Axboe 5318324aa91SJens Axboe blk_sync_queue(q); 5328324aa91SJens Axboe 533e8989faeSTejun Heo blkcg_exit_queue(q); 534e8989faeSTejun Heo 5357e5a8794STejun Heo if (q->elevator) { 5367e5a8794STejun Heo spin_lock_irq(q->queue_lock); 5377e5a8794STejun Heo ioc_clear_queue(q); 5387e5a8794STejun Heo spin_unlock_irq(q->queue_lock); 539777eb1bfSHannes Reinecke elevator_exit(q->elevator); 5407e5a8794STejun Heo } 541777eb1bfSHannes Reinecke 542a051661cSTejun Heo blk_exit_rl(&q->root_rl); 5438324aa91SJens Axboe 5448324aa91SJens Axboe if (q->queue_tags) 5458324aa91SJens Axboe __blk_queue_free_tags(q); 5468324aa91SJens Axboe 547320ae51fSJens Axboe percpu_counter_destroy(&q->mq_usage_counter); 548320ae51fSJens Axboe 549320ae51fSJens Axboe if (q->mq_ops) 550320ae51fSJens Axboe blk_mq_free_queue(q); 551320ae51fSJens Axboe 5528324aa91SJens Axboe blk_trace_shutdown(q); 5538324aa91SJens Axboe 5548324aa91SJens Axboe bdi_destroy(&q->backing_dev_info); 555a73f730dSTejun Heo 556a73f730dSTejun Heo ida_simple_remove(&blk_queue_ida, q->id); 557548bc8e1STejun Heo call_rcu(&q->rcu_head, blk_free_queue_rcu); 5588324aa91SJens Axboe } 5598324aa91SJens Axboe 56052cf25d0SEmese Revfy static const struct sysfs_ops queue_sysfs_ops = { 5618324aa91SJens Axboe .show = queue_attr_show, 5628324aa91SJens Axboe .store = queue_attr_store, 5638324aa91SJens Axboe }; 5648324aa91SJens Axboe 5658324aa91SJens Axboe struct kobj_type blk_queue_ktype = { 5668324aa91SJens Axboe .sysfs_ops = &queue_sysfs_ops, 5678324aa91SJens Axboe .default_attrs = default_attrs, 5688324aa91SJens Axboe .release = blk_release_queue, 5698324aa91SJens Axboe }; 5708324aa91SJens Axboe 5718324aa91SJens Axboe int blk_register_queue(struct gendisk *disk) 5728324aa91SJens Axboe { 5738324aa91SJens Axboe int ret; 5741d54ad6dSLi Zefan struct device *dev = disk_to_dev(disk); 5758324aa91SJens Axboe struct request_queue *q = disk->queue; 5768324aa91SJens Axboe 577fb199746SAkinobu Mita if (WARN_ON(!q)) 5788324aa91SJens Axboe return -ENXIO; 5798324aa91SJens Axboe 580749fefe6STejun Heo /* 581749fefe6STejun Heo * Initialization must be complete by now. Finish the initial 582749fefe6STejun Heo * bypass from queue allocation. 583749fefe6STejun Heo */ 584749fefe6STejun Heo blk_queue_bypass_end(q); 585320ae51fSJens Axboe queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q); 586749fefe6STejun Heo 5871d54ad6dSLi Zefan ret = blk_trace_init_sysfs(dev); 5881d54ad6dSLi Zefan if (ret) 5891d54ad6dSLi Zefan return ret; 5901d54ad6dSLi Zefan 591c9059598SLinus Torvalds ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); 592ed5302d3SLiu Yuan if (ret < 0) { 593ed5302d3SLiu Yuan blk_trace_remove_sysfs(dev); 5948324aa91SJens Axboe return ret; 595ed5302d3SLiu Yuan } 5968324aa91SJens Axboe 5978324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_ADD); 5988324aa91SJens Axboe 599320ae51fSJens Axboe if (q->mq_ops) 600320ae51fSJens Axboe blk_mq_register_disk(disk); 601320ae51fSJens Axboe 602cd43e26fSMartin K. Petersen if (!q->request_fn) 603cd43e26fSMartin K. Petersen return 0; 604cd43e26fSMartin K. Petersen 6058324aa91SJens Axboe ret = elv_register_queue(q); 6068324aa91SJens Axboe if (ret) { 6078324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 6088324aa91SJens Axboe kobject_del(&q->kobj); 60980656b67SLiu Yuan blk_trace_remove_sysfs(dev); 610c87ffbb8SXiaotian Feng kobject_put(&dev->kobj); 6118324aa91SJens Axboe return ret; 6128324aa91SJens Axboe } 6138324aa91SJens Axboe 6148324aa91SJens Axboe return 0; 6158324aa91SJens Axboe } 6168324aa91SJens Axboe 6178324aa91SJens Axboe void blk_unregister_queue(struct gendisk *disk) 6188324aa91SJens Axboe { 6198324aa91SJens Axboe struct request_queue *q = disk->queue; 6208324aa91SJens Axboe 621fb199746SAkinobu Mita if (WARN_ON(!q)) 622fb199746SAkinobu Mita return; 623fb199746SAkinobu Mita 624320ae51fSJens Axboe if (q->mq_ops) 625320ae51fSJens Axboe blk_mq_unregister_disk(disk); 626320ae51fSJens Axboe 62748c0d4d4SZdenek Kabelac if (q->request_fn) 6288324aa91SJens Axboe elv_unregister_queue(q); 6298324aa91SJens Axboe 6308324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 6318324aa91SJens Axboe kobject_del(&q->kobj); 63248c0d4d4SZdenek Kabelac blk_trace_remove_sysfs(disk_to_dev(disk)); 633ed9e1982STejun Heo kobject_put(&disk_to_dev(disk)->kobj); 6348324aa91SJens Axboe } 635