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> 108324aa91SJens Axboe 118324aa91SJens Axboe #include "blk.h" 128324aa91SJens Axboe 138324aa91SJens Axboe struct queue_sysfs_entry { 148324aa91SJens Axboe struct attribute attr; 158324aa91SJens Axboe ssize_t (*show)(struct request_queue *, char *); 168324aa91SJens Axboe ssize_t (*store)(struct request_queue *, const char *, size_t); 178324aa91SJens Axboe }; 188324aa91SJens Axboe 198324aa91SJens Axboe static ssize_t 209cb308ceSXiaotian Feng queue_var_show(unsigned long var, char *page) 218324aa91SJens Axboe { 229cb308ceSXiaotian Feng return sprintf(page, "%lu\n", var); 238324aa91SJens Axboe } 248324aa91SJens Axboe 258324aa91SJens Axboe static ssize_t 268324aa91SJens Axboe queue_var_store(unsigned long *var, const char *page, size_t count) 278324aa91SJens Axboe { 288324aa91SJens Axboe char *p = (char *) page; 298324aa91SJens Axboe 308324aa91SJens Axboe *var = simple_strtoul(p, &p, 10); 318324aa91SJens Axboe return count; 328324aa91SJens Axboe } 338324aa91SJens Axboe 348324aa91SJens Axboe static ssize_t queue_requests_show(struct request_queue *q, char *page) 358324aa91SJens Axboe { 368324aa91SJens Axboe return queue_var_show(q->nr_requests, (page)); 378324aa91SJens Axboe } 388324aa91SJens Axboe 398324aa91SJens Axboe static ssize_t 408324aa91SJens Axboe queue_requests_store(struct request_queue *q, const char *page, size_t count) 418324aa91SJens Axboe { 428324aa91SJens Axboe struct request_list *rl = &q->rq; 438324aa91SJens Axboe unsigned long nr; 44b8a9ae77SJens Axboe int ret; 45b8a9ae77SJens Axboe 46b8a9ae77SJens Axboe if (!q->request_fn) 47b8a9ae77SJens Axboe return -EINVAL; 48b8a9ae77SJens Axboe 49b8a9ae77SJens Axboe ret = queue_var_store(&nr, page, count); 508324aa91SJens Axboe if (nr < BLKDEV_MIN_RQ) 518324aa91SJens Axboe nr = BLKDEV_MIN_RQ; 528324aa91SJens Axboe 538324aa91SJens Axboe spin_lock_irq(q->queue_lock); 548324aa91SJens Axboe q->nr_requests = nr; 558324aa91SJens Axboe blk_queue_congestion_threshold(q); 568324aa91SJens Axboe 571faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q)) 581faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_SYNC); 591faa16d2SJens Axboe else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q)) 601faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_SYNC); 618324aa91SJens Axboe 621faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q)) 631faa16d2SJens Axboe blk_set_queue_congested(q, BLK_RW_ASYNC); 641faa16d2SJens Axboe else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q)) 651faa16d2SJens Axboe blk_clear_queue_congested(q, BLK_RW_ASYNC); 668324aa91SJens Axboe 671faa16d2SJens Axboe if (rl->count[BLK_RW_SYNC] >= q->nr_requests) { 681faa16d2SJens Axboe blk_set_queue_full(q, BLK_RW_SYNC); 691faa16d2SJens Axboe } else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) { 701faa16d2SJens Axboe blk_clear_queue_full(q, BLK_RW_SYNC); 711faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_SYNC]); 728324aa91SJens Axboe } 738324aa91SJens Axboe 741faa16d2SJens Axboe if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) { 751faa16d2SJens Axboe blk_set_queue_full(q, BLK_RW_ASYNC); 761faa16d2SJens Axboe } else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) { 771faa16d2SJens Axboe blk_clear_queue_full(q, BLK_RW_ASYNC); 781faa16d2SJens Axboe wake_up(&rl->wait[BLK_RW_ASYNC]); 798324aa91SJens Axboe } 808324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 818324aa91SJens Axboe return ret; 828324aa91SJens Axboe } 838324aa91SJens Axboe 848324aa91SJens Axboe static ssize_t queue_ra_show(struct request_queue *q, char *page) 858324aa91SJens Axboe { 869cb308ceSXiaotian Feng unsigned long ra_kb = q->backing_dev_info.ra_pages << 879cb308ceSXiaotian Feng (PAGE_CACHE_SHIFT - 10); 888324aa91SJens Axboe 898324aa91SJens Axboe return queue_var_show(ra_kb, (page)); 908324aa91SJens Axboe } 918324aa91SJens Axboe 928324aa91SJens Axboe static ssize_t 938324aa91SJens Axboe queue_ra_store(struct request_queue *q, const char *page, size_t count) 948324aa91SJens Axboe { 958324aa91SJens Axboe unsigned long ra_kb; 968324aa91SJens Axboe ssize_t ret = queue_var_store(&ra_kb, page, count); 978324aa91SJens Axboe 988324aa91SJens Axboe q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); 998324aa91SJens Axboe 1008324aa91SJens Axboe return ret; 1018324aa91SJens Axboe } 1028324aa91SJens Axboe 1038324aa91SJens Axboe static ssize_t queue_max_sectors_show(struct request_queue *q, char *page) 1048324aa91SJens Axboe { 105ae03bf63SMartin K. Petersen int max_sectors_kb = queue_max_sectors(q) >> 1; 1068324aa91SJens Axboe 1078324aa91SJens Axboe return queue_var_show(max_sectors_kb, (page)); 1088324aa91SJens Axboe } 1098324aa91SJens Axboe 110c77a5710SMartin K. Petersen static ssize_t queue_max_segments_show(struct request_queue *q, char *page) 111c77a5710SMartin K. Petersen { 112c77a5710SMartin K. Petersen return queue_var_show(queue_max_segments(q), (page)); 113c77a5710SMartin K. Petersen } 114c77a5710SMartin K. Petersen 115c77a5710SMartin K. Petersen static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) 116c77a5710SMartin K. Petersen { 117c77a5710SMartin K. Petersen if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) 118c77a5710SMartin K. Petersen return queue_var_show(queue_max_segment_size(q), (page)); 119c77a5710SMartin K. Petersen 120c77a5710SMartin K. Petersen return queue_var_show(PAGE_CACHE_SIZE, (page)); 121c77a5710SMartin K. Petersen } 122c77a5710SMartin K. Petersen 123e1defc4fSMartin K. Petersen static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) 124e68b903cSMartin K. Petersen { 125e1defc4fSMartin K. Petersen return queue_var_show(queue_logical_block_size(q), page); 126e68b903cSMartin K. Petersen } 127e68b903cSMartin K. Petersen 128c72758f3SMartin K. Petersen static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page) 129c72758f3SMartin K. Petersen { 130c72758f3SMartin K. Petersen return queue_var_show(queue_physical_block_size(q), page); 131c72758f3SMartin K. Petersen } 132c72758f3SMartin K. Petersen 133c72758f3SMartin K. Petersen static ssize_t queue_io_min_show(struct request_queue *q, char *page) 134c72758f3SMartin K. Petersen { 135c72758f3SMartin K. Petersen return queue_var_show(queue_io_min(q), page); 136c72758f3SMartin K. Petersen } 137c72758f3SMartin K. Petersen 138c72758f3SMartin K. Petersen static ssize_t queue_io_opt_show(struct request_queue *q, char *page) 139c72758f3SMartin K. Petersen { 140c72758f3SMartin K. Petersen return queue_var_show(queue_io_opt(q), page); 1418324aa91SJens Axboe } 1428324aa91SJens Axboe 14386b37281SMartin K. Petersen static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page) 14486b37281SMartin K. Petersen { 14586b37281SMartin K. Petersen return queue_var_show(q->limits.discard_granularity, page); 14686b37281SMartin K. Petersen } 14786b37281SMartin K. Petersen 14886b37281SMartin K. Petersen static ssize_t queue_discard_max_show(struct request_queue *q, char *page) 14986b37281SMartin K. Petersen { 15086b37281SMartin K. Petersen return queue_var_show(q->limits.max_discard_sectors << 9, page); 15186b37281SMartin K. Petersen } 15286b37281SMartin K. Petersen 15398262f27SMartin K. Petersen static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) 15498262f27SMartin K. Petersen { 15598262f27SMartin K. Petersen return queue_var_show(queue_discard_zeroes_data(q), page); 15698262f27SMartin K. Petersen } 15798262f27SMartin K. Petersen 1588324aa91SJens Axboe static ssize_t 1598324aa91SJens Axboe queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) 1608324aa91SJens Axboe { 1618324aa91SJens Axboe unsigned long max_sectors_kb, 162ae03bf63SMartin K. Petersen max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1, 1638324aa91SJens Axboe page_kb = 1 << (PAGE_CACHE_SHIFT - 10); 1648324aa91SJens Axboe ssize_t ret = queue_var_store(&max_sectors_kb, page, count); 1658324aa91SJens Axboe 1668324aa91SJens Axboe if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb) 1678324aa91SJens Axboe return -EINVAL; 1687c239517SWu Fengguang 1698324aa91SJens Axboe spin_lock_irq(q->queue_lock); 170c295fc05SNikanth Karthikesan q->limits.max_sectors = max_sectors_kb << 1; 1718324aa91SJens Axboe spin_unlock_irq(q->queue_lock); 1728324aa91SJens Axboe 1738324aa91SJens Axboe return ret; 1748324aa91SJens Axboe } 1758324aa91SJens Axboe 1768324aa91SJens Axboe static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page) 1778324aa91SJens Axboe { 178ae03bf63SMartin K. Petersen int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1; 1798324aa91SJens Axboe 1808324aa91SJens Axboe return queue_var_show(max_hw_sectors_kb, (page)); 1818324aa91SJens Axboe } 1828324aa91SJens Axboe 1831308835fSBartlomiej Zolnierkiewicz static ssize_t queue_nonrot_show(struct request_queue *q, char *page) 1841308835fSBartlomiej Zolnierkiewicz { 1851308835fSBartlomiej Zolnierkiewicz return queue_var_show(!blk_queue_nonrot(q), page); 1861308835fSBartlomiej Zolnierkiewicz } 1871308835fSBartlomiej Zolnierkiewicz 1881308835fSBartlomiej Zolnierkiewicz static ssize_t queue_nonrot_store(struct request_queue *q, const char *page, 1891308835fSBartlomiej Zolnierkiewicz size_t count) 1901308835fSBartlomiej Zolnierkiewicz { 1911308835fSBartlomiej Zolnierkiewicz unsigned long nm; 1921308835fSBartlomiej Zolnierkiewicz ssize_t ret = queue_var_store(&nm, page, count); 1931308835fSBartlomiej Zolnierkiewicz 1941308835fSBartlomiej Zolnierkiewicz spin_lock_irq(q->queue_lock); 1951308835fSBartlomiej Zolnierkiewicz if (nm) 1961308835fSBartlomiej Zolnierkiewicz queue_flag_clear(QUEUE_FLAG_NONROT, q); 1971308835fSBartlomiej Zolnierkiewicz else 1981308835fSBartlomiej Zolnierkiewicz queue_flag_set(QUEUE_FLAG_NONROT, q); 1991308835fSBartlomiej Zolnierkiewicz spin_unlock_irq(q->queue_lock); 2001308835fSBartlomiej Zolnierkiewicz 2011308835fSBartlomiej Zolnierkiewicz return ret; 2021308835fSBartlomiej Zolnierkiewicz } 2031308835fSBartlomiej Zolnierkiewicz 204ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_show(struct request_queue *q, char *page) 205ac9fafa1SAlan D. Brunelle { 206488991e2SAlan D. Brunelle return queue_var_show((blk_queue_nomerges(q) << 1) | 207488991e2SAlan D. Brunelle blk_queue_noxmerges(q), page); 208ac9fafa1SAlan D. Brunelle } 209ac9fafa1SAlan D. Brunelle 210ac9fafa1SAlan D. Brunelle static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, 211ac9fafa1SAlan D. Brunelle size_t count) 212ac9fafa1SAlan D. Brunelle { 213ac9fafa1SAlan D. Brunelle unsigned long nm; 214ac9fafa1SAlan D. Brunelle ssize_t ret = queue_var_store(&nm, page, count); 215ac9fafa1SAlan D. Brunelle 216bf0f9702SJens Axboe spin_lock_irq(q->queue_lock); 217bf0f9702SJens Axboe queue_flag_clear(QUEUE_FLAG_NOMERGES, q); 218488991e2SAlan D. Brunelle queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); 219488991e2SAlan D. Brunelle if (nm == 2) 220488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOMERGES, q); 221488991e2SAlan D. Brunelle else if (nm) 222488991e2SAlan D. Brunelle queue_flag_set(QUEUE_FLAG_NOXMERGES, q); 223bf0f9702SJens Axboe spin_unlock_irq(q->queue_lock); 2241308835fSBartlomiej Zolnierkiewicz 225ac9fafa1SAlan D. Brunelle return ret; 226ac9fafa1SAlan D. Brunelle } 227ac9fafa1SAlan D. Brunelle 228c7c22e4dSJens Axboe static ssize_t queue_rq_affinity_show(struct request_queue *q, char *page) 229c7c22e4dSJens Axboe { 2309cb308ceSXiaotian Feng bool set = test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags); 231c7c22e4dSJens Axboe 2329cb308ceSXiaotian Feng return queue_var_show(set, page); 233c7c22e4dSJens Axboe } 234c7c22e4dSJens Axboe 235c7c22e4dSJens Axboe static ssize_t 236c7c22e4dSJens Axboe queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count) 237c7c22e4dSJens Axboe { 238c7c22e4dSJens Axboe ssize_t ret = -EINVAL; 239c7c22e4dSJens Axboe #if defined(CONFIG_USE_GENERIC_SMP_HELPERS) 240c7c22e4dSJens Axboe unsigned long val; 241c7c22e4dSJens Axboe 242c7c22e4dSJens Axboe ret = queue_var_store(&val, page, count); 243c7c22e4dSJens Axboe spin_lock_irq(q->queue_lock); 244c7c22e4dSJens Axboe if (val) 245c7c22e4dSJens Axboe queue_flag_set(QUEUE_FLAG_SAME_COMP, q); 246c7c22e4dSJens Axboe else 247c7c22e4dSJens Axboe queue_flag_clear(QUEUE_FLAG_SAME_COMP, q); 248c7c22e4dSJens Axboe spin_unlock_irq(q->queue_lock); 249c7c22e4dSJens Axboe #endif 250c7c22e4dSJens Axboe return ret; 251c7c22e4dSJens Axboe } 2528324aa91SJens Axboe 253*e2e1a148SJens Axboe static ssize_t queue_random_show(struct request_queue *q, char *page) 254*e2e1a148SJens Axboe { 255*e2e1a148SJens Axboe return queue_var_show(blk_queue_add_random(q), page); 256*e2e1a148SJens Axboe } 257*e2e1a148SJens Axboe 258*e2e1a148SJens Axboe static ssize_t queue_random_store(struct request_queue *q, const char *page, 259*e2e1a148SJens Axboe size_t count) 260*e2e1a148SJens Axboe { 261*e2e1a148SJens Axboe unsigned long val; 262*e2e1a148SJens Axboe ssize_t ret = queue_var_store(&val, page, count); 263*e2e1a148SJens Axboe 264*e2e1a148SJens Axboe spin_lock_irq(q->queue_lock); 265*e2e1a148SJens Axboe if (val) 266*e2e1a148SJens Axboe queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q); 267*e2e1a148SJens Axboe else 268*e2e1a148SJens Axboe queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q); 269*e2e1a148SJens Axboe spin_unlock_irq(q->queue_lock); 270*e2e1a148SJens Axboe 271*e2e1a148SJens Axboe return ret; 272*e2e1a148SJens Axboe } 273*e2e1a148SJens Axboe 274bc58ba94SJens Axboe static ssize_t queue_iostats_show(struct request_queue *q, char *page) 275bc58ba94SJens Axboe { 276bc58ba94SJens Axboe return queue_var_show(blk_queue_io_stat(q), page); 277bc58ba94SJens Axboe } 278bc58ba94SJens Axboe 279bc58ba94SJens Axboe static ssize_t queue_iostats_store(struct request_queue *q, const char *page, 280bc58ba94SJens Axboe size_t count) 281bc58ba94SJens Axboe { 282bc58ba94SJens Axboe unsigned long stats; 283bc58ba94SJens Axboe ssize_t ret = queue_var_store(&stats, page, count); 284bc58ba94SJens Axboe 285bc58ba94SJens Axboe spin_lock_irq(q->queue_lock); 286bc58ba94SJens Axboe if (stats) 287bc58ba94SJens Axboe queue_flag_set(QUEUE_FLAG_IO_STAT, q); 288bc58ba94SJens Axboe else 289bc58ba94SJens Axboe queue_flag_clear(QUEUE_FLAG_IO_STAT, q); 290bc58ba94SJens Axboe spin_unlock_irq(q->queue_lock); 291bc58ba94SJens Axboe 292bc58ba94SJens Axboe return ret; 293bc58ba94SJens Axboe } 294bc58ba94SJens Axboe 2958324aa91SJens Axboe static struct queue_sysfs_entry queue_requests_entry = { 2968324aa91SJens Axboe .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 2978324aa91SJens Axboe .show = queue_requests_show, 2988324aa91SJens Axboe .store = queue_requests_store, 2998324aa91SJens Axboe }; 3008324aa91SJens Axboe 3018324aa91SJens Axboe static struct queue_sysfs_entry queue_ra_entry = { 3028324aa91SJens Axboe .attr = {.name = "read_ahead_kb", .mode = S_IRUGO | S_IWUSR }, 3038324aa91SJens Axboe .show = queue_ra_show, 3048324aa91SJens Axboe .store = queue_ra_store, 3058324aa91SJens Axboe }; 3068324aa91SJens Axboe 3078324aa91SJens Axboe static struct queue_sysfs_entry queue_max_sectors_entry = { 3088324aa91SJens Axboe .attr = {.name = "max_sectors_kb", .mode = S_IRUGO | S_IWUSR }, 3098324aa91SJens Axboe .show = queue_max_sectors_show, 3108324aa91SJens Axboe .store = queue_max_sectors_store, 3118324aa91SJens Axboe }; 3128324aa91SJens Axboe 3138324aa91SJens Axboe static struct queue_sysfs_entry queue_max_hw_sectors_entry = { 3148324aa91SJens Axboe .attr = {.name = "max_hw_sectors_kb", .mode = S_IRUGO }, 3158324aa91SJens Axboe .show = queue_max_hw_sectors_show, 3168324aa91SJens Axboe }; 3178324aa91SJens Axboe 318c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segments_entry = { 319c77a5710SMartin K. Petersen .attr = {.name = "max_segments", .mode = S_IRUGO }, 320c77a5710SMartin K. Petersen .show = queue_max_segments_show, 321c77a5710SMartin K. Petersen }; 322c77a5710SMartin K. Petersen 323c77a5710SMartin K. Petersen static struct queue_sysfs_entry queue_max_segment_size_entry = { 324c77a5710SMartin K. Petersen .attr = {.name = "max_segment_size", .mode = S_IRUGO }, 325c77a5710SMartin K. Petersen .show = queue_max_segment_size_show, 326c77a5710SMartin K. Petersen }; 327c77a5710SMartin K. Petersen 3288324aa91SJens Axboe static struct queue_sysfs_entry queue_iosched_entry = { 3298324aa91SJens Axboe .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, 3308324aa91SJens Axboe .show = elv_iosched_show, 3318324aa91SJens Axboe .store = elv_iosched_store, 3328324aa91SJens Axboe }; 3338324aa91SJens Axboe 334e68b903cSMartin K. Petersen static struct queue_sysfs_entry queue_hw_sector_size_entry = { 335e68b903cSMartin K. Petersen .attr = {.name = "hw_sector_size", .mode = S_IRUGO }, 336e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 337e1defc4fSMartin K. Petersen }; 338e1defc4fSMartin K. Petersen 339e1defc4fSMartin K. Petersen static struct queue_sysfs_entry queue_logical_block_size_entry = { 340e1defc4fSMartin K. Petersen .attr = {.name = "logical_block_size", .mode = S_IRUGO }, 341e1defc4fSMartin K. Petersen .show = queue_logical_block_size_show, 342e68b903cSMartin K. Petersen }; 343e68b903cSMartin K. Petersen 344c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_physical_block_size_entry = { 345c72758f3SMartin K. Petersen .attr = {.name = "physical_block_size", .mode = S_IRUGO }, 346c72758f3SMartin K. Petersen .show = queue_physical_block_size_show, 347c72758f3SMartin K. Petersen }; 348c72758f3SMartin K. Petersen 349c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_min_entry = { 350c72758f3SMartin K. Petersen .attr = {.name = "minimum_io_size", .mode = S_IRUGO }, 351c72758f3SMartin K. Petersen .show = queue_io_min_show, 352c72758f3SMartin K. Petersen }; 353c72758f3SMartin K. Petersen 354c72758f3SMartin K. Petersen static struct queue_sysfs_entry queue_io_opt_entry = { 355c72758f3SMartin K. Petersen .attr = {.name = "optimal_io_size", .mode = S_IRUGO }, 356c72758f3SMartin K. Petersen .show = queue_io_opt_show, 3578324aa91SJens Axboe }; 3588324aa91SJens Axboe 35986b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_granularity_entry = { 36086b37281SMartin K. Petersen .attr = {.name = "discard_granularity", .mode = S_IRUGO }, 36186b37281SMartin K. Petersen .show = queue_discard_granularity_show, 36286b37281SMartin K. Petersen }; 36386b37281SMartin K. Petersen 36486b37281SMartin K. Petersen static struct queue_sysfs_entry queue_discard_max_entry = { 36586b37281SMartin K. Petersen .attr = {.name = "discard_max_bytes", .mode = S_IRUGO }, 36686b37281SMartin K. Petersen .show = queue_discard_max_show, 36786b37281SMartin K. Petersen }; 36886b37281SMartin K. Petersen 36998262f27SMartin K. Petersen static struct queue_sysfs_entry queue_discard_zeroes_data_entry = { 37098262f27SMartin K. Petersen .attr = {.name = "discard_zeroes_data", .mode = S_IRUGO }, 37198262f27SMartin K. Petersen .show = queue_discard_zeroes_data_show, 37298262f27SMartin K. Petersen }; 37398262f27SMartin K. Petersen 3741308835fSBartlomiej Zolnierkiewicz static struct queue_sysfs_entry queue_nonrot_entry = { 3751308835fSBartlomiej Zolnierkiewicz .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, 3761308835fSBartlomiej Zolnierkiewicz .show = queue_nonrot_show, 3771308835fSBartlomiej Zolnierkiewicz .store = queue_nonrot_store, 3781308835fSBartlomiej Zolnierkiewicz }; 3791308835fSBartlomiej Zolnierkiewicz 380ac9fafa1SAlan D. Brunelle static struct queue_sysfs_entry queue_nomerges_entry = { 381ac9fafa1SAlan D. Brunelle .attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR }, 382ac9fafa1SAlan D. Brunelle .show = queue_nomerges_show, 383ac9fafa1SAlan D. Brunelle .store = queue_nomerges_store, 384ac9fafa1SAlan D. Brunelle }; 385ac9fafa1SAlan D. Brunelle 386c7c22e4dSJens Axboe static struct queue_sysfs_entry queue_rq_affinity_entry = { 387c7c22e4dSJens Axboe .attr = {.name = "rq_affinity", .mode = S_IRUGO | S_IWUSR }, 388c7c22e4dSJens Axboe .show = queue_rq_affinity_show, 389c7c22e4dSJens Axboe .store = queue_rq_affinity_store, 390c7c22e4dSJens Axboe }; 391c7c22e4dSJens Axboe 392bc58ba94SJens Axboe static struct queue_sysfs_entry queue_iostats_entry = { 393bc58ba94SJens Axboe .attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR }, 394bc58ba94SJens Axboe .show = queue_iostats_show, 395bc58ba94SJens Axboe .store = queue_iostats_store, 396bc58ba94SJens Axboe }; 397bc58ba94SJens Axboe 398*e2e1a148SJens Axboe static struct queue_sysfs_entry queue_random_entry = { 399*e2e1a148SJens Axboe .attr = {.name = "add_random", .mode = S_IRUGO | S_IWUSR }, 400*e2e1a148SJens Axboe .show = queue_random_show, 401*e2e1a148SJens Axboe .store = queue_random_store, 402*e2e1a148SJens Axboe }; 403*e2e1a148SJens Axboe 4048324aa91SJens Axboe static struct attribute *default_attrs[] = { 4058324aa91SJens Axboe &queue_requests_entry.attr, 4068324aa91SJens Axboe &queue_ra_entry.attr, 4078324aa91SJens Axboe &queue_max_hw_sectors_entry.attr, 4088324aa91SJens Axboe &queue_max_sectors_entry.attr, 409c77a5710SMartin K. Petersen &queue_max_segments_entry.attr, 410c77a5710SMartin K. Petersen &queue_max_segment_size_entry.attr, 4118324aa91SJens Axboe &queue_iosched_entry.attr, 412e68b903cSMartin K. Petersen &queue_hw_sector_size_entry.attr, 413e1defc4fSMartin K. Petersen &queue_logical_block_size_entry.attr, 414c72758f3SMartin K. Petersen &queue_physical_block_size_entry.attr, 415c72758f3SMartin K. Petersen &queue_io_min_entry.attr, 416c72758f3SMartin K. Petersen &queue_io_opt_entry.attr, 41786b37281SMartin K. Petersen &queue_discard_granularity_entry.attr, 41886b37281SMartin K. Petersen &queue_discard_max_entry.attr, 41998262f27SMartin K. Petersen &queue_discard_zeroes_data_entry.attr, 4201308835fSBartlomiej Zolnierkiewicz &queue_nonrot_entry.attr, 421ac9fafa1SAlan D. Brunelle &queue_nomerges_entry.attr, 422c7c22e4dSJens Axboe &queue_rq_affinity_entry.attr, 423bc58ba94SJens Axboe &queue_iostats_entry.attr, 424*e2e1a148SJens Axboe &queue_random_entry.attr, 4258324aa91SJens Axboe NULL, 4268324aa91SJens Axboe }; 4278324aa91SJens Axboe 4288324aa91SJens Axboe #define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr) 4298324aa91SJens Axboe 4308324aa91SJens Axboe static ssize_t 4318324aa91SJens Axboe queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) 4328324aa91SJens Axboe { 4338324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4348324aa91SJens Axboe struct request_queue *q = 4358324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 4368324aa91SJens Axboe ssize_t res; 4378324aa91SJens Axboe 4388324aa91SJens Axboe if (!entry->show) 4398324aa91SJens Axboe return -EIO; 4408324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4418324aa91SJens Axboe if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { 4428324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4438324aa91SJens Axboe return -ENOENT; 4448324aa91SJens Axboe } 4458324aa91SJens Axboe res = entry->show(q, page); 4468324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4478324aa91SJens Axboe return res; 4488324aa91SJens Axboe } 4498324aa91SJens Axboe 4508324aa91SJens Axboe static ssize_t 4518324aa91SJens Axboe queue_attr_store(struct kobject *kobj, struct attribute *attr, 4528324aa91SJens Axboe const char *page, size_t length) 4538324aa91SJens Axboe { 4548324aa91SJens Axboe struct queue_sysfs_entry *entry = to_queue(attr); 4556728cb0eSJens Axboe struct request_queue *q; 4568324aa91SJens Axboe ssize_t res; 4578324aa91SJens Axboe 4588324aa91SJens Axboe if (!entry->store) 4598324aa91SJens Axboe return -EIO; 4606728cb0eSJens Axboe 4616728cb0eSJens Axboe q = container_of(kobj, struct request_queue, kobj); 4628324aa91SJens Axboe mutex_lock(&q->sysfs_lock); 4638324aa91SJens Axboe if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { 4648324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4658324aa91SJens Axboe return -ENOENT; 4668324aa91SJens Axboe } 4678324aa91SJens Axboe res = entry->store(q, page, length); 4688324aa91SJens Axboe mutex_unlock(&q->sysfs_lock); 4698324aa91SJens Axboe return res; 4708324aa91SJens Axboe } 4718324aa91SJens Axboe 4728324aa91SJens Axboe /** 4738324aa91SJens Axboe * blk_cleanup_queue: - release a &struct request_queue when it is no longer needed 4748324aa91SJens Axboe * @kobj: the kobj belonging of the request queue to be released 4758324aa91SJens Axboe * 4768324aa91SJens Axboe * Description: 4778324aa91SJens Axboe * blk_cleanup_queue is the pair to blk_init_queue() or 4788324aa91SJens Axboe * blk_queue_make_request(). It should be called when a request queue is 4798324aa91SJens Axboe * being released; typically when a block device is being de-registered. 4808324aa91SJens Axboe * Currently, its primary task it to free all the &struct request 4818324aa91SJens Axboe * structures that were allocated to the queue and the queue itself. 4828324aa91SJens Axboe * 4838324aa91SJens Axboe * Caveat: 4848324aa91SJens Axboe * Hopefully the low level driver will have finished any 4858324aa91SJens Axboe * outstanding requests first... 4868324aa91SJens Axboe **/ 4878324aa91SJens Axboe static void blk_release_queue(struct kobject *kobj) 4888324aa91SJens Axboe { 4898324aa91SJens Axboe struct request_queue *q = 4908324aa91SJens Axboe container_of(kobj, struct request_queue, kobj); 4918324aa91SJens Axboe struct request_list *rl = &q->rq; 4928324aa91SJens Axboe 4938324aa91SJens Axboe blk_sync_queue(q); 4948324aa91SJens Axboe 4958324aa91SJens Axboe if (rl->rq_pool) 4968324aa91SJens Axboe mempool_destroy(rl->rq_pool); 4978324aa91SJens Axboe 4988324aa91SJens Axboe if (q->queue_tags) 4998324aa91SJens Axboe __blk_queue_free_tags(q); 5008324aa91SJens Axboe 5018324aa91SJens Axboe blk_trace_shutdown(q); 5028324aa91SJens Axboe 5038324aa91SJens Axboe bdi_destroy(&q->backing_dev_info); 5048324aa91SJens Axboe kmem_cache_free(blk_requestq_cachep, q); 5058324aa91SJens Axboe } 5068324aa91SJens Axboe 50752cf25d0SEmese Revfy static const struct sysfs_ops queue_sysfs_ops = { 5088324aa91SJens Axboe .show = queue_attr_show, 5098324aa91SJens Axboe .store = queue_attr_store, 5108324aa91SJens Axboe }; 5118324aa91SJens Axboe 5128324aa91SJens Axboe struct kobj_type blk_queue_ktype = { 5138324aa91SJens Axboe .sysfs_ops = &queue_sysfs_ops, 5148324aa91SJens Axboe .default_attrs = default_attrs, 5158324aa91SJens Axboe .release = blk_release_queue, 5168324aa91SJens Axboe }; 5178324aa91SJens Axboe 5188324aa91SJens Axboe int blk_register_queue(struct gendisk *disk) 5198324aa91SJens Axboe { 5208324aa91SJens Axboe int ret; 5211d54ad6dSLi Zefan struct device *dev = disk_to_dev(disk); 5228324aa91SJens Axboe 5238324aa91SJens Axboe struct request_queue *q = disk->queue; 5248324aa91SJens Axboe 525fb199746SAkinobu Mita if (WARN_ON(!q)) 5268324aa91SJens Axboe return -ENXIO; 5278324aa91SJens Axboe 5281d54ad6dSLi Zefan ret = blk_trace_init_sysfs(dev); 5291d54ad6dSLi Zefan if (ret) 5301d54ad6dSLi Zefan return ret; 5311d54ad6dSLi Zefan 532c9059598SLinus Torvalds ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); 5338324aa91SJens Axboe if (ret < 0) 5348324aa91SJens Axboe return ret; 5358324aa91SJens Axboe 5368324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_ADD); 5378324aa91SJens Axboe 538cd43e26fSMartin K. Petersen if (!q->request_fn) 539cd43e26fSMartin K. Petersen return 0; 540cd43e26fSMartin K. Petersen 5418324aa91SJens Axboe ret = elv_register_queue(q); 5428324aa91SJens Axboe if (ret) { 5438324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 5448324aa91SJens Axboe kobject_del(&q->kobj); 54548c0d4d4SZdenek Kabelac blk_trace_remove_sysfs(disk_to_dev(disk)); 5468324aa91SJens Axboe return ret; 5478324aa91SJens Axboe } 5488324aa91SJens Axboe 5498324aa91SJens Axboe return 0; 5508324aa91SJens Axboe } 5518324aa91SJens Axboe 5528324aa91SJens Axboe void blk_unregister_queue(struct gendisk *disk) 5538324aa91SJens Axboe { 5548324aa91SJens Axboe struct request_queue *q = disk->queue; 5558324aa91SJens Axboe 556fb199746SAkinobu Mita if (WARN_ON(!q)) 557fb199746SAkinobu Mita return; 558fb199746SAkinobu Mita 55948c0d4d4SZdenek Kabelac if (q->request_fn) 5608324aa91SJens Axboe elv_unregister_queue(q); 5618324aa91SJens Axboe 5628324aa91SJens Axboe kobject_uevent(&q->kobj, KOBJ_REMOVE); 5638324aa91SJens Axboe kobject_del(&q->kobj); 56448c0d4d4SZdenek Kabelac blk_trace_remove_sysfs(disk_to_dev(disk)); 565ed9e1982STejun Heo kobject_put(&disk_to_dev(disk)->kobj); 5668324aa91SJens Axboe } 567