Blame view

block/blk-sysfs.c 18.5 KB
8324aa91d   Jens Axboe   block: split tag ...
1
2
3
4
  /*
   * Functions related to sysfs handling
   */
  #include <linux/kernel.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
5
  #include <linux/slab.h>
8324aa91d   Jens Axboe   block: split tag ...
6
7
8
  #include <linux/module.h>
  #include <linux/bio.h>
  #include <linux/blkdev.h>
66114cad6   Tejun Heo   writeback: separa...
9
  #include <linux/backing-dev.h>
8324aa91d   Jens Axboe   block: split tag ...
10
  #include <linux/blktrace_api.h>
320ae51fe   Jens Axboe   blk-mq: new multi...
11
  #include <linux/blk-mq.h>
eea8f41cc   Tejun Heo   blkcg: move block...
12
  #include <linux/blk-cgroup.h>
8324aa91d   Jens Axboe   block: split tag ...
13
14
  
  #include "blk.h"
3edcc0ce8   Ming Lei   block: blk-mq: do...
15
  #include "blk-mq.h"
8324aa91d   Jens Axboe   block: split tag ...
16
17
18
19
20
21
22
23
  
  struct queue_sysfs_entry {
  	struct attribute attr;
  	ssize_t (*show)(struct request_queue *, char *);
  	ssize_t (*store)(struct request_queue *, const char *, size_t);
  };
  
  static ssize_t
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
24
  queue_var_show(unsigned long var, char *page)
8324aa91d   Jens Axboe   block: split tag ...
25
  {
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
26
27
  	return sprintf(page, "%lu
  ", var);
8324aa91d   Jens Axboe   block: split tag ...
28
29
30
31
32
  }
  
  static ssize_t
  queue_var_store(unsigned long *var, const char *page, size_t count)
  {
b1f3b64d7   Dave Reisner   block: reject inv...
33
34
  	int err;
  	unsigned long v;
ed751e683   Jingoo Han   block/blk-sysfs.c...
35
  	err = kstrtoul(page, 10, &v);
b1f3b64d7   Dave Reisner   block: reject inv...
36
37
38
39
  	if (err || v > UINT_MAX)
  		return -EINVAL;
  
  	*var = v;
8324aa91d   Jens Axboe   block: split tag ...
40

8324aa91d   Jens Axboe   block: split tag ...
41
42
43
44
45
46
47
48
49
50
51
  	return count;
  }
  
  static ssize_t queue_requests_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(q->nr_requests, (page));
  }
  
  static ssize_t
  queue_requests_store(struct request_queue *q, const char *page, size_t count)
  {
8324aa91d   Jens Axboe   block: split tag ...
52
  	unsigned long nr;
e3a2b3f93   Jens Axboe   blk-mq: allow cha...
53
  	int ret, err;
b8a9ae779   Jens Axboe   block: don't assu...
54

e3a2b3f93   Jens Axboe   blk-mq: allow cha...
55
  	if (!q->request_fn && !q->mq_ops)
b8a9ae779   Jens Axboe   block: don't assu...
56
57
58
  		return -EINVAL;
  
  	ret = queue_var_store(&nr, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
59
60
  	if (ret < 0)
  		return ret;
8324aa91d   Jens Axboe   block: split tag ...
61
62
  	if (nr < BLKDEV_MIN_RQ)
  		nr = BLKDEV_MIN_RQ;
e3a2b3f93   Jens Axboe   blk-mq: allow cha...
63
64
65
66
67
68
69
  	if (q->request_fn)
  		err = blk_update_nr_requests(q, nr);
  	else
  		err = blk_mq_update_nr_requests(q, nr);
  
  	if (err)
  		return err;
8324aa91d   Jens Axboe   block: split tag ...
70
71
72
73
74
  	return ret;
  }
  
  static ssize_t queue_ra_show(struct request_queue *q, char *page)
  {
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
75
  	unsigned long ra_kb = q->backing_dev_info.ra_pages <<
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
76
  					(PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
77
78
79
80
81
82
83
84
85
  
  	return queue_var_show(ra_kb, (page));
  }
  
  static ssize_t
  queue_ra_store(struct request_queue *q, const char *page, size_t count)
  {
  	unsigned long ra_kb;
  	ssize_t ret = queue_var_store(&ra_kb, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
86
87
  	if (ret < 0)
  		return ret;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
88
  	q->backing_dev_info.ra_pages = ra_kb >> (PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
89
90
91
92
93
94
  
  	return ret;
  }
  
  static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
  {
ae03bf639   Martin K. Petersen   block: Use access...
95
  	int max_sectors_kb = queue_max_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
96
97
98
  
  	return queue_var_show(max_sectors_kb, (page));
  }
c77a5710b   Martin K. Petersen   block: Export max...
99
100
101
102
  static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_max_segments(q), (page));
  }
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
103
104
105
106
  static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(q->limits.max_integrity_segments, (page));
  }
c77a5710b   Martin K. Petersen   block: Export max...
107
108
  static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
  {
e692cb668   Martin K. Petersen   block: Deprecate ...
109
  	if (blk_queue_cluster(q))
c77a5710b   Martin K. Petersen   block: Export max...
110
  		return queue_var_show(queue_max_segment_size(q), (page));
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
111
  	return queue_var_show(PAGE_SIZE, (page));
c77a5710b   Martin K. Petersen   block: Export max...
112
  }
e1defc4ff   Martin K. Petersen   block: Do away wi...
113
  static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
e68b903c6   Martin K. Petersen   Expose hardware s...
114
  {
e1defc4ff   Martin K. Petersen   block: Do away wi...
115
  	return queue_var_show(queue_logical_block_size(q), page);
e68b903c6   Martin K. Petersen   Expose hardware s...
116
  }
c72758f33   Martin K. Petersen   block: Export I/O...
117
118
119
120
121
122
123
124
125
126
127
128
129
  static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_physical_block_size(q), page);
  }
  
  static ssize_t queue_io_min_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_io_min(q), page);
  }
  
  static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_io_opt(q), page);
