Blame view

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

8324aa91d   Jens Axboe   block: split tag ...
44
45
  	return count;
  }
80e091d10   Jens Axboe   blk-wbt: allow re...
46
  static ssize_t queue_var_store64(s64 *var, const char *page)
87760e5ee   Jens Axboe   block: hook up wr...
47
48
  {
  	int err;
80e091d10   Jens Axboe   blk-wbt: allow re...
49
  	s64 v;
87760e5ee   Jens Axboe   block: hook up wr...
50

80e091d10   Jens Axboe   blk-wbt: allow re...
51
  	err = kstrtos64(page, 10, &v);
87760e5ee   Jens Axboe   block: hook up wr...
52
53
54
55
56
57
  	if (err < 0)
  		return err;
  
  	*var = v;
  	return 0;
  }
8324aa91d   Jens Axboe   block: split tag ...
58
59
60
61
62
63
64
65
  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 ...
66
  	unsigned long nr;
e3a2b3f93   Jens Axboe   blk-mq: allow cha...
67
  	int ret, err;
b8a9ae779   Jens Axboe   block: don't assu...
68

e3a2b3f93   Jens Axboe   blk-mq: allow cha...
69
  	if (!q->request_fn && !q->mq_ops)
b8a9ae779   Jens Axboe   block: don't assu...
70
71
72
  		return -EINVAL;
  
  	ret = queue_var_store(&nr, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
73
74
  	if (ret < 0)
  		return ret;
8324aa91d   Jens Axboe   block: split tag ...
75
76
  	if (nr < BLKDEV_MIN_RQ)
  		nr = BLKDEV_MIN_RQ;
e3a2b3f93   Jens Axboe   blk-mq: allow cha...
77
78
79
80
81
82
83
  	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 ...
84
85
86
87
88
  	return ret;
  }
  
  static ssize_t queue_ra_show(struct request_queue *q, char *page)
  {
dc3b17cc8   Jan Kara   block: Use pointe...
89
  	unsigned long ra_kb = q->backing_dev_info->ra_pages <<
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
90
  					(PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
91
92
93
94
95
96
97
98
99
  
  	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...
100
101
  	if (ret < 0)
  		return ret;
dc3b17cc8   Jan Kara   block: Use pointe...
102
  	q->backing_dev_info->ra_pages = ra_kb >> (PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
103
104
105
106
107
108
  
  	return ret;
  }
  
  static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
  {
ae03bf639   Martin K. Petersen   block: Use access...
109
  	int max_sectors_kb = queue_max_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
110
111
112
  
  	return queue_var_show(max_sectors_kb, (page));
  }
c77a5710b   Martin K. Petersen   block: Export max...
113
114
115
116
  static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_max_segments(q), (page));
  }
1e739730c   Christoph Hellwig   block: optionally...
117
118
119
120
121
  static ssize_t queue_max_discard_segments_show(struct request_queue *q,
  		char *page)
  {
  	return queue_var_show(queue_max_discard_segments(q), (page));
  }
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
122
123
124
125
  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...
126
127
  static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
  {
e692cb668   Martin K. Petersen   block: Deprecate ...
128
  	if (blk_queue_cluster(q))
c77a5710b   Martin K. Petersen   block: Export max...
129
  		return queue_var_show(queue_max_segment_size(q), (page));
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
130
  	return queue_var_show(PAGE_SIZE, (page));
c77a5710b   Martin K. Petersen   block: Export max...
131
  }
e1defc4ff   Martin K. Petersen   block: Do away wi...
132
  static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
e68b903c6   Martin K. Petersen   Expose hardware s...
133
  {
e1defc4ff   Martin K. Petersen   block: Do away wi...
134
  	return queue_var_show(queue_logical_block_size(q), page);
e68b903c6   Martin K. Petersen   Expose hardware s...
135
  }
c72758f33   Martin K. Petersen   block: Export I/O...
136
137
138
139
  static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_physical_block_size(q), page);
  }
87caf97cf   Hannes Reinecke   blk-sysfs: Add 'c...
140
141
142
143
  static ssize_t queue_chunk_sectors_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(q->limits.chunk_sectors, page);
  }
c72758f33   Martin K. Petersen   block: Export I/O...
144
145
146
147
148
149
150
151
  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...
152
  }
86b372814   Martin K. Petersen   block: Expose dis...
153
154
155
156
  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/...
157
158
  static ssize_t queue_discard_max_hw_show(struct request_queue *q, char *page)
  {
0034af036   Jens Axboe   block: make /sys/...
159

18f922d03   Alan   blk: fix overflow...
160
161
162
  	return sprintf(page, "%llu
  ",
  		(unsigned long long)q->limits.max_hw_discard_sectors << 9);
0034af036   Jens Axboe   block: make /sys/...
163
  }
86b372814   Martin K. Petersen   block: Expose dis...
164
165
  static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
  {
a934a00a6   Martin K. Petersen   block: Fix discar...
166
167
168
  	return sprintf(page, "%llu
  ",
  		       (unsigned long long)q->limits.max_discard_sectors << 9);
86b372814   Martin K. Petersen   block: Expose dis...
169
  }
0034af036   Jens Axboe   block: make /sys/...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
  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...
192
193
  static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
  {
48920ff2a   Christoph Hellwig   block: remove the...
194
  	return queue_var_show(0, page);
98262f276   Martin K. Petersen   block: Allow devi...
195
  }
4363ac7c1   Martin K. Petersen   block: Implement ...
196
197
198
199
200
201
  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);
  }
a6f0788ec   Chaitanya Kulkarni   block: add suppor...
202
203
204
205
206
207
  static ssize_t queue_write_zeroes_max_show(struct request_queue *q, char *page)
  {
  	return sprintf(page, "%llu
  ",
  		(unsigned long long)q->limits.max_write_zeroes_sectors << 9);
  }
4363ac7c1   Martin K. Petersen   block: Implement ...
208

8324aa91d   Jens Axboe   block: split tag ...
209
210
211
212
  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...
