Blame view

block/blk-sysfs.c 14.7 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
9
10
11
12
13
14
15
16
17
18
19
  #include <linux/module.h>
  #include <linux/bio.h>
  #include <linux/blkdev.h>
  #include <linux/blktrace_api.h>
  
  #include "blk.h"
  
  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 ...
20
  queue_var_show(unsigned long var, char *page)
8324aa91d   Jens Axboe   block: split tag ...
21
  {
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
22
23
  	return sprintf(page, "%lu
  ", var);
8324aa91d   Jens Axboe   block: split tag ...
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  }
  
  static ssize_t
  queue_var_store(unsigned long *var, const char *page, size_t count)
  {
  	char *p = (char *) page;
  
  	*var = simple_strtoul(p, &p, 10);
  	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)
  {
  	struct request_list *rl = &q->rq;
  	unsigned long nr;
b8a9ae779   Jens Axboe   block: don't assu...
45
46
47
48
49
50
  	int ret;
  
  	if (!q->request_fn)
  		return -EINVAL;
  
  	ret = queue_var_store(&nr, page, count);
8324aa91d   Jens Axboe   block: split tag ...
51
52
53
54
55
56
  	if (nr < BLKDEV_MIN_RQ)
  		nr = BLKDEV_MIN_RQ;
  
  	spin_lock_irq(q->queue_lock);
  	q->nr_requests = nr;
  	blk_queue_congestion_threshold(q);
1faa16d22   Jens Axboe   block: change the...
57
58
59
60
61
62
63
64
65
66
67
68
  	if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q))
  		blk_set_queue_congested(q, BLK_RW_SYNC);
  	else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q))
  		blk_clear_queue_congested(q, BLK_RW_SYNC);
  
  	if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q))
  		blk_set_queue_congested(q, BLK_RW_ASYNC);
  	else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q))
  		blk_clear_queue_congested(q, BLK_RW_ASYNC);
  
  	if (rl->count[BLK_RW_SYNC] >= q->nr_requests) {
  		blk_set_queue_full(q, BLK_RW_SYNC);
60735b636   Tao Ma   block: Remove the...
69
  	} else {
1faa16d22   Jens Axboe   block: change the...
70
71
  		blk_clear_queue_full(q, BLK_RW_SYNC);
  		wake_up(&rl->wait[BLK_RW_SYNC]);
8324aa91d   Jens Axboe   block: split tag ...
72
  	}
1faa16d22   Jens Axboe   block: change the...
73
74
  	if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) {
  		blk_set_queue_full(q, BLK_RW_ASYNC);
60735b636   Tao Ma   block: Remove the...
75
  	} else {
1faa16d22   Jens Axboe   block: change the...
76
77
  		blk_clear_queue_full(q, BLK_RW_ASYNC);
  		wake_up(&rl->wait[BLK_RW_ASYNC]);
8324aa91d   Jens Axboe   block: split tag ...
78
79
80
81
82
83
84
  	}
  	spin_unlock_irq(q->queue_lock);
  	return ret;
  }
  
  static ssize_t queue_ra_show(struct request_queue *q, char *page)
  {
9cb308ce8   Xiaotian Feng   block: sysfs fix ...
85
86
  	unsigned long ra_kb = q->backing_dev_info.ra_pages <<
  					(PAGE_CACHE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
87
88
89
90
91
92
93
94
95
  
  	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);
8324aa91d   Jens Axboe   block: split tag ...
96
  	q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
8324aa91d   Jens Axboe   block: split tag ...
97
98
99
100
101
102
  
  	return ret;
  }
  
  static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
  {
ae03bf639   Martin K. Petersen   block: Use access...
103
  	int max_sectors_kb = queue_max_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
104
105
106
  
  	return queue_var_show(max_sectors_kb, (page));
  }
c77a5710b   Martin K. Petersen   block: Export max...
107
108
109
110
  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...
111
112
113
114
  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...
115
116
  static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
  {
e692cb668   Martin K. Petersen   block: Deprecate ...
117
  	if (blk_queue_cluster(q))
c77a5710b   Martin K. Petersen   block: Export max...
118
119
120
121
  		return queue_var_show(queue_max_segment_size(q), (page));
  
  	return queue_var_show(PAGE_CACHE_SIZE, (page));
  }
e1defc4ff   Martin K. Petersen   block: Do away wi...
122
  static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
