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> 10*320ae51fSJens Axboe #include <linux/blk-mq.h> 118324aa91SJens Axboe 128324aa91SJens Axboe #include "blk.h" 135efd6113STejun Heo #include "blk-cgroup.h" 148324aa91SJens Axboe 158324aa91SJens Axboe struct queue_sysfs_entry { 168324aa91SJens Axboe struct attribute attr; 178324aa91SJens Axboe ssize_t (*show)(struct request_queue *, char *); 188324aa91SJens Axboe ssize_t (*store)(struct request_queue *, const char *, size_t); 198324aa91SJens Axboe }; 208324aa91SJens Axboe 218324aa91SJens Axboe static ssize_t 229cb308ceSXiaotian Feng queue_var_show(unsigned long var, char *page) 238324aa91SJens Axboe { 249cb308ceSXiaotian Feng return sprintf(page, "%lu\n", var); 258324aa91SJens Axboe } 268324aa91SJens Axboe 278324aa91SJens Axboe static ssize_t 288324aa91SJens Axboe queue_var_store(unsigned long *var, const char *page, size_t count) 298324aa91SJens Axboe { 30b1f3b64dSDave Reisner int err; 31b1f3b64dSDave Reisner unsigned long v; 328324aa91SJens Axboe 33ed751e68SJingoo Han err = kstrtoul(page, 10, &v); 34b1f3b64dSDave Reisner if (err || v > UINT_MAX) 35b1f3b64dSDave Reisner return -EINVAL; 36b1f3b64dSDave Reisner 37b1f3b64dSDave Reisner *var = v; 38b1f3b64dSDave Reisner 398324aa91SJens Axboe return count; 408324aa91SJens Axboe } 418324aa91SJens Axboe 428324aa91SJens Axboe static ssize_t queue_requests_show(struct request_queue *q, char *page) 438324aa91SJens Axboe { 448324aa91SJens Axboe return queue_var_show(q->nr_requests, (page)); 458324aa91SJens Axboe } 468324aa91SJens Axboe 478324aa91SJens Axboe static ssize_t 488324aa91SJens Axboe queue_requests_store(struct request_queue *q, const char *page, size_t count) 498324aa91SJens Axboe { 50a051661cSTejun Heo struct request_list *rl; 518324aa91SJens Axboe unsigned long nr; 52b8a9ae77SJens Axboe int ret; 53b8a9ae77SJens Axboe 54b8a9ae77SJens Axboe if (!q->request_fn) 55b8a9ae77SJens Axboe return -EINVAL; 56b8a9ae77SJens Axboe 57b8a9ae77SJens Axboe ret = queue_var_store(&nr, page, count); 58b1f3b64dSDave Reisner if (ret < 0) 59b1f3b64dSDave Reisner return ret; 60b1f3b64dSDave Reisner 618324aa91SJens Axboe if (nr < BLKDEV_MIN_RQ) 628324aa91SJens Axboe nr = BLKDEV_MIN_RQ; 638324aa91SJens Axboe 648324aa91SJens Axboe spin_lock_irq(q->queue_lock); 658324aa91SJens Axboe q->nr_requests = nr; 668324aa91SJens Axboe blk_queue_congestion_threshold(q); 678324aa91SJens Axboe 68a051661cSTejun Heo /* congestion isn't cgroup aware and follows root blkcg for now */ 69a051661cSTejun Heo rl = &q->root_rl; 70a051661cSTejun Heo 711faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q)) 721faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_SYNC); 731faa16d2SJens Axboe else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q)) 741faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_SYNC); 758324aa91SJens Axboe 761faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q)) 771faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_ASYNC); 781faa16d2SJens Axboe else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q)) 791faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_ASYNC); 808324aa91SJens Axboe 81a051661cSTejun Heo blk_queue_for_each_rl(rl, q) { 821faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= q->nr_requests) { 835b788ce3STejun Heo blk_set_rl_full(rl, BLK_RW_SYNC); 8460735b63STao Ma } else { 855b788ce3STejun Heo blk_clear_rl_full(rl, BLK_RW_SYNC); 861faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_SYNC]); 878324aa91SJens Axboe } 888324aa91SJens Axboe 891faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) { 905b788ce3STejun Heo blk_set_rl_full(rl, BLK_RW_ASYNC); 9160735b63STao Ma } else { 925b788ce3STejun Heo blk_clear_rl_full(rl, BLK_RW_ASYNC); 931faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_ASYNC]); 948324aa91SJens Axboe } 95a051661cSTejun Heo } 96a051661cSTejun Heo 978324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 988324aa91SJens Axboe return ret; 998324aa91SJens Axboe } 1008324aa91SJens Axboe 1018324aa91SJens Axboe static ssize_t queue_ra_show(struct request_queue *q, char *page) 1028324aa91SJens Axboe { 1039cb308ceSXiaotian Feng unsigned long ra_kb = q->backing_dev_info.ra_pages << 1049cb308ceSXiaotian Feng (PAGE_CACHE_SHIFT - 10); 1058324aa91SJens Axboe 1068324aa91SJens Axboe return queue_var_show(ra_kb, (page)); 1078324aa91SJens Axboe } 1088324aa91SJens Axboe 1098324aa91SJens Axboe static ssize_t 1108324aa91SJens Axboe queue_ra_store(struct request_queue *q, const char *page, size_t count) 1118324aa91SJens Axboe { 1128324aa91SJens Axboe unsigned long ra_kb; 1138324aa91SJens Axboe ssize_t ret = queue_var_store(&ra_kb, page, count); 1148324aa91SJens Axboe 115b1f3b64dSDave Reisner if (ret < 0) 116b1f3b64dSDave Reisner return ret; 117b1f3b64dSDave Reisner 1188324aa91SJens Axboe q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); 1198324aa91SJens Axboe 1208324aa91SJens Axboe return ret; 1218324aa91SJens Axboe } 1228324aa91SJens Axboe 1238324aa91SJens Axboe static ssize_t queue_max_sectors_show(struct request_queue *q, char *page) 1248324aa91SJens Axboe { 125ae03bf63SMartin K. Petersen int max_sectors_kb = queue_max_sectors(q) >> 1; 1268324aa91SJens Axboe 1278324aa91SJens Axboe return queue_var_show(max_sectors_kb, (page)); 1288324aa91SJens Axboe } 1298324aa91SJens Axboe 130c77a5710SMartin K. Petersen static ssize_t queue_max_segments_show(struct request_queue *q, char *page) 131c77a5710SMartin K. Petersen { 132c77a5710SMartin K. Petersen return queue_var_show(queue_max_segments(q), (page)); 133c77a5710SMartin K. Petersen } 134c77a5710SMartin K. Petersen 13513f05c8dSMartin K. Petersen static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *page) 13613f05c8dSMartin K. Petersen { 13713f05c8dSMartin K. Petersen return queue_var_show(q->limits.max_integrity_segments, (page)); 13813f05c8dSMartin K. Petersen } 13913f05c8dSMartin K. Petersen 140c77a5710SMartin K. Petersen static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) 141c77a5710SMartin K. Petersen { 142e692cb66SMartin K. Petersen if (blk_queue_cluster(q)) 143c77a5710SMartin K. Petersen return queue_var_show(queue_max_segment_size(q), (page)); 144c77a5710SMartin K. Petersen 145c77a5710SMartin K. Petersen return queue_var_show(PAGE_CACHE_SIZE, (page)); 146c77a5710SMartin K. Petersen } 147c77a5710SMartin K. Petersen 148e1defc4fSMartin K. Petersen static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) 149e68b903cSMartin K. Petersen { 150e1defc4fSMartin K. Petersen return queue_var_show(queue_logical_block_size(q), page); 151e68b903cSMartin K. Petersen } 152e68b903cSMartin K. Petersen 153c72758f3SMartin K. Petersen static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page) 154c72758f3SMartin K. Petersen { 155c72758f3SMartin K. Petersen return queue_var_show(queue_physical_block_size(q), page); 156c72758f3SMartin K. Petersen } 157c72758f3SMartin K. Petersen 158c72758f3SMartin K. Petersen static ssize_t queue_io_min_show(struct request_queue *q, char *page) 159c72758f3SMartin K. Petersen { 160c72758f3SMartin K. Petersen return queue_var_show(queue_io_min(q), page); 161c72758f3SMartin K. Petersen } 162c72758f3SMartin K. Petersen 163c72758f3SMartin K. Petersen static ssize_t queue_io_opt_show(struct request_queue *q, char *page) 164c72758f3SMartin K. Petersen { 165c72758f3SMartin K. Petersen return queue_var_show(queue_io_opt(q), page); 1668324aa91SJens Axboe } 1678324aa91SJens Axboe 16886b37281SMartin K. Petersen static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page) 16986b37281SMartin K. Petersen { 17086b37281SMartin K. Petersen return queue_var_show(q->limits.discard_granularity, page); 17186b37281SMartin K. Petersen } 17286b37281SMartin K. Petersen 17386b37281SMartin K. Petersen static ssize_t queue_discard_max_show(struct request_queue *q, char *page) 17486b37281SMartin K. Petersen { 175a934a00aSMartin K. Petersen return sprintf(page, "%llu\n", 176a934a00aSMartin K. Petersen (unsigned long long)q->limits.max_discard_sectors << 9); 17786b37281SMartin K. Petersen } 17886b37281SMartin K. Petersen 17998262f27SMartin K. Petersen static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) 18098262f27SMartin K. Petersen { 18198262f27SMartin K. Petersen return queue_var_show(queue_discard_zeroes_data(q), page); 18298262f27SMartin K. Petersen } 18398262f27SMartin K. Petersen 1844363ac7cSMartin K. Petersen static ssize_t queue_write_same_max_show(struct request_queue *q, char *page) 1854363ac7cSMartin K. Petersen { 1864363ac7cSMartin K. Petersen return sprintf(page, "%llu\n", 1874363ac7cSMartin K. Petersen (unsigned long long)q->limits.max_write_same_sectors << 9); 1884363ac7cSMartin K. Petersen } 1894363ac7cSMartin K. Petersen 1904363ac7cSMartin K. Petersen 1918324aa91SJens Axboe static ssize_t 1928324aa91SJens Axboe queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) 1938324aa91SJens Axboe { 1948324aa91SJens Axboe unsigned long max_sectors_kb, 195ae03bf63SMartin K. Petersen max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1, 1968324aa91SJens Axboe page_kb = 1 << (PAGE_CACHE_SHIFT - 10); 1978324aa91SJens Axboe ssize_t ret = queue_var_store(&max_sectors_kb, page, count); 1988324aa91SJens Axboe 199b1f3b64dSDave Reisner if (ret < 0) 200b1f3b64dSDave Reisner return ret; 201b1f3b64dSDave Reisner 2028324aa91SJens Axboe if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb) 2038324aa91SJens Axboe return -EINVAL; 2047c239517SWu Fengguang 2058324aa91SJens Axboe spin_lock_irq(q->queue_lock); 206c295fc05SNikanth Karthikesan q->limits.max_sectors = max_sectors_kb << 1; 2078324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 2088324aa91SJens Axboe 2098324aa91SJens Axboe return ret; 2108324aa91SJens Axboe } 2118324aa91SJens Axboe 2128324aa91SJens Axboe static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page) 2138324aa91SJens Axboe { 214ae03bf63SMartin K. Petersen int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1; 2158324aa91SJens Axboe 2168324aa91SJens Axboe return queue_var_show(max_hw_sectors_kb, (page)); 2178324aa91SJens Axboe } 2188324aa91SJens Axboe 219956bcb7cSJens Axboe #define QUEUE_SYSFS_BIT_FNS(name, flag, neg) \ 220956bcb7cSJens Axboe static ssize_t \ 221956bcb7cSJens Axboe queue_show_##name(struct request_queue *q, char *page) \ 222956bcb7cSJens Axboe { \ 223956bcb7cSJens Axboe int bit; \ 224956bcb7cSJens Axboe bit = test_bit(QUEUE_FLAG_##flag, &q->queue_flags); \ 225956bcb7cSJens Axboe return queue_var_show(neg ? !bit : bit, page); \ 226956bcb7cSJens Axboe } \ 227956bcb7cSJens Axboe static ssize_t \ 228956bcb7cSJens Axboe queue_store_##name(struct request_queue *q, const char *page, size_t count) \ 229956bcb7cSJens Axboe { \ 230956bcb7cSJens Axboe unsigned long val; \ 231956bcb7cSJens Axboe ssize_t ret; \ 232956bcb7cSJens Axboe ret = queue_var_store(&val, page, count); \ 233c678ef52SArnd Bergmann if (ret < 0) \ 234c678ef52SArnd Bergmann return ret; \ 235956bcb7cSJens Axboe if (neg) \ 236956bcb7cSJens Axboe val = !val; \ 237956bcb7cSJens Axboe \ 238956bcb7cSJens Axboe spin_lock_irq(q->queue_lock); \ 239956bcb7cSJens Axboe if (val) \ 240956bcb7cSJens Axboe queue_flag_set(QUEUE_FLAG_##flag, q); \ 241956bcb7cSJens Axboe else \ 242956bcb7cSJens Axboe queue_flag_clear(QUEUE_FLAG_##flag, q); \ 243956bcb7cSJens Axboe spin_unlock_irq(q->queue_lock); \ 244956bcb7cSJens Axboe return ret; \ 2451308835fSBartlomiej Zolnierkiewicz } 2461308835fSBartlomiej Zolnierkiewicz 247956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1); 248956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0); 249956bcb7cSJens Axboe QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0); 250956bcb7cSJens Axboe #undef QUEUE_SYSFS_BIT_FNS 2511308835fSBartlomiej Zolnierkiewicz 252ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_show(struct request_queue *q, char *page) 253ac9fafa1SAlan D. Brunelle { 254488991e2SAlan D. Brunelle return queue_var_show((blk_queue_nomerges(q) << 1) | 255488991e2SAlan D. Brunelle blk_queue_noxmerges(q), page); 256ac9fafa1SAlan D. Brunelle } 257ac9fafa1SAlan D. Brunelle 258ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, 259ac9fafa1SAlan D. Brunelle size_t count) 260ac9fafa1SAlan D. Brunelle { 261ac9fafa1SAlan D. Brunelle unsigned long nm; 262ac9fafa1SAlan D. Brunelle ssize_t ret = queue_var_store(&nm, page, count); 263ac9fafa1SAlan D. Brunelle 264b1f3b64dSDave Reisner if (ret < 0) 265b1f3b64dSDave Reisner return ret; 266b1f3b64dSDave Reisner 267bf0f9702SJens Axboe spin_lock_irq(q->queue_lock); 268bf0f9702SJens Axboe queue_flag_clear(QUEUE_FLAG_NOMERGES, q); 269488991e2SAlan D. Brunelle queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); 270488991e2SAlan D. Brunelle if (nm == 2) 271488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOMERGES, q); 272488991e2SAlan D. Brunelle else if (nm) 273488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOXMERGES, q); 274bf0f9702SJens Axboe spin_unlock_irq(q->queue_lock); 2751308835fSBartlomiej Zolnierkiewicz 276ac9fafa1SAlan D. Brunelle return ret; 277ac9fafa1SAlan D. Brunelle } 278ac9fafa1SAlan D. Brunelle 279c7c22e4dSJens Axboe static ssize_t queue_rq_affinity_show(struct request_queue *q, char *page) 280c7c22e4dSJens Axboe { 2819cb308ceSXiaotian Feng bool set = test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags); 2825757a6d7SDan Williams bool force = test_bit(QUEUE_FLAG_SAME_FORCE, &q->queue_flags); 283c7c22e4dSJens Axboe 2845757a6d7SDan Williams return queue_var_show(set << force, page); 285c7c22e4dSJens Axboe } 286c7c22e4dSJens Axboe 287c7c22e4dSJens Axboe static ssize_t 288c7c22e4dSJens Axboe queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count) 289c7c22e4dSJens Axboe { 290c7c22e4dSJens Axboe ssize_t ret = -EINVAL; 291c7c22e4dSJens Axboe #if defined(CONFIG_USE_GENERIC_SMP_HELPERS) 292c7c22e4dSJens Axboe unsigned long val; 293c7c22e4dSJens Axboe 294c7c22e4dSJens Axboe ret = queue_var_store(&val, page, count); 295b1f3b64dSDave Reisner if (ret < 0) 296b1f3b64dSDave Reisner return ret; 297b1f3b64dSDave Reisner 298c7c22e4dSJens Axboe spin_lock_irq(q->queue_lock); 299e8037d49SEric Seppanen if (val == 2) { 300c7c22e4dSJens Axboe queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 3015757a6d7SDan Williams queue_flag_set(QUEUE_FLAG_SAME_FORCE, q); 302e8037d49SEric Seppanen } else if (val == 1) { 303e8037d49SEric Seppanen queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 304e8037d49SEric Seppanen queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q); 305e8037d49SEric Seppanen } else if (val == 0) { 306c7c22e4dSJens Axboe queue_flag_clear(QUEUE_FLAG_SAME_COMP, q); 3075757a6d7SDan Williams queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q); 3085757a6d7SDan Williams } 309c7c22e4dSJens Axboe spin_unlock_irq(q->queue_lock); 310c7c22e4dSJens Axboe #endif 311c7c22e4dSJens Axboe return ret; 312c7c22e4dSJens Axboe } 3138324aa91SJens Axboe 3148324aa91SJens Axboe static struct queue_sysfs_entry queue_requests_entry = { 3158324aa91SJens Axboe .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 3168324aa91SJens Axboe .show = queue_requests_show, 3178324aa91SJens Axboe .store = queue_requests_store, 3188324aa91SJens Axboe }; 3198324aa91SJens Axboe 3208324aa91SJens Axboe static struct queue_sysfs_entry queue_ra_entry = { 3218324aa91SJens Axboe .attr = {.name = "read_ahead_kb", .mode = S_IRUGO | S_IWUSR }, 3228324aa91SJens Axboe .show = queue_ra_show, 3238324aa91SJens Axboe .store = queue_ra_store, 3248324aa91SJens Axboe }; 3258324aa91SJens Axboe 3268324aa91SJens Axboe static struct queue_sysfs_entry queue_max_sectors_entry = { 3278324aa91SJens Axboe .attr = {.name = "max_sectors_kb", .mode = S_IRUGO | S_IWUSR }, 3288324aa91SJens Axboe .show = queue_max_sectors_show, 3298324aa91SJens Axboe .store = queue_max_sectors_store, 3308324aa91SJens Axboe }; 3318324aa91SJens Axboe 3328324aa91SJens Axboe static struct queue_sysfs_entry queue_max_hw_sectors_entry = { 3338324aa91SJens Axboe .attr = {.name = "max_hw_sectors_kb", .mode = S_IRUGO }, 3348324aa91SJens Axboe .show = queue_max_hw_sectors_show, 3358324aa91SJens Axboe }; 3368324aa91SJens Axboe 337c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segments_entry = { 338c77a5710SMartin K. Petersen .attr = {.name = "max_segments", .mode = S_IRUGO }, 339c77a5710SMartin K. Petersen .show = queue_max_segments_show, 340c77a5710SMartin K. Petersen }; 341c77a5710SMartin K. Petersen 34213f05c8dSMartin K. Petersen static struct queue_sysfs_entry queue_max_integrity_segments_entry = { 34313f05c8dSMartin K. Petersen .attr = {.name = "max_integrity_segments", .mode = S_IRUGO }, 34413f05c8dSMartin K. Petersen .show = queue_max_integrity_segments_show, 34513f05c8dSMartin K. Petersen }; 34613f05c8dSMartin K. Petersen 347c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segment_size_entry = { 348c77a5710SMartin K. Petersen .attr = {.name = "max_segment_size", .mode = S_IRUGO }, 349c77a5710SMartin K. Petersen .show = queue_max_segment_size_show, 350c77a5710SMartin K. Petersen }; 351c77a5710SMartin K. Petersen 3528324aa91SJens Axboe static struct queue_sysfs_entry queue_iosched_entry = { 3538324aa91SJens Axboe .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, 3548324aa91SJens Axboe .show = elv_iosched_show, 3558324aa91SJens Axboe .store = elv_iosched_store, 3568324aa91SJens Axboe }; 3578324aa91SJens Axboe 358e68b903cSMartin K. Petersen static struct queue_sysfs_entry queue_hw_sector_size_entry = { 359e68b903cSMartin K. Petersen .attr = {.name = "hw_sector_size", .mode = S_IRUGO }, 360e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 361e1defc4fSMartin K. Petersen }; 362e1defc4fSMartin K. Petersen 363e1defc4fSMartin K. Petersen static struct queue_sysfs_entry queue_logical_block_size_entry = { 364e1defc4fSMartin K. Petersen .attr = {.name = "logical_block_size", .mode = S_IRUGO }, 365e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 366e68b903cSMartin K. Petersen }; 367e68b903cSMartin K. Petersen 368c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_physical_block_size_entry = { 369c72758f3SMartin K. Petersen .attr = {.name = "physical_block_size", .mode = S_IRUGO }, 370c72758f3SMartin K. Petersen .show = queue_physical_block_size_show, 371c72758f3SMartin K. Petersen }; 372c72758f3SMartin K. Petersen 373c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_min_entry = { 374c72758f3SMartin K. Petersen .attr = {.name = "minimum_io_size", .mode = S_IRUGO }, 375c72758f3SMartin K. Petersen .show = queue_io_min_show, 376c72758f3SMartin K. Petersen }; 377c72758f3SMartin K. Petersen 378c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_opt_entry = { 379c72758f3SMartin K. Petersen .attr = {.name = "optimal_io_size", .mode = S_IRUGO }, 380c72758f3SMartin K. Petersen .show = queue_io_opt_show, 3818324aa91SJens Axboe }; 3828324aa91SJens Axboe 38386b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_granularity_entry = { 38486b37281SMartin K. Petersen .attr = {.name = "discard_granularity", .mode = S_IRUGO }, 38586b37281SMartin K. Petersen .show = queue_discard_granularity_show, 38686b37281SMartin K. Petersen }; 38786b37281SMartin K. Petersen 38886b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_max_entry = { 38986b37281SMartin K. Petersen .attr = {.name = "discard_max_bytes", .mode = S_IRUGO }, 39086b37281SMartin K. Petersen .show = queue_discard_max_show, 39186b37281SMartin K. Petersen }; 39286b37281SMartin K. Petersen 39398262f27SMartin K. Petersen static struct queue_sysfs_entry queue_discard_zeroes_data_entry = { 39498262f27SMartin K. Petersen .attr = {.name = "discard_zeroes_data", .mode = S_IRUGO }, 39598262f27SMartin K. Petersen .show = queue_discard_zeroes_data_show, 39698262f27SMartin K. Petersen }; 39798262f27SMartin K. Petersen 3984363ac7cSMartin K. Petersen static struct queue_sysfs_entry queue_write_same_max_entry = { 3994363ac7cSMartin K. Petersen .attr = {.name = "write_same_max_bytes", .mode = S_IRUGO }, 4004363ac7cSMartin K. Petersen .show = queue_write_same_max_show, 4014363ac7cSMartin K. Petersen }; 4024363ac7cSMartin K. Petersen 4031308835fSBartlomiej Zolnierkiewicz static struct queue_sysfs_entry queue_nonrot_entry = { 4041308835fSBartlomiej Zolnierkiewicz .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, 405956bcb7cSJens Axboe .show = queue_show_nonrot, 406956bcb7cSJens Axboe .store = queue_store_nonrot, 4071308835fSBartlomiej Zolnierkiewicz }; 4081308835fSBartlomiej Zolnierkiewicz 409ac9fafa1SAlan D. Brunelle static struct queue_sysfs_entry queue_nomerges_entry = { 410ac9fafa1SAlan D. Brunelle .attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR }, 411ac9fafa1SAlan D. Brunelle .show = queue_nomerges_show, 412ac9fafa1SAlan D. Brunelle .store = queue_nomerges_store, 413ac9fafa1SAlan D. Brunelle }; 414ac9fafa1SAlan D. Brunelle 415c7c22e4dSJens Axboe static struct queue_sysfs_entry queue_rq_affinity_entry = { 416c7c22e4dSJens Axboe .attr = {.name = "rq_affinity", .mode = S_IRUGO | S_IWUSR }, 417c7c22e4dSJens Axboe .show = queue_rq_affinity_show, 418c7c22e4dSJens Axboe .store = queue_rq_affinity_store, 419c7c22e4dSJens Axboe }; 420c7c22e4dSJens Axboe 421bc58ba94SJens Axboe static struct queue_sysfs_entry queue_iostats_entry = { 422bc58ba94SJens Axboe .attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR }, 423956bcb7cSJens Axboe .show = queue_show_iostats, 424956bcb7cSJens Axboe .store = queue_store_iostats, 425bc58ba94SJens Axboe }; 426bc58ba94SJens Axboe 427e2e1a148SJens Axboe static struct queue_sysfs_entry queue_random_entry = { 428e2e1a148SJens Axboe .attr = {.name = "add_random", .mode = S_IRUGO | S_IWUSR }, 429956bcb7cSJens Axboe .show = queue_show_random, 430956bcb7cSJens Axboe .store = queue_store_random, 431e2e1a148SJens Axboe }; 432e2e1a148SJens Axboe 4338324aa91SJens Axboe static struct attribute *default_attrs[] = { 4348324aa91SJens Axboe &queue_requests_entry.attr, 4358324aa91SJens Axboe &queue_ra_entry.attr, 4368324aa91SJens Axboe &queue_max_hw_sectors_entry.attr, 4378324aa91SJens Axboe &queue_max_sectors_entry.attr, 438c77a5710SMartin K. Petersen &queue_max_segments_entry.attr, 43913f05c8dSMartin K. Petersen &queue_max_integrity_segments_entry.attr, 440c77a5710SMartin K. Petersen &queue_max_segment_size_entry.attr, 4418324aa91SJens Axboe &queue_iosched_entry.attr, 442e68b903cSMartin K. Petersen &queue_hw_sector_size_entry.attr, 443e1defc4fSMartin K. Petersen &queue_logical_block_size_entry.attr, 444c72758f3SMartin K. Petersen &queue_physical_block_size_entry.attr, 445c72758f3SMartin K. Petersen &queue_io_min_entry.attr, 446c72758f3SMartin K. Petersen &queue_io_opt_entry.attr, 44786b37281SMartin K. Petersen &queue_discard_granularity_entry.attr, 44886b37281SMartin K. Petersen &queue_discard_max_entry.attr, 44998262f27SMartin K. Petersen &queue_discard_zeroes_data_entry.attr, 4504363ac7cSMartin K. Petersen &queue_write_same_max_entry.attr, 4511308835fSBartlomiej Zolnierkiewicz &queue_nonrot_entry.attr, 452ac9fafa1SAlan D. Brunelle &queue_nomerges_entry.attr, 453c7c22e4dSJens Axboe &queue_rq_affinity_entry.attr, 454bc58ba94SJens Axboe &queue_iostats_entry.attr, 455e2e1a148SJens Axboe &queue_random_entry.attr, 4568324aa91SJens Axboe NULL, 4578324aa91SJens Axboe }; 4588324aa91SJens Axboe 4598324aa91SJens Axboe #define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr) 4608324aa91SJens Axboe 4618324aa91SJens Axboe static ssize_t 4628324aa91SJens Axboe queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) 4638324aa91SJens Axboe { 4648324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4658324aa91SJens Axboe struct request_queue *q = 4668324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 4678324aa91SJens Axboe ssize_t res; 4688324aa91SJens Axboe 4698324aa91SJens Axboe if (!entry->show) 4708324aa91SJens Axboe return -EIO; 4718324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4723f3299d5SBart Van Assche if (blk_queue_dying(q)) { 4738324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4748324aa91SJens Axboe return -ENOENT; 4758324aa91SJens Axboe } 4768324aa91SJens Axboe res = entry->show(q, page); 4778324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4788324aa91SJens Axboe return res; 4798324aa91SJens Axboe } 4808324aa91SJens Axboe 4818324aa91SJens Axboe static ssize_t 4828324aa91SJens Axboe queue_attr_store(struct kobject *kobj, struct attribute *attr, 4838324aa91SJens Axboe const char *page, size_t length) 4848324aa91SJens Axboe { 4858324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4866728cb0eSJens Axboe struct request_queue *q; 4878324aa91SJens Axboe ssize_t res; 4888324aa91SJens Axboe 4898324aa91SJens Axboe if (!entry->store) 4908324aa91SJens Axboe return -EIO; 4916728cb0eSJens Axboe 4926728cb0eSJens Axboe q = container_of(kobj, struct request_queue, kobj); 4938324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4943f3299d5SBart Van Assche if (blk_queue_dying(q)) { 4958324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4968324aa91SJens Axboe return -ENOENT; 4978324aa91SJens Axboe } 4988324aa91SJens Axboe res = entry->store(q, page, length); 4998324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 5008324aa91SJens Axboe return res; 5018324aa91SJens Axboe } 5028324aa91SJens Axboe 503548bc8e1STejun Heo static void blk_free_queue_rcu(struct rcu_head *rcu_head) 504548bc8e1STejun Heo { 505548bc8e1STejun Heo struct request_queue *q = container_of(rcu_head, struct request_queue, 506548bc8e1STejun Heo rcu_head); 507548bc8e1STejun Heo kmem_cache_free(blk_requestq_cachep, q); 508548bc8e1STejun Heo } 509548bc8e1STejun Heo 5108324aa91SJens Axboe /** 511499337bbSAndrew Morton * blk_release_queue: - release a &struct request_queue when it is no longer needed 512499337bbSAndrew Morton * @kobj: the kobj belonging to the request queue to be released 5138324aa91SJens Axboe * 5148324aa91SJens Axboe * Description: 515499337bbSAndrew Morton * blk_release_queue is the pair to blk_init_queue() or 5168324aa91SJens Axboe * blk_queue_make_request(). It should be called when a request queue is 5178324aa91SJens Axboe * being released; typically when a block device is being de-registered. 5188324aa91SJens Axboe * Currently, its primary task it to free all the &struct request 5198324aa91SJens Axboe * structures that were allocated to the queue and the queue itself. 5208324aa91SJens Axboe * 5218324aa91SJens Axboe * Caveat: 5228324aa91SJens Axboe * Hopefully the low level driver will have finished any 5238324aa91SJens Axboe * outstanding requests first... 5248324aa91SJens Axboe **/ 5258324aa91SJens Axboe static void blk_release_queue(struct kobject *kobj) 5268324aa91SJens Axboe { 5278324aa91SJens Axboe struct request_queue *q = 5288324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 5298324aa91SJens Axboe 5308324aa91SJens Axboe blk_sync_queue(q); 5318324aa91SJens Axboe 532e8989faeSTejun Heo blkcg_exit_queue(q); 533e8989faeSTejun Heo 5347e5a8794STejun Heo if (q->elevator) { 5357e5a8794STejun Heo spin_lock_irq(q->queue_lock); 5367e5a8794STejun Heo ioc_clear_queue(q); 5377e5a8794STejun Heo spin_unlock_irq(q->queue_lock); 538777eb1bfSHannes Reinecke elevator_exit(q->elevator); 5397e5a8794STejun Heo } 540777eb1bfSHannes Reinecke 541a051661cSTejun Heo blk_exit_rl(&q->root_rl); 5428324aa91SJens Axboe 5438324aa91SJens Axboe if (q->queue_tags) 5448324aa91SJens Axboe __blk_queue_free_tags(q); 5458324aa91SJens Axboe 546*320ae51fSJens Axboe percpu_counter_destroy(&q->mq_usage_counter); 547*320ae51fSJens Axboe 548*320ae51fSJens Axboe if (q->mq_ops) 549*320ae51fSJens Axboe blk_mq_free_queue(q); 550*320ae51fSJens Axboe 5518324aa91SJens Axboe blk_trace_shutdown(q); 5528324aa91SJens Axboe 5538324aa91SJens Axboe bdi_destroy(&q->backing_dev_info); 554a73f730dSTejun Heo 555a73f730dSTejun Heo ida_simple_remove(&blk_queue_ida, q->id); 556548bc8e1STejun Heo call_rcu(&q->rcu_head, blk_free_queue_rcu); 5578324aa91SJens Axboe } 5588324aa91SJens Axboe 55952cf25d0SEmese Revfy static const struct sysfs_ops queue_sysfs_ops = { 5608324aa91SJens Axboe .show = queue_attr_show, 5618324aa91SJens Axboe .store = queue_attr_store, 5628324aa91SJens Axboe }; 5638324aa91SJens Axboe 5648324aa91SJens Axboe struct kobj_type blk_queue_ktype = { 5658324aa91SJens Axboe .sysfs_ops = &queue_sysfs_ops, 5668324aa91SJens Axboe .default_attrs = default_attrs, 5678324aa91SJens Axboe .release = blk_release_queue, 5688324aa91SJens Axboe }; 5698324aa91SJens Axboe 5708324aa91SJens Axboe int blk_register_queue(struct gendisk *disk) 5718324aa91SJens Axboe { 5728324aa91SJens Axboe int ret; 5731d54ad6dSLi Zefan struct device *dev = disk_to_dev(disk); 5748324aa91SJens Axboe struct request_queue *q = disk->queue; 5758324aa91SJens Axboe 576fb199746SAkinobu Mita if (WARN_ON(!q)) 5778324aa91SJens Axboe return -ENXIO; 5788324aa91SJens Axboe 579749fefe6STejun Heo /* 580749fefe6STejun Heo * Initialization must be complete by now. Finish the initial 581749fefe6STejun Heo * bypass from queue allocation. 582749fefe6STejun Heo */ 583749fefe6STejun Heo blk_queue_bypass_end(q); 584*320ae51fSJens Axboe queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q); 585749fefe6STejun Heo 5861d54ad6dSLi Zefan ret = blk_trace_init_sysfs(dev); 5871d54ad6dSLi Zefan if (ret) 5881d54ad6dSLi Zefan return ret; 5891d54ad6dSLi Zefan 590c9059598SLinus Torvalds ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); 591ed5302d3SLiu Yuan if (ret < 0) { 592ed5302d3SLiu Yuan blk_trace_remove_sysfs(dev); 5938324aa91SJens Axboe return ret; 594ed5302d3SLiu Yuan } 5958324aa91SJens Axboe 5968324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_ADD); 5978324aa91SJens Axboe 598*320ae51fSJens Axboe if (q->mq_ops) 599*320ae51fSJens Axboe blk_mq_register_disk(disk); 600*320ae51fSJens Axboe 601cd43e26fSMartin K. Petersen if (!q->request_fn) 602cd43e26fSMartin K. Petersen return 0; 603cd43e26fSMartin K. Petersen 6048324aa91SJens Axboe ret = elv_register_queue(q); 6058324aa91SJens Axboe if (ret) { 6068324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 6078324aa91SJens Axboe kobject_del(&q->kobj); 60880656b67SLiu Yuan blk_trace_remove_sysfs(dev); 609c87ffbb8SXiaotian Feng kobject_put(&dev->kobj); 6108324aa91SJens Axboe return ret; 6118324aa91SJens Axboe } 6128324aa91SJens Axboe 6138324aa91SJens Axboe return 0; 6148324aa91SJens Axboe } 6158324aa91SJens Axboe 6168324aa91SJens Axboe void blk_unregister_queue(struct gendisk *disk) 6178324aa91SJens Axboe { 6188324aa91SJens Axboe struct request_queue *q = disk->queue; 6198324aa91SJens Axboe 620fb199746SAkinobu Mita if (WARN_ON(!q)) 621fb199746SAkinobu Mita return; 622fb199746SAkinobu Mita 623*320ae51fSJens Axboe if (q->mq_ops) 624*320ae51fSJens Axboe blk_mq_unregister_disk(disk); 625*320ae51fSJens Axboe 62648c0d4d4SZdenek Kabelac if (q->request_fn) 6278324aa91SJens Axboe elv_unregister_queue(q); 6288324aa91SJens Axboe 6298324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 6308324aa91SJens Axboe kobject_del(&q->kobj); 63148c0d4d4SZdenek Kabelac blk_trace_remove_sysfs(disk_to_dev(disk)); 632ed9e1982STejun Heo kobject_put(&disk_to_dev(disk)->kobj); 6338324aa91SJens Axboe } 634