213
  		max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1,
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
214
  			page_kb = 1 << (PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
215
  	ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
216
217
  	if (ret < 0)
  		return ret;
ca369d51b   Martin K. Petersen   block/sd: Fix dev...
218
219
  	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 ...
220
221
  	if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
  		return -EINVAL;
7c239517d   Wu Fengguang   block: don't take...
222

8324aa91d   Jens Axboe   block: split tag ...
223
  	spin_lock_irq(q->queue_lock);
c295fc057   Nikanth Karthikesan   block: Allow chan...
224
  	q->limits.max_sectors = max_sectors_kb << 1;
dc3b17cc8   Jan Kara   block: Use pointe...
225
  	q->backing_dev_info->io_pages = max_sectors_kb >> (PAGE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
226
227
228
229
230
231
232
  	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...
233
  	int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
234
235
236
  
  	return queue_var_show(max_hw_sectors_kb, (page));
  }
956bcb7c1   Jens Axboe   block: add helper...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  #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...
251
252
  	if (ret < 0)							\
  		 return ret;						\
956bcb7c1   Jens Axboe   block: add helper...
253
254
255
  	if (neg)							\
  		val = !val;						\
  									\
956bcb7c1   Jens Axboe   block: add helper...
256
  	if (val)							\
8814ce8a0   Bart Van Assche   block: Introduce ...
257
  		blk_queue_flag_set(QUEUE_FLAG_##flag, q);		\
956bcb7c1   Jens Axboe   block: add helper...
258
  	else								\
8814ce8a0   Bart Van Assche   block: Introduce ...
259
  		blk_queue_flag_clear(QUEUE_FLAG_##flag, q);		\
956bcb7c1   Jens Axboe   block: add helper...
260
  	return ret;							\
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
261
  }
956bcb7c1   Jens Axboe   block: add helper...
262
263
264
265
  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...
266

797476b88   Damien Le Moal   block: Add 'zoned...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  static ssize_t queue_zoned_show(struct request_queue *q, char *page)
  {
  	switch (blk_queue_zoned_model(q)) {
  	case BLK_ZONED_HA:
  		return sprintf(page, "host-aware
  ");
  	case BLK_ZONED_HM:
  		return sprintf(page, "host-managed
  ");
  	default:
  		return sprintf(page, "none
  ");
  	}
  }
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
281
282
  static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
  {
488991e28   Alan D. Brunelle   block: Added in s...
283
284
  	return queue_var_show((blk_queue_nomerges(q) << 1) |
  			       blk_queue_noxmerges(q), page);
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
285
286
287
288
289
290
291
  }
  
  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...
292
293
  	if (ret < 0)
  		return ret;
bf0f97025   Jens Axboe   block: sysfs stor...
294
  	spin_lock_irq(q->queue_lock);
488991e28   Alan D. Brunelle   block: Added in s...
295
296
297
  	queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
  	queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
  	if (nm == 2)
bf0f97025   Jens Axboe   block: sysfs stor...
298
  		queue_flag_set(QUEUE_FLAG_NOMERGES, q);
488991e28   Alan D. Brunelle   block: Added in s...
299
300
  	else if (nm)
  		queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
bf0f97025   Jens Axboe   block: sysfs stor...
301
  	spin_unlock_irq(q->queue_lock);
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
302

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

5757a6d76   Dan Williams   block: strict rq_...
310
  	return queue_var_show(set << force, page);
c7c22e4d5   Jens Axboe   block: add suppor...
311
312
313
314
315
316
  }
  
  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...
317
  #ifdef CONFIG_SMP
c7c22e4d5   Jens Axboe   block: add suppor...
318
319
320
  	unsigned long val;
  
  	ret = queue_var_store(&val, page, count);
b1f3b64d7   Dave Reisner   block: reject inv...
321
322
  	if (ret < 0)
  		return ret;
c7c22e4d5   Jens Axboe   block: add suppor...
323
  	spin_lock_irq(q->queue_lock);
e8037d498   Eric Seppanen   block: Fix queue_...
324
  	if (val == 2) {
c7c22e4d5   Jens Axboe   block: add suppor...
325
  		queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
e8037d498   Eric Seppanen   block: Fix queue_...
326
327
328
329
330
  		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_...
331
332
333
  		queue_flag_clear(QUEUE_FLAG_SAME_COMP, q);
  		queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q);
  	}
c7c22e4d5   Jens Axboe   block: add suppor...
334
335
336
337
  	spin_unlock_irq(q->queue_lock);
  #endif
  	return ret;
  }
8324aa91d   Jens Axboe   block: split tag ...
338

06426adf0   Jens Axboe   blk-mq: implement...
339
340
  static ssize_t queue_poll_delay_show(struct request_queue *q, char *page)
  {
64f1c21e8   Jens Axboe   blk-mq: make the ...
341
342
343
344
345
346
347
348
349
  	int val;
  
  	if (q->poll_nsec == -1)
  		val = -1;
  	else
  		val = q->poll_nsec / 1000;
  
  	return sprintf(page, "%d
  ", val);
06426adf0   Jens Axboe   blk-mq: implement...
350
351
352
353
354
  }
  
  static ssize_t queue_poll_delay_store(struct request_queue *q, const char *page,
  				size_t count)
  {
64f1c21e8   Jens Axboe   blk-mq: make the ...
355
  	int err, val;
06426adf0   Jens Axboe   blk-mq: implement...
356
357
358
  
  	if (!q->mq_ops || !q->mq_ops->poll)
  		return -EINVAL;
64f1c21e8   Jens Axboe   blk-mq: make the ...
359
360
361
  	err = kstrtoint(page, 10, &val);
  	if (err < 0)
  		return err;
06426adf0   Jens Axboe   blk-mq: implement...
362

64f1c21e8   Jens Axboe   blk-mq: make the ...
363
364
365
366
367
368
  	if (val == -1)
  		q->poll_nsec = -1;
  	else
  		q->poll_nsec = val * 1000;
  
  	return count;
06426adf0   Jens Axboe   blk-mq: implement...
369
  }
05229beed   Jens Axboe   block: add block ...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  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;
05229beed   Jens Axboe   block: add block ...
387
  	if (poll_on)
8814ce8a0   Bart Van Assche   block: Introduce ...
388
  		blk_queue_flag_set(QUEUE_FLAG_POLL, q);
05229beed   Jens Axboe   block: add block ...
389
  	else
8814ce8a0   Bart Van Assche   block: Introduce ...
390
  		blk_queue_flag_clear(QUEUE_FLAG_POLL, q);
05229beed   Jens Axboe   block: add block ...
391
392
393
  
  	return ret;
  }
87760e5ee   Jens Axboe   block: hook up wr...
394
395
  static ssize_t queue_wb_lat_show(struct request_queue *q, char *page)
  {
a79050434   Josef Bacik   blk-rq-qos: refac...
396
  	if (!wbt_rq_qos(q))
87760e5ee   Jens Axboe   block: hook up wr...
397
  		return -EINVAL;
a79050434   Josef Bacik   blk-rq-qos: refac...
398
399
  	return sprintf(page, "%llu
  ", div_u64(wbt_get_min_lat(q), 1000));
87760e5ee   Jens Axboe   block: hook up wr...
400
401
402
403
404
  }
  
  static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page,
  				  size_t count)
  {
a79050434   Josef Bacik   blk-rq-qos: refac...
405
  	struct rq_qos *rqos;
87760e5ee   Jens Axboe   block: hook up wr...
406
  	ssize_t ret;
80e091d10   Jens Axboe   blk-wbt: allow re...
407
  	s64 val;
87760e5ee   Jens Axboe   block: hook up wr...
408

87760e5ee   Jens Axboe   block: hook up wr...
409
410
411
  	ret = queue_var_store64(&val, page);
  	if (ret < 0)
  		return ret;
d62118b6d   Jens Axboe   blk-wbt: allow wb...
412
413
  	if (val < -1)
  		return -EINVAL;
a79050434   Josef Bacik   blk-rq-qos: refac...
414
415
  	rqos = wbt_rq_qos(q);
  	if (!rqos) {
d62118b6d   Jens Axboe   blk-wbt: allow wb...
416
417
418
  		ret = wbt_init(q);
  		if (ret)
  			return ret;
d62118b6d   Jens Axboe   blk-wbt: allow wb...
419
  	}
87760e5ee   Jens Axboe   block: hook up wr...
420

80e091d10   Jens Axboe   blk-wbt: allow re...
421
  	if (val == -1)
a79050434   Josef Bacik   blk-rq-qos: refac...
422
  		val = wbt_default_latency_nsec(q);
80e091d10   Jens Axboe   blk-wbt: allow re...
423
  	else if (val >= 0)
a79050434   Josef Bacik   blk-rq-qos: refac...
424
  		val *= 1000ULL;
d62118b6d   Jens Axboe   blk-wbt: allow wb...
425

c125311d9   Jens Axboe   blk-wbt: don't ma...
426
427
428
429
430
431
432
433
434
435
  	/*
  	 * Ensure that the queue is idled, in case the latency update
  	 * ends up either enabling or disabling wbt completely. We can't
  	 * have IO inflight if that happens.
  	 */
  	if (q->mq_ops) {
  		blk_mq_freeze_queue(q);
  		blk_mq_quiesce_queue(q);
  	} else
  		blk_queue_bypass_start(q);
80e091d10   Jens Axboe   blk-wbt: allow re...
436

c125311d9   Jens Axboe   blk-wbt: don't ma...
437
  	wbt_set_min_lat(q, val);
a79050434   Josef Bacik   blk-rq-qos: refac...
438
  	wbt_update_limits(q);
c125311d9   Jens Axboe   blk-wbt: don't ma...
439
440
441
442
443
444
  
  	if (q->mq_ops) {
  		blk_mq_unquiesce_queue(q);
  		blk_mq_unfreeze_queue(q);
  	} else
  		blk_queue_bypass_end(q);
87760e5ee   Jens Axboe   block: hook up wr...
445
446
  	return count;
  }
93e9d8e83   Jens Axboe   block: add abilit...
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
  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;
93e9d8e83   Jens Axboe   block: add abilit...
470
  	if (set)
8814ce8a0   Bart Van Assche   block: Introduce ...
471
  		blk_queue_flag_set(QUEUE_FLAG_WC, q);
93e9d8e83   Jens Axboe   block: add abilit...
472
  	else
8814ce8a0   Bart Van Assche   block: Introduce ...
473
  		blk_queue_flag_clear(QUEUE_FLAG_WC, q);
93e9d8e83   Jens Axboe   block: add abilit...
474
475
476
  
  	return count;
  }
6fcefbe57   Kent Overstreet   block: Add sysfs ...
477
478
479
480
481
  static ssize_t queue_fua_show(struct request_queue *q, char *page)
  {
  	return sprintf(page, "%u
  ", test_bit(QUEUE_FLAG_FUA, &q->queue_flags));
  }
ea6ca600e   Yigal Korman   block: expose QUE...
482
483
484
485
  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 ...
486
  static struct queue_sysfs_entry queue_requests_entry = {
5657a819a   Joe Perches   block drivers/blo...
487
  	.attr = {.name = "nr_requests", .mode = 0644 },
8324aa91d   Jens Axboe   block: split tag ...
488
489
490
491
492
  	.show = queue_requests_show,
  	.store = queue_requests_store,
  };
  
  static struct queue_sysfs_entry queue_ra_entry = {
5657a819a   Joe Perches   block drivers/blo...
493
  	.attr = {.name = "read_ahead_kb", .mode = 0644 },
8324aa91d   Jens Axboe   block: split tag ...
494
495
496
497
498
  	.show = queue_ra_show,
  	.store = queue_ra_store,
  };
  
  static struct queue_sysfs_entry queue_max_sectors_entry = {
5657a819a   Joe Perches   block drivers/blo...
499
  	.attr = {.name = "max_sectors_kb", .mode = 0644 },
8324aa91d   Jens Axboe   block: split tag ...
500
501
502
503
504
  	.show = queue_max_sectors_show,
  	.store = queue_max_sectors_store,
  };
  
  static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
5657a819a   Joe Perches   block drivers/blo...
505
  	.attr = {.name = "max_hw_sectors_kb", .mode = 0444 },
8324aa91d   Jens Axboe   block: split tag ...
506
507
  	.show = queue_max_hw_sectors_show,
  };
c77a5710b   Martin K. Petersen   block: Export max...
508
  static struct queue_sysfs_entry queue_max_segments_entry = {
5657a819a   Joe Perches   block drivers/blo...
509
  	.attr = {.name = "max_segments", .mode = 0444 },
c77a5710b   Martin K. Petersen   block: Export max...
510
511
  	.show = queue_max_segments_show,
  };
1e739730c   Christoph Hellwig   block: optionally...
512
  static struct queue_sysfs_entry queue_max_discard_segments_entry = {
5657a819a   Joe Perches   block drivers/blo...
513
  	.attr = {.name = "max_discard_segments", .mode = 0444 },
1e739730c   Christoph Hellwig   block: optionally...
514
515
  	.show = queue_max_discard_segments_show,
  };
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
516
  static struct queue_sysfs_entry queue_max_integrity_segments_entry = {
5657a819a   Joe Perches   block drivers/blo...
517
  	.attr = {.name = "max_integrity_segments", .mode = 0444 },
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
518
519
  	.show = queue_max_integrity_segments_show,
  };
c77a5710b   Martin K. Petersen   block: Export max...
520
  static struct queue_sysfs_entry queue_max_segment_size_entry = {
5657a819a   Joe Perches   block drivers/blo...
521
  	.attr = {.name = "max_segment_size", .mode = 0444 },
c77a5710b   Martin K. Petersen   block: Export max...
522
523
  	.show = queue_max_segment_size_show,
  };
8324aa91d   Jens Axboe   block: split tag ...
524
  static struct queue_sysfs_entry queue_iosched_entry = {
5657a819a   Joe Perches   block drivers/blo...
525
  	.attr = {.name = "scheduler", .mode = 0644 },
8324aa91d   Jens Axboe   block: split tag ...
526
527
528
  	.show = elv_iosched_show,
  	.store = elv_iosched_store,
  };
e68b903c6   Martin K. Petersen   Expose hardware s...
529
  static struct queue_sysfs_entry queue_hw_sector_size_entry = {
5657a819a   Joe Perches   block drivers/blo...
530
  	.attr = {.name = "hw_sector_size", .mode = 0444 },
e1defc4ff   Martin K. Petersen   block: Do away wi...
531
532
533
534
  	.show = queue_logical_block_size_show,
  };
  
  static struct queue_sysfs_entry queue_logical_block_size_entry = {
5657a819a   Joe Perches   block drivers/blo...
535
  	.attr = {.name = "logical_block_size", .mode = 0444 },
e1defc4ff   Martin K. Petersen   block: Do away wi...
536
  	.show = queue_logical_block_size_show,
e68b903c6   Martin K. Petersen   Expose hardware s...
537
  };
c72758f33   Martin K. Petersen   block: Export I/O...
538
  static struct queue_sysfs_entry queue_physical_block_size_entry = {
5657a819a   Joe Perches   block drivers/blo...
539
  	.attr = {.name = "physical_block_size", .mode = 0444 },
c72758f33   Martin K. Petersen   block: Export I/O...
540
541
  	.show = queue_physical_block_size_show,
  };
87caf97cf   Hannes Reinecke   blk-sysfs: Add 'c...
542
  static struct queue_sysfs_entry queue_chunk_sectors_entry = {
5657a819a   Joe Perches   block drivers/blo...
543
  	.attr = {.name = "chunk_sectors", .mode = 0444 },
87caf97cf   Hannes Reinecke   blk-sysfs: Add 'c...
544
545
  	.show = queue_chunk_sectors_show,
  };
c72758f33   Martin K. Petersen   block: Export I/O...
546
  static struct queue_sysfs_entry queue_io_min_entry = {
5657a819a   Joe Perches   block drivers/blo...
547
  	.attr = {.name = "minimum_io_size", .mode = 0444 },
c72758f33   Martin K. Petersen   block: Export I/O...
548
549
550
551
  	.show = queue_io_min_show,
  };
  
  static struct queue_sysfs_entry queue_io_opt_entry = {
5657a819a   Joe Perches   block drivers/blo...
552
  	.attr = {.name = "optimal_io_size", .mode = 0444 },
c72758f33   Martin K. Petersen   block: Export I/O...
553
  	.show = queue_io_opt_show,
e68b903c6   Martin K. Petersen   Expose hardware s...
554
  };
86b372814   Martin K. Petersen   block: Expose dis...
555
  static struct queue_sysfs_entry queue_discard_granularity_entry = {
5657a819a   Joe Perches   block drivers/blo...
556
  	.attr = {.name = "discard_granularity", .mode = 0444 },
86b372814   Martin K. Petersen   block: Expose dis...
557
558
  	.show = queue_discard_granularity_show,
  };
0034af036   Jens Axboe   block: make /sys/...
559
  static struct queue_sysfs_entry queue_discard_max_hw_entry = {
5657a819a   Joe Perches   block drivers/blo...
560
  	.attr = {.name = "discard_max_hw_bytes", .mode = 0444 },
0034af036   Jens Axboe   block: make /sys/...
561
562
  	.show = queue_discard_max_hw_show,
  };
86b372814   Martin K. Petersen   block: Expose dis...
563
  static struct queue_sysfs_entry queue_discard_max_entry = {
5657a819a   Joe Perches   block drivers/blo...
564
  	.attr = {.name = "discard_max_bytes", .mode = 0644 },
86b372814   Martin K. Petersen   block: Expose dis...
565
  	.show = queue_discard_max_show,
0034af036   Jens Axboe   block: make /sys/...
566
  	.store = queue_discard_max_store,
86b372814   Martin K. Petersen   block: Expose dis...
567
  };
98262f276   Martin K. Petersen   block: Allow devi...
568
  static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
5657a819a   Joe Perches   block drivers/blo...
569
  	.attr = {.name = "discard_zeroes_data", .mode = 0444 },
98262f276   Martin K. Petersen   block: Allow devi...
570
571
  	.show = queue_discard_zeroes_data_show,
  };