e68b903c6   Martin K. Petersen   Expose hardware s...
123
  {
e1defc4ff   Martin K. Petersen   block: Do away wi...
124
  	return queue_var_show(queue_logical_block_size(q), page);
e68b903c6   Martin K. Petersen   Expose hardware s...
125
  }
c72758f33   Martin K. Petersen   block: Export I/O...
126
127
128
129
130
131
132
133
134
135
136
137
138
  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...
139
  }
86b372814   Martin K. Petersen   block: Expose dis...
140
141
142
143
144
145
146
  static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(q->limits.discard_granularity, page);
  }
  
  static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
  {
a934a00a6   Martin K. Petersen   block: Fix discar...
147
148
149
  	return sprintf(page, "%llu
  ",
  		       (unsigned long long)q->limits.max_discard_sectors << 9);
86b372814   Martin K. Petersen   block: Expose dis...
150
  }
98262f276   Martin K. Petersen   block: Allow devi...
151
152
153
154
  static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
  {
  	return queue_var_show(queue_discard_zeroes_data(q), page);
  }
8324aa91d   Jens Axboe   block: split tag ...
155
156
157
158
  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...
159
  		max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1,
8324aa91d   Jens Axboe   block: split tag ...
160
161
162
163
164
  			page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
  	ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
  
  	if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
  		return -EINVAL;
7c239517d   Wu Fengguang   block: don't take...
165

8324aa91d   Jens Axboe   block: split tag ...
166
  	spin_lock_irq(q->queue_lock);
c295fc057   Nikanth Karthikesan   block: Allow chan...
167
  	q->limits.max_sectors = max_sectors_kb << 1;
8324aa91d   Jens Axboe   block: split tag ...
168
169
170
171
172
173
174
  	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...
175
  	int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1;
8324aa91d   Jens Axboe   block: split tag ...
176
177
178
  
  	return queue_var_show(max_hw_sectors_kb, (page));
  }
956bcb7c1   Jens Axboe   block: add helper...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  #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);			\
  	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...
203
  }
956bcb7c1   Jens Axboe   block: add helper...
204
205
206
207
  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...
208

ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
209
210
  static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
  {
488991e28   Alan D. Brunelle   block: Added in s...
211
212
  	return queue_var_show((blk_queue_nomerges(q) << 1) |
  			       blk_queue_noxmerges(q), page);
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
213
214
215
216
217
218
219
  }
  
  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);
bf0f97025   Jens Axboe   block: sysfs stor...
220
  	spin_lock_irq(q->queue_lock);
488991e28   Alan D. Brunelle   block: Added in s...
221
222
223
  	queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
  	queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
  	if (nm == 2)
bf0f97025   Jens Axboe   block: sysfs stor...
224
  		queue_flag_set(QUEUE_FLAG_NOMERGES, q);
488991e28   Alan D. Brunelle   block: Added in s...
225
226
  	else if (nm)
  		queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
bf0f97025   Jens Axboe   block: sysfs stor...
227
  	spin_unlock_irq(q->queue_lock);
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
228

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

5757a6d76   Dan Williams   block: strict rq_...
236
  	return queue_var_show(set << force, page);
c7c22e4d5   Jens Axboe   block: add suppor...
237
238
239
240
241
242
243
244
245
246
247
  }
  
  static ssize_t
  queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count)
  {
  	ssize_t ret = -EINVAL;
  #if defined(CONFIG_USE_GENERIC_SMP_HELPERS)
  	unsigned long val;
  
  	ret = queue_var_store(&val, page, count);
  	spin_lock_irq(q->queue_lock);
e8037d498   Eric Seppanen   block: Fix queue_...
248
  	if (val == 2) {
c7c22e4d5   Jens Axboe   block: add suppor...
249
  		queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
e8037d498   Eric Seppanen   block: Fix queue_...
250
251
252
253
254
  		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_...
255
256
257
  		queue_flag_clear(QUEUE_FLAG_SAME_COMP, q);
  		queue_flag_clear(QUEUE_FLAG_SAME_FORCE, q);
  	}
c7c22e4d5   Jens Axboe   block: add suppor...
258
259
260
261
  	spin_unlock_irq(q->queue_lock);
  #endif
  	return ret;
  }
8324aa91d   Jens Axboe   block: split tag ...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  
  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...