e68b903c6   Martin K. Petersen   Expose hardware s...
130
  }
86b372814   Martin K. Petersen   block: Expose dis...
131
132
133
134
  static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(q->limits.discard_granularity, page);
  }
0034af036   Jens Axboe   block: make /sys/...
135
136
  static ssize_t queue_discard_max_hw_show(struct request_queue *q, char *page)
  {
0034af036   Jens Axboe   block: make /sys/...
137

18f922d03   Alan   blk: fix overflow...
138
139
140
  	return sprintf(page, "%llu
  ",
  		(unsigned long long)q->limits.max_hw_discard_sectors << 9);
0034af036   Jens Axboe   block: make /sys/...
141
  }
86b372814   Martin K. Petersen   block: Expose dis...
142
143
  static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
  {
a934a00a6   Martin K. Petersen   block: Fix discar...
144
145
146
  	return sprintf(page, "%llu
  ",
  		       (unsigned long long)q->limits.max_discard_sectors << 9);
86b372814   Martin K. Petersen   block: Expose dis...
147
  }
0034af036   Jens Axboe   block: make /sys/...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  static ssize_t queue_discard_max_store(struct request_queue *q,
  				       const char *page, size_t count)
  {
  	unsigned long max_discard;
  	ssize_t ret = queue_var_store(&max_discard, page, count);
  
  	if (ret < 0)
  		return ret;
  
  	if (max_discard & (q->limits.discard_granularity - 1))
  		return -EINVAL;
  
  	max_discard >>= 9;
  	if (max_discard > UINT_MAX)
  		return -EINVAL;
  
  	if (max_discard > q->limits.max_hw_discard_sectors)
  		max_discard = q->limits.max_hw_discard_sectors;
  
  	q->limits.max_discard_sectors = max_discard;
  	return ret;
  }
98262f276   Martin K. Petersen   block: Allow devi...
170
171
172
173
  static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_discard_zeroes_data(q), page);
  }
4363ac7c1   Martin K. Petersen   block: Implement ...
174
175
176
177
178
179
  static ssize_t queue_write_same_max_show(struct request_queue *q, char *page)
  {
  	return sprintf(page, "%llu
  ",
  		(unsigned long long)q->limits.max_write_same_sectors << 9);
  }