4363ac7c1   Martin K. Petersen   block: Implement ...
572
  static struct queue_sysfs_entry queue_write_same_max_entry = {
5657a819a   Joe Perches   block drivers/blo...
573
  	.attr = {.name = "write_same_max_bytes", .mode = 0444 },
4363ac7c1   Martin K. Petersen   block: Implement ...
574
575
  	.show = queue_write_same_max_show,
  };
a6f0788ec   Chaitanya Kulkarni   block: add suppor...
576
  static struct queue_sysfs_entry queue_write_zeroes_max_entry = {
5657a819a   Joe Perches   block drivers/blo...
577
  	.attr = {.name = "write_zeroes_max_bytes", .mode = 0444 },
a6f0788ec   Chaitanya Kulkarni   block: add suppor...
578
579
  	.show = queue_write_zeroes_max_show,
  };
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
580
  static struct queue_sysfs_entry queue_nonrot_entry = {
5657a819a   Joe Perches   block drivers/blo...
581
  	.attr = {.name = "rotational", .mode = 0644 },
956bcb7c1   Jens Axboe   block: add helper...
582
583
  	.show = queue_show_nonrot,
  	.store = queue_store_nonrot,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
584
  };
797476b88   Damien Le Moal   block: Add 'zoned...
585
  static struct queue_sysfs_entry queue_zoned_entry = {
5657a819a   Joe Perches   block drivers/blo...
586
  	.attr = {.name = "zoned", .mode = 0444 },
797476b88   Damien Le Moal   block: Add 'zoned...
587
588
  	.show = queue_zoned_show,
  };
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
589
  static struct queue_sysfs_entry queue_nomerges_entry = {
5657a819a   Joe Perches   block drivers/blo...
590
  	.attr = {.name = "nomerges", .mode = 0644 },
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
591
592
593
  	.show = queue_nomerges_show,
  	.store = queue_nomerges_store,
  };