285
286
287
288
  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...
289
290
291
292
  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...
293
294
295
296
  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 ...
297
298
299
300
301
  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...
302
303
  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...
304
305
306
307
308
309
  	.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...
310
  };
c72758f33   Martin K. Petersen   block: Export I/O...
311
312
313
314
315
316
317
318
319
320
321
322
323
  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...
324
  };
86b372814   Martin K. Petersen   block: Expose dis...
325
326
327
328
329
330
331
332
333
  static struct queue_sysfs_entry queue_discard_granularity_entry = {
  	.attr = {.name = "discard_granularity", .mode = S_IRUGO },
  	.show = queue_discard_granularity_show,
  };
  
  static struct queue_sysfs_entry queue_discard_max_entry = {
  	.attr = {.name = "discard_max_bytes", .mode = S_IRUGO },
  	.show = queue_discard_max_show,
  };
98262f276   Martin K. Petersen   block: Allow devi...
334
335
336
337
  static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
  	.attr = {.name = "discard_zeroes_data", .mode = S_IRUGO },
  	.show = queue_discard_zeroes_data_show,
  };
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
338
339
  static struct queue_sysfs_entry queue_nonrot_entry = {
  	.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
340
341
  	.show = queue_show_nonrot,
  	.store = queue_store_nonrot,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
342
  };
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
343
344
345
346
347
  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...
348
349
350
351
352
  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 ...
353
354
  static struct queue_sysfs_entry queue_iostats_entry = {
  	.attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
355
356
  	.show = queue_show_iostats,
  	.store = queue_store_iostats,
bc58ba946   Jens Axboe   block: add sysfs ...
357
  };
e2e1a148b   Jens Axboe   block: add sysfs ...
358
359
  static struct queue_sysfs_entry queue_random_entry = {
  	.attr = {.name = "add_random", .mode = S_IRUGO | S_IWUSR },
956bcb7c1   Jens Axboe   block: add helper...
360
361
  	.show = queue_show_random,
  	.store = queue_store_random,
e2e1a148b   Jens Axboe   block: add sysfs ...
362
  };
8324aa91d   Jens Axboe   block: split tag ...
363
364
365
366
367
  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...
368
  	&queue_max_segments_entry.attr,
13f05c8d8   Martin K. Petersen   block/scsi: Provi...
369
  	&queue_max_integrity_segments_entry.attr,
c77a5710b   Martin K. Petersen   block: Export max...
370
  	&queue_max_segment_size_entry.attr,
8324aa91d   Jens Axboe   block: split tag ...
371
  	&queue_iosched_entry.attr,
e68b903c6   Martin K. Petersen   Expose hardware s...
372
  	&queue_hw_sector_size_entry.attr,
e1defc4ff   Martin K. Petersen   block: Do away wi...
373
  	&queue_logical_block_size_entry.attr,
c72758f33   Martin K. Petersen   block: Export I/O...
374
375
376
  	&queue_physical_block_size_entry.attr,
  	&queue_io_min_entry.attr,
  	&queue_io_opt_entry.attr,
86b372814   Martin K. Petersen   block: Expose dis...
377
378
  	&queue_discard_granularity_entry.attr,
  	&queue_discard_max_entry.attr,
98262f276   Martin K. Petersen   block: Allow devi...
379
  	&queue_discard_zeroes_data_entry.attr,
1308835ff   Bartlomiej Zolnierkiewicz   block: export SSD...
380
  	&queue_nonrot_entry.attr,
ac9fafa12   Alan D. Brunelle   block: Skip I/O m...
381
  	&queue_nomerges_entry.attr,
c7c22e4d5   Jens Axboe   block: add suppor...
382
  	&queue_rq_affinity_entry.attr,
bc58ba946   Jens Axboe   block: add sysfs ...
383
  	&queue_iostats_entry.attr,
e2e1a148b   Jens Axboe   block: add sysfs ...
384
  	&queue_random_entry.attr,
8324aa91d   Jens Axboe   block: split tag ...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
  	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);
  	if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
  		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 ...
415
  	struct request_queue *q;
8324aa91d   Jens Axboe   block: split tag ...
416
417
418
419
  	ssize_t res;
  
  	if (!entry->store)
  		return -EIO;
6728cb0e6   Jens Axboe   block: make core ...
420
421
  
  	q = container_of(kobj, struct request_queue, kobj);