8324aa91d   Jens Axboe   block: split tag ...
180
181
182
183
  static ssize_t
  queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
  {
  	unsigned long max_sectors_kb,
ae03bf639   Martin K. Petersen   block: Use access...
184
  		max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1,
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
185
  			page_kb = 1 << (PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
186
  	ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
187
188
  	if (ret < 0)
  		return ret;
ca369d51b   Martin K. Petersen   block/sd: Fix dev...
189
190
  	max_hw_sectors_kb = min_not_zero(max_hw_sectors_kb, (unsigned long)
  					 q->limits.max_dev_sectors >> 1);
8324aa91d   Jens Axboe   block: split tag ...
191
192
  	if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
  		return -EINVAL;
7c239517d   Wu Fengguang   block: don't take...
193

8324aa91d   Jens Axboe   block: split tag ...
194
  	spin_lock_irq(q->queue_lock);
c295fc057   Nikanth Karthikesan   block: Allow chan...
195
  	q->limits.max_sectors = max_sectors_kb << 1;
8324aa91d   Jens Axboe   block: split tag ...
196
197
198
199
200
201
202
  	spin_unlock_irq(q->queue_lock);
  
  	return ret;
  }
  
  static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
  {
ae03bf639   Martin K. Petersen   block: Use access...
203
  	int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
204
205
206
  
  	return queue_var_show(max_hw_sectors_kb, (page));
  }
956bcb7c1   Jens Axboe   block: add helper...
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  #define QUEUE_SYSFS_BIT_FNS(name, flag, neg)				\
  static ssize_t								\
  queue_show_##name(struct request_queue *q, char *page)			\
  {									\
  	int bit;							\
  	bit = test_bit(QUEUE_FLAG_##flag, &q->queue_flags);		\
  	return queue_var_show(neg ? !bit : bit, page);			\
  }									\
  static ssize_t								\
  queue_store_##name(struct request_queue *q, const char *page, size_t count) \
  {									\
  	unsigned long val;						\
  	ssize_t ret;							\
  	ret = queue_var_store(&val, page, count);			\
c678ef528   Arnd Bergmann   block: avoid usin...
221
222
  	if (ret < 0)							\
  		 return ret;						\
956bcb7c1   Jens Axboe   block: add helper...
223
224
225
226
227
228
229
230
231
232
  	if (neg)							\
  		val = !val;						\
  									\
  	spin_lock_irq(q->queue_lock);					\
  	if (val)							\
  		queue_flag_set(QUEUE_FLAG_##flag, q);			\
  	else								\
  		queue_flag_clear(QUEUE_FLAG_##flag, q);			\
  	spin_unlock_irq(q->queue_lock);					\
  	return ret;							\
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
233
  }
956bcb7c1   Jens Axboe   block: add helper...
234
235
236
237
  QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1);
  QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0);
  QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0);
  #undef QUEUE_SYSFS_BIT_FNS
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
238

ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
239
240
  static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
  {
488991e28   Alan D. Brunelle   block: Added in s...
241
242
  	return queue_var_show((blk_queue_nomerges(q) << 1) |
  			       blk_queue_noxmerges(q), page);
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
243
244
245
246
247
248
249
  }
  
  static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
  				    size_t count)
  {
  	unsigned long nm;
  	ssize_t ret = queue_var_store(&nm, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
250
251
  	if (ret < 0)
  		return ret;
bf0f97025   Jens Axboe   block: sysfs stor...
252
  	spin_lock_irq(q->queue_lock);
488991e28   Alan D. Brunelle   block: Added in s...
253
254
255
  	queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
  	queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
  	if (nm == 2)
bf0f97025   Jens Axboe   block: sysfs stor...
256
  		queue_flag_set(QUEUE_FLAG_NOMERGES, q);
488991e28   Alan D. Brunelle   block: Added in s...
257
258
  	else if (nm)
  		queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
bf0f97025   Jens Axboe   block: sysfs stor...
259
  	spin_unlock_irq(q->queue_lock);
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
260

ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
261
262
  	return ret;
  }
c7c22e4d5   Jens Axboe   block: add suppor...
263
264
  static ssize_t queue_rq_affinity_show(struct request_queue *q, char *page)
  {
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
265
  	bool set = test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags);
5757a6d76   Dan Williams   block: strict rq_...
266
  	bool force = test_bit(QUEUE_FLAG_SAME_FORCE, &q->queue_flags);
c7c22e4d5   Jens Axboe   block: add suppor...
267

5757a6d76   Dan Williams   block: strict rq_...
268
  	return queue_var_show(set << force, page);
c7c22e4d5   Jens Axboe   block: add suppor...
269
270
271
272
273
274
  }
  
  static ssize_t
  queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count)
  {
  	ssize_t ret = -EINVAL;
0a06ff068   Christoph Hellwig   kernel: remove CO...
275
  #ifdef CONFIG_SMP
c7c22e4d5   Jens Axboe   block: add suppor...
276
277
278
  	unsigned long val;
  
  	ret = queue_var_store(&val, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
279
280
  	if (ret < 0)
  		return ret;
c7c22e4d5   Jens Axboe   block: add suppor...
281
  	spin_lock_irq(q->queue_lock);
e8037d498   Eric Seppanen   block: Fix queue_...
282
  	if (val == 2) {
c7c22e4d5   Jens Axboe   block: add suppor...
283
  		queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
e8037d498   Eric Seppanen   block: Fix queue_...
284
285
286
287
288
  		queue_flag_set(QUEUE_FLAG_SAME_FORCE, q);
  	} else if (val == 1) {
  		queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
  		queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q);
  	} else if (val == 0) {
5757a6d76   Dan Williams   block: strict rq_...
289
290
291
  		queue_flag_clear(QUEUE_FLAG_SAME_COMP, q);
  		queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q);
  	}