c7c22e4d5   Jens Axboe   block: add suppor...
594
  static struct queue_sysfs_entry queue_rq_affinity_entry = {
5657a819a   Joe Perches   block drivers/blo...
595
  	.attr = {.name = "rq_affinity", .mode = 0644 },
c7c22e4d5   Jens Axboe   block: add suppor...
596
597
598
  	.show = queue_rq_affinity_show,
  	.store = queue_rq_affinity_store,
  };
bc58ba946   Jens Axboe   block: add sysfs ...
599
  static struct queue_sysfs_entry queue_iostats_entry = {
5657a819a   Joe Perches   block drivers/blo...
600
  	.attr = {.name = "iostats", .mode = 0644 },
956bcb7c1   Jens Axboe   block: add helper...
601
602
  	.show = queue_show_iostats,
  	.store = queue_store_iostats,
bc58ba946   Jens Axboe   block: add sysfs ...
603
  };
e2e1a148b   Jens Axboe   block: add sysfs ...
604
  static struct queue_sysfs_entry queue_random_entry = {
5657a819a   Joe Perches   block drivers/blo...
605
  	.attr = {.name = "add_random", .mode = 0644 },
956bcb7c1   Jens Axboe   block: add helper...
606
607
  	.show = queue_show_random,
  	.store = queue_store_random,
e2e1a148b   Jens Axboe   block: add sysfs ...
608
  };
