Commit | Line | Data |
---|---|---|
07e4fead OS |
1 | /* |
2 | * Copyright (C) 2017 Facebook | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public | |
6 | * License v2 as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
15 | */ | |
16 | ||
17 | #include <linux/kernel.h> | |
18 | #include <linux/blkdev.h> | |
19 | #include <linux/debugfs.h> | |
20 | ||
21 | #include <linux/blk-mq.h> | |
22 | #include "blk-mq.h" | |
d96b37c0 | 23 | #include "blk-mq-tag.h" |
07e4fead OS |
24 | |
25 | struct blk_mq_debugfs_attr { | |
26 | const char *name; | |
27 | umode_t mode; | |
28 | const struct file_operations *fops; | |
29 | }; | |
30 | ||
31 | static struct dentry *block_debugfs_root; | |
32 | ||
950cd7e9 OS |
33 | static int blk_mq_debugfs_seq_open(struct inode *inode, struct file *file, |
34 | const struct seq_operations *ops) | |
35 | { | |
36 | struct seq_file *m; | |
37 | int ret; | |
38 | ||
39 | ret = seq_open(file, ops); | |
40 | if (!ret) { | |
41 | m = file->private_data; | |
42 | m->private = inode->i_private; | |
43 | } | |
44 | return ret; | |
45 | } | |
46 | ||
9abb2ad2 OS |
47 | static int hctx_state_show(struct seq_file *m, void *v) |
48 | { | |
49 | struct blk_mq_hw_ctx *hctx = m->private; | |
50 | ||
51 | seq_printf(m, "0x%lx\n", hctx->state); | |
52 | return 0; | |
53 | } | |
54 | ||
55 | static int hctx_state_open(struct inode *inode, struct file *file) | |
56 | { | |
57 | return single_open(file, hctx_state_show, inode->i_private); | |
58 | } | |
59 | ||
60 | static const struct file_operations hctx_state_fops = { | |
61 | .open = hctx_state_open, | |
62 | .read = seq_read, | |
63 | .llseek = seq_lseek, | |
64 | .release = single_release, | |
65 | }; | |
66 | ||
67 | static int hctx_flags_show(struct seq_file *m, void *v) | |
68 | { | |
69 | struct blk_mq_hw_ctx *hctx = m->private; | |
70 | ||
71 | seq_printf(m, "0x%lx\n", hctx->flags); | |
72 | return 0; | |
73 | } | |
74 | ||
75 | static int hctx_flags_open(struct inode *inode, struct file *file) | |
76 | { | |
77 | return single_open(file, hctx_flags_show, inode->i_private); | |
78 | } | |
79 | ||
80 | static const struct file_operations hctx_flags_fops = { | |
81 | .open = hctx_flags_open, | |
82 | .read = seq_read, | |
83 | .llseek = seq_lseek, | |
84 | .release = single_release, | |
85 | }; | |
86 | ||
950cd7e9 OS |
87 | static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) |
88 | { | |
89 | struct request *rq = list_entry_rq(v); | |
90 | ||
7b393852 OS |
91 | seq_printf(m, "%p {.cmd_type=%u, .cmd_flags=0x%x, .rq_flags=0x%x, .tag=%d, .internal_tag=%d}\n", |
92 | rq, rq->cmd_type, rq->cmd_flags, (unsigned int)rq->rq_flags, | |
93 | rq->tag, rq->internal_tag); | |
950cd7e9 OS |
94 | return 0; |
95 | } | |
96 | ||
97 | static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos) | |
98 | { | |
99 | struct blk_mq_hw_ctx *hctx = m->private; | |
100 | ||
101 | spin_lock(&hctx->lock); | |
102 | return seq_list_start(&hctx->dispatch, *pos); | |
103 | } | |
104 | ||
105 | static void *hctx_dispatch_next(struct seq_file *m, void *v, loff_t *pos) | |
106 | { | |
107 | struct blk_mq_hw_ctx *hctx = m->private; | |
108 | ||
109 | return seq_list_next(v, &hctx->dispatch, pos); | |
110 | } | |
111 | ||
112 | static void hctx_dispatch_stop(struct seq_file *m, void *v) | |
113 | { | |
114 | struct blk_mq_hw_ctx *hctx = m->private; | |
115 | ||
116 | spin_unlock(&hctx->lock); | |
117 | } | |
118 | ||
119 | static const struct seq_operations hctx_dispatch_seq_ops = { | |
120 | .start = hctx_dispatch_start, | |
121 | .next = hctx_dispatch_next, | |
122 | .stop = hctx_dispatch_stop, | |
123 | .show = blk_mq_debugfs_rq_show, | |
124 | }; | |
125 | ||
126 | static int hctx_dispatch_open(struct inode *inode, struct file *file) | |
127 | { | |
128 | return blk_mq_debugfs_seq_open(inode, file, &hctx_dispatch_seq_ops); | |
129 | } | |
130 | ||
131 | static const struct file_operations hctx_dispatch_fops = { | |
132 | .open = hctx_dispatch_open, | |
133 | .read = seq_read, | |
134 | .llseek = seq_lseek, | |
135 | .release = seq_release, | |
136 | }; | |
137 | ||
0bfa5288 OS |
138 | static int hctx_ctx_map_show(struct seq_file *m, void *v) |
139 | { | |
140 | struct blk_mq_hw_ctx *hctx = m->private; | |
141 | ||
142 | sbitmap_bitmap_show(&hctx->ctx_map, m); | |
143 | return 0; | |
144 | } | |
145 | ||
146 | static int hctx_ctx_map_open(struct inode *inode, struct file *file) | |
147 | { | |
148 | return single_open(file, hctx_ctx_map_show, inode->i_private); | |
149 | } | |
150 | ||
151 | static const struct file_operations hctx_ctx_map_fops = { | |
152 | .open = hctx_ctx_map_open, | |
153 | .read = seq_read, | |
154 | .llseek = seq_lseek, | |
155 | .release = single_release, | |
156 | }; | |
157 | ||
d96b37c0 OS |
158 | static void blk_mq_debugfs_tags_show(struct seq_file *m, |
159 | struct blk_mq_tags *tags) | |
160 | { | |
161 | seq_printf(m, "nr_tags=%u\n", tags->nr_tags); | |
162 | seq_printf(m, "nr_reserved_tags=%u\n", tags->nr_reserved_tags); | |
163 | seq_printf(m, "active_queues=%d\n", | |
164 | atomic_read(&tags->active_queues)); | |
165 | ||
166 | seq_puts(m, "\nbitmap_tags:\n"); | |
167 | sbitmap_queue_show(&tags->bitmap_tags, m); | |
168 | ||
169 | if (tags->nr_reserved_tags) { | |
170 | seq_puts(m, "\nbreserved_tags:\n"); | |
171 | sbitmap_queue_show(&tags->breserved_tags, m); | |
172 | } | |
173 | } | |
174 | ||
175 | static int hctx_tags_show(struct seq_file *m, void *v) | |
176 | { | |
177 | struct blk_mq_hw_ctx *hctx = m->private; | |
178 | struct request_queue *q = hctx->queue; | |
179 | ||
180 | mutex_lock(&q->sysfs_lock); | |
181 | if (hctx->tags) | |
182 | blk_mq_debugfs_tags_show(m, hctx->tags); | |
183 | mutex_unlock(&q->sysfs_lock); | |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
188 | static int hctx_tags_open(struct inode *inode, struct file *file) | |
189 | { | |
190 | return single_open(file, hctx_tags_show, inode->i_private); | |
191 | } | |
192 | ||
193 | static const struct file_operations hctx_tags_fops = { | |
194 | .open = hctx_tags_open, | |
195 | .read = seq_read, | |
196 | .llseek = seq_lseek, | |
197 | .release = single_release, | |
198 | }; | |
199 | ||
d7e3621a OS |
200 | static int hctx_tags_bitmap_show(struct seq_file *m, void *v) |
201 | { | |
202 | struct blk_mq_hw_ctx *hctx = m->private; | |
203 | struct request_queue *q = hctx->queue; | |
204 | ||
205 | mutex_lock(&q->sysfs_lock); | |
206 | if (hctx->tags) | |
207 | sbitmap_bitmap_show(&hctx->tags->bitmap_tags.sb, m); | |
208 | mutex_unlock(&q->sysfs_lock); | |
209 | return 0; | |
210 | } | |
211 | ||
212 | static int hctx_tags_bitmap_open(struct inode *inode, struct file *file) | |
213 | { | |
214 | return single_open(file, hctx_tags_bitmap_show, inode->i_private); | |
215 | } | |
216 | ||
217 | static const struct file_operations hctx_tags_bitmap_fops = { | |
218 | .open = hctx_tags_bitmap_open, | |
219 | .read = seq_read, | |
220 | .llseek = seq_lseek, | |
221 | .release = single_release, | |
222 | }; | |
223 | ||
d96b37c0 OS |
224 | static int hctx_sched_tags_show(struct seq_file *m, void *v) |
225 | { | |
226 | struct blk_mq_hw_ctx *hctx = m->private; | |
227 | struct request_queue *q = hctx->queue; | |
228 | ||
229 | mutex_lock(&q->sysfs_lock); | |
230 | if (hctx->sched_tags) | |
231 | blk_mq_debugfs_tags_show(m, hctx->sched_tags); | |
232 | mutex_unlock(&q->sysfs_lock); | |
233 | ||
234 | return 0; | |
235 | } | |
236 | ||
237 | static int hctx_sched_tags_open(struct inode *inode, struct file *file) | |
238 | { | |
239 | return single_open(file, hctx_sched_tags_show, inode->i_private); | |
240 | } | |
241 | ||
242 | static const struct file_operations hctx_sched_tags_fops = { | |
243 | .open = hctx_sched_tags_open, | |
244 | .read = seq_read, | |
245 | .llseek = seq_lseek, | |
246 | .release = single_release, | |
247 | }; | |
248 | ||
d7e3621a OS |
249 | static int hctx_sched_tags_bitmap_show(struct seq_file *m, void *v) |
250 | { | |
251 | struct blk_mq_hw_ctx *hctx = m->private; | |
252 | struct request_queue *q = hctx->queue; | |
253 | ||
254 | mutex_lock(&q->sysfs_lock); | |
255 | if (hctx->sched_tags) | |
256 | sbitmap_bitmap_show(&hctx->sched_tags->bitmap_tags.sb, m); | |
257 | mutex_unlock(&q->sysfs_lock); | |
258 | return 0; | |
259 | } | |
260 | ||
261 | static int hctx_sched_tags_bitmap_open(struct inode *inode, struct file *file) | |
262 | { | |
263 | return single_open(file, hctx_sched_tags_bitmap_show, inode->i_private); | |
264 | } | |
265 | ||
266 | static const struct file_operations hctx_sched_tags_bitmap_fops = { | |
267 | .open = hctx_sched_tags_bitmap_open, | |
268 | .read = seq_read, | |
269 | .llseek = seq_lseek, | |
270 | .release = single_release, | |
271 | }; | |
272 | ||
be215473 OS |
273 | static int hctx_io_poll_show(struct seq_file *m, void *v) |
274 | { | |
275 | struct blk_mq_hw_ctx *hctx = m->private; | |
276 | ||
277 | seq_printf(m, "considered=%lu\n", hctx->poll_considered); | |
278 | seq_printf(m, "invoked=%lu\n", hctx->poll_invoked); | |
279 | seq_printf(m, "success=%lu\n", hctx->poll_success); | |
280 | return 0; | |
281 | } | |
282 | ||
283 | static int hctx_io_poll_open(struct inode *inode, struct file *file) | |
284 | { | |
285 | return single_open(file, hctx_io_poll_show, inode->i_private); | |
286 | } | |
287 | ||
288 | static ssize_t hctx_io_poll_write(struct file *file, const char __user *buf, | |
289 | size_t count, loff_t *ppos) | |
290 | { | |
291 | struct seq_file *m = file->private_data; | |
292 | struct blk_mq_hw_ctx *hctx = m->private; | |
293 | ||
294 | hctx->poll_considered = hctx->poll_invoked = hctx->poll_success = 0; | |
295 | return count; | |
296 | } | |
297 | ||
298 | static const struct file_operations hctx_io_poll_fops = { | |
299 | .open = hctx_io_poll_open, | |
300 | .read = seq_read, | |
301 | .write = hctx_io_poll_write, | |
302 | .llseek = seq_lseek, | |
303 | .release = single_release, | |
304 | }; | |
305 | ||
306 | static void print_stat(struct seq_file *m, struct blk_rq_stat *stat) | |
307 | { | |
308 | seq_printf(m, "samples=%d, mean=%lld, min=%llu, max=%llu", | |
309 | stat->nr_samples, stat->mean, stat->min, stat->max); | |
310 | } | |
311 | ||
312 | static int hctx_stats_show(struct seq_file *m, void *v) | |
313 | { | |
314 | struct blk_mq_hw_ctx *hctx = m->private; | |
315 | struct blk_rq_stat stat[2]; | |
316 | ||
317 | blk_stat_init(&stat[BLK_STAT_READ]); | |
318 | blk_stat_init(&stat[BLK_STAT_WRITE]); | |
319 | ||
320 | blk_hctx_stat_get(hctx, stat); | |
321 | ||
322 | seq_puts(m, "read: "); | |
323 | print_stat(m, &stat[BLK_STAT_READ]); | |
324 | seq_puts(m, "\n"); | |
325 | ||
326 | seq_puts(m, "write: "); | |
327 | print_stat(m, &stat[BLK_STAT_WRITE]); | |
328 | seq_puts(m, "\n"); | |
329 | return 0; | |
330 | } | |
331 | ||
332 | static int hctx_stats_open(struct inode *inode, struct file *file) | |
333 | { | |
334 | return single_open(file, hctx_stats_show, inode->i_private); | |
335 | } | |
336 | ||
337 | static ssize_t hctx_stats_write(struct file *file, const char __user *buf, | |
338 | size_t count, loff_t *ppos) | |
339 | { | |
340 | struct seq_file *m = file->private_data; | |
341 | struct blk_mq_hw_ctx *hctx = m->private; | |
342 | struct blk_mq_ctx *ctx; | |
343 | int i; | |
344 | ||
345 | hctx_for_each_ctx(hctx, ctx, i) { | |
346 | blk_stat_init(&ctx->stat[BLK_STAT_READ]); | |
347 | blk_stat_init(&ctx->stat[BLK_STAT_WRITE]); | |
348 | } | |
349 | return count; | |
350 | } | |
351 | ||
352 | static const struct file_operations hctx_stats_fops = { | |
353 | .open = hctx_stats_open, | |
354 | .read = seq_read, | |
355 | .write = hctx_stats_write, | |
356 | .llseek = seq_lseek, | |
357 | .release = single_release, | |
358 | }; | |
359 | ||
360 | static int hctx_dispatched_show(struct seq_file *m, void *v) | |
361 | { | |
362 | struct blk_mq_hw_ctx *hctx = m->private; | |
363 | int i; | |
364 | ||
365 | seq_printf(m, "%8u\t%lu\n", 0U, hctx->dispatched[0]); | |
366 | ||
367 | for (i = 1; i < BLK_MQ_MAX_DISPATCH_ORDER - 1; i++) { | |
368 | unsigned int d = 1U << (i - 1); | |
369 | ||
370 | seq_printf(m, "%8u\t%lu\n", d, hctx->dispatched[i]); | |
371 | } | |
372 | ||
373 | seq_printf(m, "%8u+\t%lu\n", 1U << (i - 1), hctx->dispatched[i]); | |
374 | return 0; | |
375 | } | |
376 | ||
377 | static int hctx_dispatched_open(struct inode *inode, struct file *file) | |
378 | { | |
379 | return single_open(file, hctx_dispatched_show, inode->i_private); | |
380 | } | |
381 | ||
382 | static ssize_t hctx_dispatched_write(struct file *file, const char __user *buf, | |
383 | size_t count, loff_t *ppos) | |
384 | { | |
385 | struct seq_file *m = file->private_data; | |
386 | struct blk_mq_hw_ctx *hctx = m->private; | |
387 | int i; | |
388 | ||
389 | for (i = 0; i < BLK_MQ_MAX_DISPATCH_ORDER; i++) | |
390 | hctx->dispatched[i] = 0; | |
391 | return count; | |
392 | } | |
393 | ||
394 | static const struct file_operations hctx_dispatched_fops = { | |
395 | .open = hctx_dispatched_open, | |
396 | .read = seq_read, | |
397 | .write = hctx_dispatched_write, | |
398 | .llseek = seq_lseek, | |
399 | .release = single_release, | |
400 | }; | |
401 | ||
950cd7e9 OS |
402 | static void *ctx_rq_list_start(struct seq_file *m, loff_t *pos) |
403 | { | |
404 | struct blk_mq_ctx *ctx = m->private; | |
405 | ||
406 | spin_lock(&ctx->lock); | |
407 | return seq_list_start(&ctx->rq_list, *pos); | |
408 | } | |
409 | ||
410 | static void *ctx_rq_list_next(struct seq_file *m, void *v, loff_t *pos) | |
411 | { | |
412 | struct blk_mq_ctx *ctx = m->private; | |
413 | ||
414 | return seq_list_next(v, &ctx->rq_list, pos); | |
415 | } | |
416 | ||
417 | static void ctx_rq_list_stop(struct seq_file *m, void *v) | |
418 | { | |
419 | struct blk_mq_ctx *ctx = m->private; | |
420 | ||
421 | spin_unlock(&ctx->lock); | |
422 | } | |
423 | ||
424 | static const struct seq_operations ctx_rq_list_seq_ops = { | |
425 | .start = ctx_rq_list_start, | |
426 | .next = ctx_rq_list_next, | |
427 | .stop = ctx_rq_list_stop, | |
428 | .show = blk_mq_debugfs_rq_show, | |
429 | }; | |
430 | ||
431 | static int ctx_rq_list_open(struct inode *inode, struct file *file) | |
432 | { | |
433 | return blk_mq_debugfs_seq_open(inode, file, &ctx_rq_list_seq_ops); | |
434 | } | |
435 | ||
436 | static const struct file_operations ctx_rq_list_fops = { | |
437 | .open = ctx_rq_list_open, | |
438 | .read = seq_read, | |
439 | .llseek = seq_lseek, | |
440 | .release = seq_release, | |
441 | }; | |
442 | ||
07e4fead | 443 | static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = { |
9abb2ad2 OS |
444 | {"state", 0400, &hctx_state_fops}, |
445 | {"flags", 0400, &hctx_flags_fops}, | |
950cd7e9 | 446 | {"dispatch", 0400, &hctx_dispatch_fops}, |
0bfa5288 | 447 | {"ctx_map", 0400, &hctx_ctx_map_fops}, |
d96b37c0 | 448 | {"tags", 0400, &hctx_tags_fops}, |
d7e3621a | 449 | {"tags_bitmap", 0400, &hctx_tags_bitmap_fops}, |
d96b37c0 | 450 | {"sched_tags", 0400, &hctx_sched_tags_fops}, |
d7e3621a | 451 | {"sched_tags_bitmap", 0400, &hctx_sched_tags_bitmap_fops}, |
be215473 OS |
452 | {"io_poll", 0600, &hctx_io_poll_fops}, |
453 | {"stats", 0600, &hctx_stats_fops}, | |
454 | {"dispatched", 0600, &hctx_dispatched_fops}, | |
07e4fead OS |
455 | }; |
456 | ||
457 | static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = { | |
950cd7e9 | 458 | {"rq_list", 0400, &ctx_rq_list_fops}, |
07e4fead OS |
459 | }; |
460 | ||
461 | int blk_mq_debugfs_register(struct request_queue *q, const char *name) | |
462 | { | |
463 | if (!block_debugfs_root) | |
464 | return -ENOENT; | |
465 | ||
466 | q->debugfs_dir = debugfs_create_dir(name, block_debugfs_root); | |
467 | if (!q->debugfs_dir) | |
468 | goto err; | |
469 | ||
470 | if (blk_mq_debugfs_register_hctxs(q)) | |
471 | goto err; | |
472 | ||
473 | return 0; | |
474 | ||
475 | err: | |
476 | blk_mq_debugfs_unregister(q); | |
477 | return -ENOMEM; | |
478 | } | |
479 | ||
480 | void blk_mq_debugfs_unregister(struct request_queue *q) | |
481 | { | |
482 | debugfs_remove_recursive(q->debugfs_dir); | |
483 | q->mq_debugfs_dir = NULL; | |
484 | q->debugfs_dir = NULL; | |
485 | } | |
486 | ||
487 | static int blk_mq_debugfs_register_ctx(struct request_queue *q, | |
488 | struct blk_mq_ctx *ctx, | |
489 | struct dentry *hctx_dir) | |
490 | { | |
491 | struct dentry *ctx_dir; | |
492 | char name[20]; | |
493 | int i; | |
494 | ||
495 | snprintf(name, sizeof(name), "cpu%u", ctx->cpu); | |
496 | ctx_dir = debugfs_create_dir(name, hctx_dir); | |
497 | if (!ctx_dir) | |
498 | return -ENOMEM; | |
499 | ||
500 | for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_ctx_attrs); i++) { | |
501 | const struct blk_mq_debugfs_attr *attr; | |
502 | ||
503 | attr = &blk_mq_debugfs_ctx_attrs[i]; | |
504 | if (!debugfs_create_file(attr->name, attr->mode, ctx_dir, ctx, | |
505 | attr->fops)) | |
506 | return -ENOMEM; | |
507 | } | |
508 | ||
509 | return 0; | |
510 | } | |
511 | ||
512 | static int blk_mq_debugfs_register_hctx(struct request_queue *q, | |
513 | struct blk_mq_hw_ctx *hctx) | |
514 | { | |
515 | struct blk_mq_ctx *ctx; | |
516 | struct dentry *hctx_dir; | |
517 | char name[20]; | |
518 | int i; | |
519 | ||
520 | snprintf(name, sizeof(name), "%u", hctx->queue_num); | |
521 | hctx_dir = debugfs_create_dir(name, q->mq_debugfs_dir); | |
522 | if (!hctx_dir) | |
523 | return -ENOMEM; | |
524 | ||
525 | for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_hctx_attrs); i++) { | |
526 | const struct blk_mq_debugfs_attr *attr; | |
527 | ||
528 | attr = &blk_mq_debugfs_hctx_attrs[i]; | |
529 | if (!debugfs_create_file(attr->name, attr->mode, hctx_dir, hctx, | |
530 | attr->fops)) | |
531 | return -ENOMEM; | |
532 | } | |
533 | ||
534 | hctx_for_each_ctx(hctx, ctx, i) { | |
535 | if (blk_mq_debugfs_register_ctx(q, ctx, hctx_dir)) | |
536 | return -ENOMEM; | |
537 | } | |
538 | ||
539 | return 0; | |
540 | } | |
541 | ||
542 | int blk_mq_debugfs_register_hctxs(struct request_queue *q) | |
543 | { | |
544 | struct blk_mq_hw_ctx *hctx; | |
545 | int i; | |
546 | ||
547 | if (!q->debugfs_dir) | |
548 | return -ENOENT; | |
549 | ||
550 | q->mq_debugfs_dir = debugfs_create_dir("mq", q->debugfs_dir); | |
551 | if (!q->mq_debugfs_dir) | |
552 | goto err; | |
553 | ||
554 | queue_for_each_hw_ctx(q, hctx, i) { | |
555 | if (blk_mq_debugfs_register_hctx(q, hctx)) | |
556 | goto err; | |
557 | } | |
558 | ||
559 | return 0; | |
560 | ||
561 | err: | |
562 | blk_mq_debugfs_unregister_hctxs(q); | |
563 | return -ENOMEM; | |
564 | } | |
565 | ||
566 | void blk_mq_debugfs_unregister_hctxs(struct request_queue *q) | |
567 | { | |
568 | debugfs_remove_recursive(q->mq_debugfs_dir); | |
569 | q->mq_debugfs_dir = NULL; | |
570 | } | |
571 | ||
572 | void blk_mq_debugfs_init(void) | |
573 | { | |
574 | block_debugfs_root = debugfs_create_dir("block", NULL); | |
575 | } |