c7c22e4d5   Jens Axboe   block: add suppor...
292
293
294
295
  	spin_unlock_irq(q->queue_lock);
  #endif
  	return ret;
  }
8324aa91d   Jens Axboe   block: split tag ...
296

05229beed   Jens Axboe   block: add block ...
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  static ssize_t queue_poll_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(test_bit(QUEUE_FLAG_POLL, &q->queue_flags), page);
  }
  
  static ssize_t queue_poll_store(struct request_queue *q, const char *page,
  				size_t count)
  {
  	unsigned long poll_on;
  	ssize_t ret;
  
  	if (!q->mq_ops || !q->mq_ops->poll)
  		return -EINVAL;
  
  	ret = queue_var_store(&poll_on, page, count);
  	if (ret < 0)
  		return ret;
  
  	spin_lock_irq(q->queue_lock);
  	if (poll_on)
  		queue_flag_set(QUEUE_FLAG_POLL, q);
  	else
  		queue_flag_clear(QUEUE_FLAG_POLL, q);
  	spin_unlock_irq(q->queue_lock);
  
  	return ret;
  }
93e9d8e83   Jens Axboe   block: add abilit...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  static ssize_t queue_wc_show(struct request_queue *q, char *page)
  {
  	if (test_bit(QUEUE_FLAG_WC, &q->queue_flags))
  		return sprintf(page, "write back
  ");
  
  	return sprintf(page, "write through
  ");
  }
  
  static ssize_t queue_wc_store(struct request_queue *q, const char *page,
  			      size_t count)
  {
  	int set = -1;
  
  	if (!strncmp(page, "write back", 10))
  		set = 1;
  	else if (!strncmp(page, "write through", 13) ||
  		 !strncmp(page, "none", 4))
  		set = 0;
  
  	if (set == -1)
  		return -EINVAL;
  
  	spin_lock_irq(q->queue_lock);
  	if (set)
  		queue_flag_set(QUEUE_FLAG_WC, q);
  	else
  		queue_flag_clear(QUEUE_FLAG_WC, q);
  	spin_unlock_irq(q->queue_lock);
  
  	return count;
  }
ea6ca600e   Yigal Korman   block: expose QUE...
357
358
359
360
  static ssize_t queue_dax_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(blk_queue_dax(q), page);
  }
8324aa91d   Jens Axboe   block: split tag ...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
  static struct queue_sysfs_entry queue_requests_entry = {
  	.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_requests_show,
  	.store = queue_requests_store,
  };
  
  static struct queue_sysfs_entry queue_ra_entry = {
  	.attr = {.name = "read_ahead_kb", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_ra_show,
  	.store = queue_ra_store,
  };
  
  static struct queue_sysfs_entry queue_max_sectors_entry = {
  	.attr = {.name = "max_sectors_kb", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_max_sectors_show,
  	.store = queue_max_sectors_store,
  };
  
  static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
  	.attr = {.name = "max_hw_sectors_kb", .mode = S_IRUGO },
  	.show = queue_max_hw_sectors_show,
  };
c77a5710b   Martin K. Petersen   block: Export max...
383
384
385
386
  static struct queue_sysfs_entry queue_max_segments_entry = {
  	.attr = {.name = "max_segments", .mode = S_IRUGO },
  	.show = queue_max_segments_show,
  };
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
387
388
389
390
  static struct queue_sysfs_entry queue_max_integrity_segments_entry = {
  	.attr = {.name = "max_integrity_segments", .mode = S_IRUGO },
  	.show = queue_max_integrity_segments_show,
  };
c77a5710b   Martin K. Petersen   block: Export max...
391
392
393
394
  static struct queue_sysfs_entry queue_max_segment_size_entry = {
  	.attr = {.name = "max_segment_size", .mode = S_IRUGO },
  	.show = queue_max_segment_size_show,
  };
8324aa91d   Jens Axboe   block: split tag ...
395
396
397
398
399
  static struct queue_sysfs_entry queue_iosched_entry = {
  	.attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
  	.show = elv_iosched_show,
  	.store = elv_iosched_store,
  };
e68b903c6   Martin K. Petersen   Expose hardware s...
400
401
  static struct queue_sysfs_entry queue_hw_sector_size_entry = {
  	.attr = {.name = "hw_sector_size", .mode = S_IRUGO },
e1defc4ff   Martin K. Petersen   block: Do away wi...
402
403
404
405
406
407
  	.show = queue_logical_block_size_show,
  };
  
  static struct queue_sysfs_entry queue_logical_block_size_entry = {
  	.attr = {.name = "logical_block_size", .mode = S_IRUGO },
  	.show = queue_logical_block_size_show,
e68b903c6   Martin K. Petersen   Expose hardware s...
408
  };
c72758f33   Martin K. Petersen   block: Export I/O...
409
410
411
412
413
414
415
416
417
418
419
420
421
  static struct queue_sysfs_entry queue_physical_block_size_entry = {
  	.attr = {.name = "physical_block_size", .mode = S_IRUGO },
  	.show = queue_physical_block_size_show,
  };
  
  static struct queue_sysfs_entry queue_io_min_entry = {
  	.attr = {.name = "minimum_io_size", .mode = S_IRUGO },
  	.show = queue_io_min_show,
  };
  
  static struct queue_sysfs_entry queue_io_opt_entry = {
  	.attr = {.name = "optimal_io_size", .mode = S_IRUGO },
  	.show = queue_io_opt_show,
e68b903c6   Martin K. Petersen   Expose hardware s...
422
  };
86b372814   Martin K. Petersen   block: Expose dis...
423
424
425
426
  static struct queue_sysfs_entry queue_discard_granularity_entry = {
  	.attr = {.name = "discard_granularity", .mode = S_IRUGO },
  	.show = queue_discard_granularity_show,
  };
0034af036   Jens Axboe   block: make /sys/...
427
428
429
430
  static struct queue_sysfs_entry queue_discard_max_hw_entry = {
  	.attr = {.name = "discard_max_hw_bytes", .mode = S_IRUGO },
  	.show = queue_discard_max_hw_show,
  };
86b372814   Martin K. Petersen   block: Expose dis...
431
  static struct queue_sysfs_entry queue_discard_max_entry = {
0034af036   Jens Axboe   block: make /sys/...
432
  	.attr = {.name = "discard_max_bytes", .mode = S_IRUGO | S_IWUSR },
86b372814   Martin K. Petersen   block: Expose dis...
433
  	.show = queue_discard_max_show,
0034af036   Jens Axboe   block: make /sys/...
434
  	.store = queue_discard_max_store,
86b372814   Martin K. Petersen   block: Expose dis...
435
  };
98262f276   Martin K. Petersen   block: Allow devi...
436
437
438
439
  static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
  	.attr = {.name = "discard_zeroes_data", .mode = S_IRUGO },
  	.show = queue_discard_zeroes_data_show,
  };
4363ac7c1   Martin K. Petersen   block: Implement ...
440
441
442
443
  static struct queue_sysfs_entry queue_write_same_max_entry = {
  	.attr = {.name = "write_same_max_bytes", .mode = S_IRUGO },
  	.show = queue_write_same_max_show,
  };
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
444
445
  static struct queue_sysfs_entry queue_nonrot_entry = {
  	.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
446
447
  	.show = queue_show_nonrot,
  	.store = queue_store_nonrot,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
448
  };
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
449
450
451
452
453
  static struct queue_sysfs_entry queue_nomerges_entry = {
  	.attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_nomerges_show,
  	.store = queue_nomerges_store,
  };
c7c22e4d5   Jens Axboe   block: add suppor...
454
455
456
457
458
  static struct queue_sysfs_entry queue_rq_affinity_entry = {
  	.attr = {.name = "rq_affinity", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_rq_affinity_show,
  	.store = queue_rq_affinity_store,
  };
bc58ba946   Jens Axboe   block: add sysfs ...
459
460
  static struct queue_sysfs_entry queue_iostats_entry = {
  	.attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
461
462
  	.show = queue_show_iostats,
  	.store = queue_store_iostats,
bc58ba946   Jens Axboe   block: add sysfs ...
463
  };
e2e1a148b   Jens Axboe   block: add sysfs ...
464
465
  static struct queue_sysfs_entry queue_random_entry = {
  	.attr = {.name = "add_random", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
466
467
  	.show = queue_show_random,
  	.store = queue_store_random,
e2e1a148b   Jens Axboe   block: add sysfs ...
468
  };
05229beed   Jens Axboe   block: add block ...
469
470
471
472
473
  static struct queue_sysfs_entry queue_poll_entry = {
  	.attr = {.name = "io_poll", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_poll_show,
  	.store = queue_poll_store,
  };
93e9d8e83   Jens Axboe   block: add abilit...
474
475
476
477
478
  static struct queue_sysfs_entry queue_wc_entry = {
  	.attr = {.name = "write_cache", .mode = S_IRUGO | S_IWUSR },
  	.show = queue_wc_show,
  	.store = queue_wc_store,
  };
ea6ca600e   Yigal Korman   block: expose QUE...
479
480
481
482
  static struct queue_sysfs_entry queue_dax_entry = {
  	.attr = {.name = "dax", .mode = S_IRUGO },
  	.show = queue_dax_show,
  };
8324aa91d   Jens Axboe   block: split tag ...
483
484
485
486
487
  static struct attribute *default_attrs[] = {
  	&queue_requests_entry.attr,
  	&queue_ra_entry.attr,
  	&queue_max_hw_sectors_entry.attr,
  	&queue_max_sectors_entry.attr,
c77a5710b   Martin K. Petersen   block: Export max...
488
  	&queue_max_segments_entry.attr,
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
489
  	&queue_max_integrity_segments_entry.attr,
c77a5710b   Martin K. Petersen   block: Export max...
490
  	&queue_max_segment_size_entry.attr,
8324aa91d   Jens Axboe   block: split tag ...
491
  	&queue_iosched_entry.attr,
e68b903c6   Martin K. Petersen   Expose hardware s...
492
  	&queue_hw_sector_size_entry.attr,
e1defc4ff   Martin K. Petersen   block: Do away wi...
493
  	&queue_logical_block_size_entry.attr,
c72758f33   Martin K. Petersen   block: Export I/O...
494
495
496
  	&queue_physical_block_size_entry.attr,
  	&queue_io_min_entry.attr,
  	&queue_io_opt_entry.attr,
86b372814   Martin K. Petersen   block: Expose dis...
497
498
  	&queue_discard_granularity_entry.attr,
  	&queue_discard_max_entry.attr,
0034af036   Jens Axboe   block: make /sys/...
499
  	&queue_discard_max_hw_entry.attr,
98262f276   Martin K. Petersen   block: Allow devi...
500
  	&queue_discard_zeroes_data_entry.attr,
4363ac7c1   Martin K. Petersen   block: Implement ...
501
  	&queue_write_same_max_entry.attr,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
502
  	&queue_nonrot_entry.attr,
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
503
  	&queue_nomerges_entry.attr,
c7c22e4d5   Jens Axboe   block: add suppor...
504
  	&queue_rq_affinity_entry.attr,
bc58ba946   Jens Axboe   block: add sysfs ...
505
  	&queue_iostats_entry.attr,
e2e1a148b   Jens Axboe   block: add sysfs ...
506
  	&queue_random_entry.attr,
05229beed   Jens Axboe   block: add block ...
507
  	&queue_poll_entry.attr,
93e9d8e83   Jens Axboe   block: add abilit...
508
  	&queue_wc_entry.attr,
ea6ca600e   Yigal Korman   block: expose QUE...
509
  	&queue_dax_entry.attr,
8324aa91d   Jens Axboe   block: split tag ...
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
  	NULL,
  };
  
  #define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr)
  
  static ssize_t
  queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
  {
  	struct queue_sysfs_entry *entry = to_queue(attr);
  	struct request_queue *q =
  		container_of(kobj, struct request_queue, kobj);
  	ssize_t res;
  
  	if (!entry->show)
  		return -EIO;
  	mutex_lock(&q->sysfs_lock);
3f3299d5c   Bart Van Assche   block: Rename que...
526
  	if (blk_queue_dying(q)) {
8324aa91d   Jens Axboe   block: split tag ...
527
528
529
530
531
532
533
534
535
536
537
538
539
  		mutex_unlock(&q->sysfs_lock);
  		return -ENOENT;
  	}
  	res = entry->show(q, page);
  	mutex_unlock(&q->sysfs_lock);
  	return res;
  }
  
  static ssize_t
  queue_attr_store(struct kobject *kobj, struct attribute *attr,
  		    const char *page, size_t length)
  {
  	struct queue_sysfs_entry *entry = to_queue(attr);
6728cb0e6   Jens Axboe   block: make core ...
540
  	struct request_queue *q;
8324aa91d   Jens Axboe   block: split tag ...
541
542
543
544
  	ssize_t res;
  
  	if (!entry->store)
  		return -EIO;
6728cb0e6   Jens Axboe   block: make core ...
545
546
  
  	q = container_of(kobj, struct request_queue, kobj);
8324aa91d   Jens Axboe   block: split tag ...
547
  	mutex_lock(&q->sysfs_lock);
3f3299d5c   Bart Van Assche   block: Rename que...
548
  	if (blk_queue_dying(q)) {
8324aa91d   Jens Axboe   block: split tag ...
549
550
551
552
553
554
555
  		mutex_unlock(&q->sysfs_lock);
  		return -ENOENT;
  	}
  	res = entry->store(q, page, length);
  	mutex_unlock(&q->sysfs_lock);
  	return res;
  }
548bc8e1b   Tejun Heo   block: RCU free r...
556
557
558
559
560
561
  static void blk_free_queue_rcu(struct rcu_head *rcu_head)
  {
  	struct request_queue *q = container_of(rcu_head, struct request_queue,
  					       rcu_head);
  	kmem_cache_free(blk_requestq_cachep, q);
  }
8324aa91d   Jens Axboe   block: split tag ...
562
  /**
499337bb6   Andrew Morton   block/blk-sysfs.c...
563
564
   * blk_release_queue: - release a &struct request_queue when it is no longer needed
   * @kobj:    the kobj belonging to the request queue to be released
8324aa91d   Jens Axboe   block: split tag ...
565
566
   *
   * Description:
499337bb6   Andrew Morton   block/blk-sysfs.c...
567
   *     blk_release_queue is the pair to blk_init_queue() or
8324aa91d   Jens Axboe   block: split tag ...
568
569
570
571
572
   *     blk_queue_make_request().  It should be called when a request queue is
   *     being released; typically when a block device is being de-registered.
   *     Currently, its primary task it to free all the &struct request
   *     structures that were allocated to the queue and the queue itself.
   *
45a9c9d90   Bart Van Assche   blk-mq: Fix a use...
573
574
575
   * Note:
   *     The low level driver must have finished any outstanding requests first
   *     via blk_cleanup_queue().
8324aa91d   Jens Axboe   block: split tag ...
576
577
578
579
580
   **/
  static void blk_release_queue(struct kobject *kobj)
  {
  	struct request_queue *q =
  		container_of(kobj, struct request_queue, kobj);
8324aa91d   Jens Axboe   block: split tag ...
581

b02176f30   Tejun Heo   block: don't rele...
582
  	bdi_exit(&q->backing_dev_info);
e8989fae3   Tejun Heo   blkcg: unify blkg...
583
  	blkcg_exit_queue(q);
7e5a87944   Tejun Heo   block, cfq: move ...
584
585
586
587
  	if (q->elevator) {
  		spin_lock_irq(q->queue_lock);
  		ioc_clear_queue(q);
  		spin_unlock_irq(q->queue_lock);
777eb1bf1   Hannes Reinecke   block: Free queue...
588
  		elevator_exit(q->elevator);
7e5a87944   Tejun Heo   block, cfq: move ...
589
  	}
777eb1bf1   Hannes Reinecke   block: Free queue...
590

a051661ca   Tejun Heo   blkcg: implement ...
591
  	blk_exit_rl(&q->root_rl);
8324aa91d   Jens Axboe   block: split tag ...
592
593
594
  
  	if (q->queue_tags)
  		__blk_queue_free_tags(q);
45a9c9d90   Bart Van Assche   blk-mq: Fix a use...
595
  	if (!q->mq_ops)
f70ced091   Ming Lei   blk-mq: support p...
596
  		blk_free_flush_queue(q->fq);
e09aae7ed   Ming Lei   blk-mq: release m...
597
598
  	else
  		blk_mq_release(q);
18741986a   Christoph Hellwig   blk-mq: rework fl...
599

8324aa91d   Jens Axboe   block: split tag ...
600
  	blk_trace_shutdown(q);
54efd50bf   Kent Overstreet   block: make gener...
601
602
  	if (q->bio_split)
  		bioset_free(q->bio_split);
a73f730d0   Tejun Heo   block, cfq: move ...
603
  	ida_simple_remove(&blk_queue_ida, q->id);
548bc8e1b   Tejun Heo   block: RCU free r...
604
  	call_rcu(&q->rcu_head, blk_free_queue_rcu);
8324aa91d   Jens Axboe   block: split tag ...
605
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
606
  static const struct sysfs_ops queue_sysfs_ops = {
8324aa91d   Jens Axboe   block: split tag ...
607
608
609
610
611
612
613
614
615
616
617
618
619
  	.show	= queue_attr_show,
  	.store	= queue_attr_store,
  };
  
  struct kobj_type blk_queue_ktype = {
  	.sysfs_ops	= &queue_sysfs_ops,
  	.default_attrs	= default_attrs,
  	.release	= blk_release_queue,
  };
  
  int blk_register_queue(struct gendisk *disk)
  {
  	int ret;
1d54ad6da   Li Zefan   blktrace: add tra...
620
  	struct device *dev = disk_to_dev(disk);
8324aa91d   Jens Axboe   block: split tag ...
621
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
622
  	if (WARN_ON(!q))
8324aa91d   Jens Axboe   block: split tag ...
623
  		return -ENXIO;
749fefe67   Tejun Heo   block: lift the i...
624
  	/*
17497acbd   Tejun Heo   blk-mq, percpu_re...
625
626
627
628
629
630
631
  	 * SCSI probing may synchronously create and destroy a lot of
  	 * request_queues for non-existent devices.  Shutting down a fully
  	 * functional queue takes measureable wallclock time as RCU grace
  	 * periods are involved.  To avoid excessive latency in these
  	 * cases, a request_queue starts out in a degraded mode which is
  	 * faster to shut down and is made fully functional here as
  	 * request_queues for non-existent devices never get registered.
749fefe67   Tejun Heo   block: lift the i...
632
  	 */
df35c7c91   Alan Stern   Block: fix unbala...
633
634
  	if (!blk_queue_init_done(q)) {
  		queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q);
3ef28e83a   Dan Williams   block: generic re...
635
  		percpu_ref_switch_to_percpu(&q->q_usage_counter);
df35c7c91   Alan Stern   Block: fix unbala...
636
637
  		blk_queue_bypass_end(q);
  	}
749fefe67   Tejun Heo   block: lift the i...
638

1d54ad6da   Li Zefan   blktrace: add tra...
639
640
641
  	ret = blk_trace_init_sysfs(dev);
  	if (ret)
  		return ret;
c9059598e   Linus Torvalds   Merge branch 'for...
642
  	ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue");
ed5302d3c   Liu Yuan   block, blk-sysfs:...
643
644
  	if (ret < 0) {
  		blk_trace_remove_sysfs(dev);
8324aa91d   Jens Axboe   block: split tag ...
645
  		return ret;
ed5302d3c   Liu Yuan   block, blk-sysfs:...
646
  	}
8324aa91d   Jens Axboe   block: split tag ...
647
648
  
  	kobject_uevent(&q->kobj, KOBJ_ADD);
320ae51fe   Jens Axboe   blk-mq: new multi...
649
  	if (q->mq_ops)
b21d5b301   Matias Bjørling   blk-mq: register ...
650
  		blk_mq_register_dev(dev, q);
320ae51fe   Jens Axboe   blk-mq: new multi...
651

cd43e26f0   Martin K. Petersen   block: Expose sta...
652
653
  	if (!q->request_fn)
  		return 0;
8324aa91d   Jens Axboe   block: split tag ...
654
655
656
657
  	ret = elv_register_queue(q);
  	if (ret) {
  		kobject_uevent(&q->kobj, KOBJ_REMOVE);
  		kobject_del(&q->kobj);
80656b67b   Liu Yuan   block, blk-sysfs:...
658
  		blk_trace_remove_sysfs(dev);
c87ffbb81   Xiaotian Feng   block: put dev->k...
659
  		kobject_put(&dev->kobj);
8324aa91d   Jens Axboe   block: split tag ...
660
661
662
663
664
665
666
667
668
  		return ret;
  	}
  
  	return 0;
  }
  
  void blk_unregister_queue(struct gendisk *disk)
  {
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
669
670
  	if (WARN_ON(!q))
  		return;
320ae51fe   Jens Axboe   blk-mq: new multi...
671
  	if (q->mq_ops)
b21d5b301   Matias Bjørling   blk-mq: register ...
672
  		blk_mq_unregister_dev(disk_to_dev(disk), q);
320ae51fe   Jens Axboe   blk-mq: new multi...
673

48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
674
  	if (q->request_fn)
8324aa91d   Jens Axboe   block: split tag ...
675
  		elv_unregister_queue(q);
48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
676
677
678
679
  	kobject_uevent(&q->kobj, KOBJ_REMOVE);
  	kobject_del(&q->kobj);
  	blk_trace_remove_sysfs(disk_to_dev(disk));
  	kobject_put(&disk_to_dev(disk)->kobj);
8324aa91d   Jens Axboe   block: split tag ...
680
  }