05229beed   Jens Axboe   block: add block ...
609
  static struct queue_sysfs_entry queue_poll_entry = {
5657a819a   Joe Perches   block drivers/blo...
610
  	.attr = {.name = "io_poll", .mode = 0644 },
05229beed   Jens Axboe   block: add block ...
611
612
613
  	.show = queue_poll_show,
  	.store = queue_poll_store,
  };
06426adf0   Jens Axboe   blk-mq: implement...
614
  static struct queue_sysfs_entry queue_poll_delay_entry = {
5657a819a   Joe Perches   block drivers/blo...
615
  	.attr = {.name = "io_poll_delay", .mode = 0644 },
06426adf0   Jens Axboe   blk-mq: implement...
616
617
618
  	.show = queue_poll_delay_show,
  	.store = queue_poll_delay_store,
  };
93e9d8e83   Jens Axboe   block: add abilit...
619
  static struct queue_sysfs_entry queue_wc_entry = {
5657a819a   Joe Perches   block drivers/blo...
620
  	.attr = {.name = "write_cache", .mode = 0644 },
93e9d8e83   Jens Axboe   block: add abilit...
621
622
623
  	.show = queue_wc_show,
  	.store = queue_wc_store,
  };
6fcefbe57   Kent Overstreet   block: Add sysfs ...
624
  static struct queue_sysfs_entry queue_fua_entry = {
5657a819a   Joe Perches   block drivers/blo...
625
  	.attr = {.name = "fua", .mode = 0444 },
6fcefbe57   Kent Overstreet   block: Add sysfs ...
626
627
  	.show = queue_fua_show,
  };
ea6ca600e   Yigal Korman   block: expose QUE...
628
  static struct queue_sysfs_entry queue_dax_entry = {
5657a819a   Joe Perches   block drivers/blo...
629
  	.attr = {.name = "dax", .mode = 0444 },
ea6ca600e   Yigal Korman   block: expose QUE...
630
631
  	.show = queue_dax_show,
  };