8324aa91d   Jens Axboe   block: split tag ...
422
423
424
425
426
427
428
429
430
431
432
  	mutex_lock(&q->sysfs_lock);
  	if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
  		mutex_unlock(&q->sysfs_lock);
  		return -ENOENT;
  	}
  	res = entry->store(q, page, length);
  	mutex_unlock(&q->sysfs_lock);
  	return res;
  }
  
  /**
499337bb6   Andrew Morton   block/blk-sysfs.c...
433
434
   * 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 ...
435
436
   *
   * Description:
499337bb6   Andrew Morton   block/blk-sysfs.c...
437
   *     blk_release_queue is the pair to blk_init_queue() or
8324aa91d   Jens Axboe   block: split tag ...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
   *     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.
   *
   * Caveat:
   *     Hopefully the low level driver will have finished any
   *     outstanding requests first...
   **/
  static void blk_release_queue(struct kobject *kobj)
  {
  	struct request_queue *q =
  		container_of(kobj, struct request_queue, kobj);
  	struct request_list *rl = &q->rq;
  
  	blk_sync_queue(q);
777eb1bf1   Hannes Reinecke   block: Free queue...
454
455
456
457
  	if (q->elevator)
  		elevator_exit(q->elevator);
  
  	blk_throtl_exit(q);
8324aa91d   Jens Axboe   block: split tag ...
458
459
460
461
462
  	if (rl->rq_pool)
  		mempool_destroy(rl->rq_pool);
  
  	if (q->queue_tags)
  		__blk_queue_free_tags(q);
c9a929dde   Tejun Heo   block: fix reques...
463
  	blk_throtl_release(q);
8324aa91d   Jens Axboe   block: split tag ...
464
465
466
467
468
  	blk_trace_shutdown(q);
  
  	bdi_destroy(&q->backing_dev_info);
  	kmem_cache_free(blk_requestq_cachep, q);
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
469
  static const struct sysfs_ops queue_sysfs_ops = {
8324aa91d   Jens Axboe   block: split tag ...
470
471
472
473
474
475
476
477
478
479
480
481
482
  	.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...
483
  	struct device *dev = disk_to_dev(disk);
8324aa91d   Jens Axboe   block: split tag ...
484
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
485
  	if (WARN_ON(!q))
8324aa91d   Jens Axboe   block: split tag ...
486
  		return -ENXIO;
1d54ad6da   Li Zefan   blktrace: add tra...
487
488
489
  	ret = blk_trace_init_sysfs(dev);
  	if (ret)
  		return ret;
c9059598e   Linus Torvalds   Merge branch 'for...
490
  	ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue");
ed5302d3c   Liu Yuan   block, blk-sysfs:...
491
492
  	if (ret < 0) {
  		blk_trace_remove_sysfs(dev);
8324aa91d   Jens Axboe   block: split tag ...
493
  		return ret;
ed5302d3c   Liu Yuan   block, blk-sysfs:...
494
  	}
8324aa91d   Jens Axboe   block: split tag ...
495
496
  
  	kobject_uevent(&q->kobj, KOBJ_ADD);
cd43e26f0   Martin K. Petersen   block: Expose sta...
497
498
  	if (!q->request_fn)
  		return 0;
8324aa91d   Jens Axboe   block: split tag ...
499
500
501
502
  	ret = elv_register_queue(q);
  	if (ret) {
  		kobject_uevent(&q->kobj, KOBJ_REMOVE);
  		kobject_del(&q->kobj);
80656b67b   Liu Yuan   block, blk-sysfs:...
503
  		blk_trace_remove_sysfs(dev);
c87ffbb81   Xiaotian Feng   block: put dev->k...
504
  		kobject_put(&dev->kobj);
8324aa91d   Jens Axboe   block: split tag ...
505
506
507
508
509
510
511
512
513
  		return ret;
  	}
  
  	return 0;
  }
  
  void blk_unregister_queue(struct gendisk *disk)
  {
  	struct request_queue *q = disk->queue;
fb1997463   Akinobu Mita   block: fix blk_re...
514
515
  	if (WARN_ON(!q))
  		return;
48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
516
  	if (q->request_fn)
8324aa91d   Jens Axboe   block: split tag ...
517
  		elv_unregister_queue(q);
48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
518
519
520
521
  	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 ...
522
  }