87760e5ee   Jens Axboe   block: hook up wr...
632
  static struct queue_sysfs_entry queue_wb_lat_entry = {
5657a819a   Joe Perches   block drivers/blo...
633
  	.attr = {.name = "wbt_lat_usec", .mode = 0644 },
87760e5ee   Jens Axboe   block: hook up wr...
634
635
636
  	.show = queue_wb_lat_show,
  	.store = queue_wb_lat_store,
  };
297e3d854   Shaohua Li   blk-throttle: mak...
637
638
  #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
  static struct queue_sysfs_entry throtl_sample_time_entry = {
5657a819a   Joe Perches   block drivers/blo...
639
  	.attr = {.name = "throttle_sample_time", .mode = 0644 },
297e3d854   Shaohua Li   blk-throttle: mak...
640
641
642
643
  	.show = blk_throtl_sample_time_show,
  	.store = blk_throtl_sample_time_store,
  };
  #endif
8324aa91d   Jens Axboe   block: split tag ...
644
645
646
647
648
  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...
649
  	&queue_max_segments_entry.attr,
1e739730c   Christoph Hellwig   block: optionally...
650
  	&queue_max_discard_segments_entry.attr,
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
651
  	&queue_max_integrity_segments_entry.attr,
c77a5710b   Martin K. Petersen   block: Export max...
652
  	&queue_max_segment_size_entry.attr,
8324aa91d   Jens Axboe   block: split tag ...
653
  	&queue_iosched_entry.attr,
e68b903c6   Martin K. Petersen   Expose hardware s...
654
  	&queue_hw_sector_size_entry.attr,
e1defc4ff   Martin K. Petersen   block: Do away wi...
655
  	&queue_logical_block_size_entry.attr,
c72758f33   Martin K. Petersen   block: Export I/O...
656
  	&queue_physical_block_size_entry.attr,
87caf97cf   Hannes Reinecke   blk-sysfs: Add 'c...
657
  	&queue_chunk_sectors_entry.attr,
c72758f33   Martin K. Petersen   block: Export I/O...
658
659
  	&queue_io_min_entry.attr,
  	&queue_io_opt_entry.attr,
86b372814   Martin K. Petersen   block: Expose dis...
660
661
  	&queue_discard_granularity_entry.attr,
  	&queue_discard_max_entry.attr,
0034af036   Jens Axboe   block: make /sys/...
662
  	&queue_discard_max_hw_entry.attr,
98262f276   Martin K. Petersen   block: Allow devi...
663
  	&queue_discard_zeroes_data_entry.attr,
4363ac7c1   Martin K. Petersen   block: Implement ...
664
  	&queue_write_same_max_entry.attr,
a6f0788ec   Chaitanya Kulkarni   block: add suppor...
665
  	&queue_write_zeroes_max_entry.attr,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
666
  	&queue_nonrot_entry.attr,
797476b88   Damien Le Moal   block: Add 'zoned...
667
  	&queue_zoned_entry.attr,
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
668
  	&queue_nomerges_entry.attr,
c7c22e4d5   Jens Axboe   block: add suppor...
669
  	&queue_rq_affinity_entry.attr,
bc58ba946   Jens Axboe   block: add sysfs ...
670
  	&queue_iostats_entry.attr,
e2e1a148b   Jens Axboe   block: add sysfs ...
671
  	&queue_random_entry.attr,
05229beed   Jens Axboe   block: add block ...
672
  	&queue_poll_entry.attr,
93e9d8e83   Jens Axboe   block: add abilit...
673
  	&queue_wc_entry.attr,
6fcefbe57   Kent Overstreet   block: Add sysfs ...
674
  	&queue_fua_entry.attr,
ea6ca600e   Yigal Korman   block: expose QUE...
675
  	&queue_dax_entry.attr,
87760e5ee   Jens Axboe   block: hook up wr...
676
  	&queue_wb_lat_entry.attr,
06426adf0   Jens Axboe   blk-mq: implement...
677
  	&queue_poll_delay_entry.attr,
297e3d854   Shaohua Li   blk-throttle: mak...
678
679
680
  #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
  	&throtl_sample_time_entry.attr,
  #endif
8324aa91d   Jens Axboe   block: split tag ...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  	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...
697
  	if (blk_queue_dying(q)) {
8324aa91d   Jens Axboe   block: split tag ...
698
699
700
701
702
703
704
705
706
707
708
709
710
  		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 ...
711
  	struct request_queue *q;
8324aa91d   Jens Axboe   block: split tag ...
712
713
714
715
  	ssize_t res;
  
  	if (!entry->store)
  		return -EIO;
6728cb0e6   Jens Axboe   block: make core ...
716
717
  
  	q = container_of(kobj, struct request_queue, kobj);
8324aa91d   Jens Axboe   block: split tag ...
718
  	mutex_lock(&q->sysfs_lock);
3f3299d5c   Bart Van Assche   block: Rename que...
719
  	if (blk_queue_dying(q)) {
8324aa91d   Jens Axboe   block: split tag ...
720
721
722
723
724
725
726
  		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...
727
728
729
730
731
732
  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 ...
733
  /**
dc9edc44d   Bart Van Assche   block: Fix a blk_...
734
735
   * __blk_release_queue - release a request queue when it is no longer needed
   * @work: pointer to the release_work member of the request queue to be released
8324aa91d   Jens Axboe   block: split tag ...
736
737
   *
   * Description:
dc9edc44d   Bart Van Assche   block: Fix a blk_...
738
739
740
741
   *     blk_release_queue is the counterpart of blk_init_queue(). It should be
   *     called when a request queue is being released; typically when a block
   *     device is being de-registered. Its primary task it to free the queue
   *     itself.
8324aa91d   Jens Axboe   block: split tag ...
742
   *
dc9edc44d   Bart Van Assche   block: Fix a blk_...
743
   * Notes:
45a9c9d90   Bart Van Assche   blk-mq: Fix a use...
744
745
   *     The low level driver must have finished any outstanding requests first
   *     via blk_cleanup_queue().
dc9edc44d   Bart Van Assche   block: Fix a blk_...
746
747
748
749
750
   *
   *     Although blk_release_queue() may be called with preemption disabled,
   *     __blk_release_queue() may sleep.
   */
  static void __blk_release_queue(struct work_struct *work)
8324aa91d   Jens Axboe   block: split tag ...
751
  {
dc9edc44d   Bart Van Assche   block: Fix a blk_...
752
  	struct request_queue *q = container_of(work, typeof(*q), release_work);
8324aa91d   Jens Axboe   block: split tag ...
753

34dbad5d2   Omar Sandoval   blk-stat: convert...
754
755
756
  	if (test_bit(QUEUE_FLAG_POLL_STATS, &q->queue_flags))
  		blk_stat_remove_callback(q, q->poll_cb);
  	blk_stat_free_callback(q->poll_cb);
777eb1bf1   Hannes Reinecke   block: Free queue...
757

24ecc3585   Bart Van Assche   block: Ensure tha...
758
759
760
761
762
763
764
765
766
767
768
  	if (!blk_queue_dead(q)) {
  		/*
  		 * Last reference was dropped without having called
  		 * blk_cleanup_queue().
  		 */
  		WARN_ONCE(blk_queue_init_done(q),
  			  "request queue %p has been registered but blk_cleanup_queue() has not been called for that queue
  ",
  			  q);
  		blk_exit_queue(q);
  	}
b86d865cb   Bart Van Assche   blkcg: Make blkg_...
769
  	WARN(blk_queue_root_blkg(q),
24ecc3585   Bart Van Assche   block: Ensure tha...
770
771
772
  	     "request queue %p is being released but it has not yet been removed from the blkcg controller
  ",
  	     q);
34dbad5d2   Omar Sandoval   blk-stat: convert...
773
  	blk_free_queue_stats(q->stats);
b425e5049   Bart Van Assche   block: Avoid that...
774
  	blk_exit_rl(q, &q->root_rl);
8324aa91d   Jens Axboe   block: split tag ...
775
776
777
  
  	if (q->queue_tags)
  		__blk_queue_free_tags(q);
6d247d7f7   Christoph Hellwig   block: allow spec...
778
779
780
  	if (!q->mq_ops) {
  		if (q->exit_rq_fn)
  			q->exit_rq_fn(q, q->fq->flush_rq);
f70ced091   Ming Lei   blk-mq: support p...
781
  		blk_free_flush_queue(q->fq);
6d247d7f7   Christoph Hellwig   block: allow spec...
782
  	} else {
e09aae7ed   Ming Lei   blk-mq: release m...
783
  		blk_mq_release(q);
6d247d7f7   Christoph Hellwig   block: allow spec...
784
  	}
18741986a   Christoph Hellwig   blk-mq: rework fl...
785

8324aa91d   Jens Axboe   block: split tag ...
786
  	blk_trace_shutdown(q);
62ebce16c   Omar Sandoval   blk-mq: move debu...
787
788
  	if (q->mq_ops)
  		blk_mq_debugfs_unregister(q);
338aa96d5   Kent Overstreet   block: convert bo...
789
  	bioset_exit(&q->bio_split);
54efd50bf   Kent Overstreet   block: make gener...
790

a73f730d0   Tejun Heo   block, cfq: move ...
791
  	ida_simple_remove(&blk_queue_ida, q->id);
548bc8e1b   Tejun Heo   block: RCU free r...
792
  	call_rcu(&q->rcu_head, blk_free_queue_rcu);
8324aa91d   Jens Axboe   block: split tag ...
793
  }
dc9edc44d   Bart Van Assche   block: Fix a blk_...
794
795
796
797
798
799
800
801
  static void blk_release_queue(struct kobject *kobj)
  {
  	struct request_queue *q =
  		container_of(kobj, struct request_queue, kobj);
  
  	INIT_WORK(&q->release_work, __blk_release_queue);
  	schedule_work(&q->release_work);
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
802
  static const struct sysfs_ops queue_sysfs_ops = {
8324aa91d   Jens Axboe   block: split tag ...
803
804
805
806
807
808
809
810
811
  	.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,
  };
2c2086afc   Bart Van Assche   block: Protect le...
812
813
814
815
  /**
   * blk_register_queue - register a block layer queue with sysfs
   * @disk: Disk of which the request queue should be registered with sysfs.
   */
8324aa91d   Jens Axboe   block: split tag ...
816
817
818
  int blk_register_queue(struct gendisk *disk)
  {
  	int ret;
1d54ad6da   Li Zefan   blktrace: add tra...
819
  	struct device *dev = disk_to_dev(disk);
8324aa91d   Jens Axboe   block: split tag ...
820
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
821
  	if (WARN_ON(!q))
8324aa91d   Jens Axboe   block: split tag ...
822
  		return -ENXIO;
334335d2f   Omar Sandoval   block: warn if sh...
823
824
825
826
827
  	WARN_ONCE(test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags),
  		  "%s is registering an already registered queue
  ",
  		  kobject_name(&dev->kobj));
  	queue_flag_set_unlocked(QUEUE_FLAG_REGISTERED, q);
749fefe67   Tejun Heo   block: lift the i...
828
  	/*
17497acbd   Tejun Heo   blk-mq, percpu_re...
829
830
831
832
833
834
835
  	 * 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...
836
  	 */
df35c7c91   Alan Stern   Block: fix unbala...
837
838
  	if (!blk_queue_init_done(q)) {
  		queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q);
3ef28e83a   Dan Williams   block: generic re...
839
  		percpu_ref_switch_to_percpu(&q->q_usage_counter);
df35c7c91   Alan Stern   Block: fix unbala...
840
841
  		blk_queue_bypass_end(q);
  	}
749fefe67   Tejun Heo   block: lift the i...
842

1d54ad6da   Li Zefan   blktrace: add tra...
843
844
845
  	ret = blk_trace_init_sysfs(dev);
  	if (ret)
  		return ret;
b410aff2b   Tahsin Erdogan   block: do not all...
846
847
  	/* Prevent changes through sysfs until registration is completed. */
  	mutex_lock(&q->sysfs_lock);
c9059598e   Linus Torvalds   Merge branch 'for...
848
  	ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue");
ed5302d3c   Liu Yuan   block, blk-sysfs:...
849
850
  	if (ret < 0) {
  		blk_trace_remove_sysfs(dev);
b410aff2b   Tahsin Erdogan   block: do not all...
851
  		goto unlock;
ed5302d3c   Liu Yuan   block, blk-sysfs:...
852
  	}
8324aa91d   Jens Axboe   block: split tag ...
853

a8ecdd711   Bart Van Assche   blk-mq: Only regi...
854
  	if (q->mq_ops) {
2d0364c8c   Bart Van Assche   blk-mq: Register ...
855
  		__blk_mq_register_dev(dev, q);
a8ecdd711   Bart Van Assche   blk-mq: Only regi...
856
857
  		blk_mq_debugfs_register(q);
  	}
9c1051aac   Omar Sandoval   blk-mq: untangle ...
858

8324aa91d   Jens Axboe   block: split tag ...
859
  	kobject_uevent(&q->kobj, KOBJ_ADD);
8330cdb0f   Jan Kara   block: Make write...
860
  	wbt_enable_default(q);
87760e5ee   Jens Axboe   block: hook up wr...
861

d61fcfa4b   Shaohua Li   blk-throttle: cho...
862
  	blk_throtl_register_queue(q);
80c6b1573   Omar Sandoval   blk-mq-sched: (un...
863
864
865
  	if (q->request_fn || (q->mq_ops && q->elevator)) {
  		ret = elv_register_queue(q);
  		if (ret) {
2c2086afc   Bart Van Assche   block: Protect le...
866
  			mutex_unlock(&q->sysfs_lock);
80c6b1573   Omar Sandoval   blk-mq-sched: (un...
867
868
869
870
  			kobject_uevent(&q->kobj, KOBJ_REMOVE);
  			kobject_del(&q->kobj);
  			blk_trace_remove_sysfs(dev);
  			kobject_put(&dev->kobj);
2c2086afc   Bart Van Assche   block: Protect le...
871
  			return ret;
80c6b1573   Omar Sandoval   blk-mq-sched: (un...
872
  		}
8324aa91d   Jens Axboe   block: split tag ...
873
  	}
b410aff2b   Tahsin Erdogan   block: do not all...
874
875
876
877
  	ret = 0;
  unlock:
  	mutex_unlock(&q->sysfs_lock);
  	return ret;
8324aa91d   Jens Axboe   block: split tag ...
878
  }
fa70d2e2c   Mike Snitzer   block: allow gend...
879
  EXPORT_SYMBOL_GPL(blk_register_queue);
8324aa91d   Jens Axboe   block: split tag ...
880

2c2086afc   Bart Van Assche   block: Protect le...
881
882
883
884
885
886
887
  /**
   * blk_unregister_queue - counterpart of blk_register_queue()
   * @disk: Disk of which the request queue should be unregistered from sysfs.
   *
   * Note: the caller is responsible for guaranteeing that this function is called
   * after blk_register_queue() has finished.
   */
8324aa91d   Jens Axboe   block: split tag ...
888
889
890
  void blk_unregister_queue(struct gendisk *disk)
  {
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
891
892
  	if (WARN_ON(!q))
  		return;
fa70d2e2c   Mike Snitzer   block: allow gend...
893
894
895
  	/* Return early if disk->queue was never registered. */
  	if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
  		return;
667257e8b   Mike Snitzer   block: properly p...
896
  	/*
2c2086afc   Bart Van Assche   block: Protect le...
897
898
899
  	 * Since sysfs_remove_dir() prevents adding new directory entries
  	 * before removal of existing entries starts, protect against
  	 * concurrent elv_iosched_store() calls.
667257e8b   Mike Snitzer   block: properly p...
900
  	 */
e9a823fb3   David Jeffery   block: fix warnin...
901
  	mutex_lock(&q->sysfs_lock);
334335d2f   Omar Sandoval   block: warn if sh...
902

8814ce8a0   Bart Van Assche   block: Introduce ...
903
  	blk_queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
02ba8893a   Omar Sandoval   block: fix leak o...
904

2c2086afc   Bart Van Assche   block: Protect le...
905
906
907
908
  	/*
  	 * Remove the sysfs attributes before unregistering the queue data
  	 * structures that can be modified through sysfs.
  	 */
320ae51fe   Jens Axboe   blk-mq: new multi...
909
  	if (q->mq_ops)
b21d5b301   Matias Bjørling   blk-mq: register ...
910
  		blk_mq_unregister_dev(disk_to_dev(disk), q);
2c2086afc   Bart Van Assche   block: Protect le...
911
  	mutex_unlock(&q->sysfs_lock);
8324aa91d   Jens Axboe   block: split tag ...
912

48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
913
914
915
  	kobject_uevent(&q->kobj, KOBJ_REMOVE);
  	kobject_del(&q->kobj);
  	blk_trace_remove_sysfs(disk_to_dev(disk));
667257e8b   Mike Snitzer   block: properly p...
916

a79050434   Josef Bacik   blk-rq-qos: refac...
917
  	rq_qos_exit(q);
2c2086afc   Bart Van Assche   block: Protect le...
918
919
920
921
  
  	mutex_lock(&q->sysfs_lock);
  	if (q->request_fn || (q->mq_ops && q->elevator))
  		elv_unregister_queue(q);
667257e8b   Mike Snitzer   block: properly p...
922
  	mutex_unlock(&q->sysfs_lock);
2c2086afc   Bart Van Assche   block: Protect le...
923
924
  
  	kobject_put(&disk_to_dev(disk)->kobj);
8324aa91d   Jens Axboe   block: split tag ...
925
  }