blk-mq-debug: Avoid that sparse complains about req_flags_t usage
[linux-block.git] / block / blk-mq-debugfs.c
CommitLineData
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
25struct blk_mq_debugfs_attr {
26 const char *name;
27 umode_t mode;
28 const struct file_operations *fops;
29};
30
31static struct dentry *block_debugfs_root;
32
950cd7e9
OS
33static 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
47static 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
55static int hctx_state_open(struct inode *inode, struct file *file)
56{
57 return single_open(file, hctx_state_show, inode->i_private);
58}
59
60static 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
67static 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
75static int hctx_flags_open(struct inode *inode, struct file *file)
76{
77 return single_open(file, hctx_flags_show, inode->i_private);
78}
79
80static 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
87static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v)
88{
89 struct request *rq = list_entry_rq(v);
90
aebf526b 91 seq_printf(m, "%p {.cmd_flags=0x%x, .rq_flags=0x%x, .tag=%d, .internal_tag=%d}\n",
a1ae0f74 92 rq, rq->cmd_flags, (__force unsigned int)rq->rq_flags,
7b393852 93 rq->tag, rq->internal_tag);
950cd7e9
OS
94 return 0;
95}
96
97static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos)
f3bcb0e6 98 __acquires(&hctx->lock)
950cd7e9
OS
99{
100 struct blk_mq_hw_ctx *hctx = m->private;
101
102 spin_lock(&hctx->lock);
103 return seq_list_start(&hctx->dispatch, *pos);
104}
105
106static void *hctx_dispatch_next(struct seq_file *m, void *v, loff_t *pos)
107{
108 struct blk_mq_hw_ctx *hctx = m->private;
109
110 return seq_list_next(v, &hctx->dispatch, pos);
111}
112
113static void hctx_dispatch_stop(struct seq_file *m, void *v)
f3bcb0e6 114 __releases(&hctx->lock)
950cd7e9
OS
115{
116 struct blk_mq_hw_ctx *hctx = m->private;
117
118 spin_unlock(&hctx->lock);
119}
120
121static const struct seq_operations hctx_dispatch_seq_ops = {
122 .start = hctx_dispatch_start,
123 .next = hctx_dispatch_next,
124 .stop = hctx_dispatch_stop,
125 .show = blk_mq_debugfs_rq_show,
126};
127
128static int hctx_dispatch_open(struct inode *inode, struct file *file)
129{
130 return blk_mq_debugfs_seq_open(inode, file, &hctx_dispatch_seq_ops);
131}
132
133static const struct file_operations hctx_dispatch_fops = {
134 .open = hctx_dispatch_open,
135 .read = seq_read,
136 .llseek = seq_lseek,
137 .release = seq_release,
138};
139
0bfa5288
OS
140static int hctx_ctx_map_show(struct seq_file *m, void *v)
141{
142 struct blk_mq_hw_ctx *hctx = m->private;
143
144 sbitmap_bitmap_show(&hctx->ctx_map, m);
145 return 0;
146}
147
148static int hctx_ctx_map_open(struct inode *inode, struct file *file)
149{
150 return single_open(file, hctx_ctx_map_show, inode->i_private);
151}
152
153static const struct file_operations hctx_ctx_map_fops = {
154 .open = hctx_ctx_map_open,
155 .read = seq_read,
156 .llseek = seq_lseek,
157 .release = single_release,
158};
159
d96b37c0
OS
160static void blk_mq_debugfs_tags_show(struct seq_file *m,
161 struct blk_mq_tags *tags)
162{
163 seq_printf(m, "nr_tags=%u\n", tags->nr_tags);
164 seq_printf(m, "nr_reserved_tags=%u\n", tags->nr_reserved_tags);
165 seq_printf(m, "active_queues=%d\n",
166 atomic_read(&tags->active_queues));
167
168 seq_puts(m, "\nbitmap_tags:\n");
169 sbitmap_queue_show(&tags->bitmap_tags, m);
170
171 if (tags->nr_reserved_tags) {
172 seq_puts(m, "\nbreserved_tags:\n");
173 sbitmap_queue_show(&tags->breserved_tags, m);
174 }
175}
176
177static int hctx_tags_show(struct seq_file *m, void *v)
178{
179 struct blk_mq_hw_ctx *hctx = m->private;
180 struct request_queue *q = hctx->queue;
181
182 mutex_lock(&q->sysfs_lock);
183 if (hctx->tags)
184 blk_mq_debugfs_tags_show(m, hctx->tags);
185 mutex_unlock(&q->sysfs_lock);
186
187 return 0;
188}
189
190static int hctx_tags_open(struct inode *inode, struct file *file)
191{
192 return single_open(file, hctx_tags_show, inode->i_private);
193}
194
195static const struct file_operations hctx_tags_fops = {
196 .open = hctx_tags_open,
197 .read = seq_read,
198 .llseek = seq_lseek,
199 .release = single_release,
200};
201
d7e3621a
OS
202static int hctx_tags_bitmap_show(struct seq_file *m, void *v)
203{
204 struct blk_mq_hw_ctx *hctx = m->private;
205 struct request_queue *q = hctx->queue;
206
207 mutex_lock(&q->sysfs_lock);
208 if (hctx->tags)
209 sbitmap_bitmap_show(&hctx->tags->bitmap_tags.sb, m);
210 mutex_unlock(&q->sysfs_lock);
211 return 0;
212}
213
214static int hctx_tags_bitmap_open(struct inode *inode, struct file *file)
215{
216 return single_open(file, hctx_tags_bitmap_show, inode->i_private);
217}
218
219static const struct file_operations hctx_tags_bitmap_fops = {
220 .open = hctx_tags_bitmap_open,
221 .read = seq_read,
222 .llseek = seq_lseek,
223 .release = single_release,
224};
225
d96b37c0
OS
226static int hctx_sched_tags_show(struct seq_file *m, void *v)
227{
228 struct blk_mq_hw_ctx *hctx = m->private;
229 struct request_queue *q = hctx->queue;
230
231 mutex_lock(&q->sysfs_lock);
232 if (hctx->sched_tags)
233 blk_mq_debugfs_tags_show(m, hctx->sched_tags);
234 mutex_unlock(&q->sysfs_lock);
235
236 return 0;
237}
238
239static int hctx_sched_tags_open(struct inode *inode, struct file *file)
240{
241 return single_open(file, hctx_sched_tags_show, inode->i_private);
242}
243
244static const struct file_operations hctx_sched_tags_fops = {
245 .open = hctx_sched_tags_open,
246 .read = seq_read,
247 .llseek = seq_lseek,
248 .release = single_release,
249};
250
d7e3621a
OS
251static int hctx_sched_tags_bitmap_show(struct seq_file *m, void *v)
252{
253 struct blk_mq_hw_ctx *hctx = m->private;
254 struct request_queue *q = hctx->queue;
255
256 mutex_lock(&q->sysfs_lock);
257 if (hctx->sched_tags)
258 sbitmap_bitmap_show(&hctx->sched_tags->bitmap_tags.sb, m);
259 mutex_unlock(&q->sysfs_lock);
260 return 0;
261}
262
263static int hctx_sched_tags_bitmap_open(struct inode *inode, struct file *file)
264{
265 return single_open(file, hctx_sched_tags_bitmap_show, inode->i_private);
266}
267
268static const struct file_operations hctx_sched_tags_bitmap_fops = {
269 .open = hctx_sched_tags_bitmap_open,
270 .read = seq_read,
271 .llseek = seq_lseek,
272 .release = single_release,
273};
274
be215473
OS
275static int hctx_io_poll_show(struct seq_file *m, void *v)
276{
277 struct blk_mq_hw_ctx *hctx = m->private;
278
279 seq_printf(m, "considered=%lu\n", hctx->poll_considered);
280 seq_printf(m, "invoked=%lu\n", hctx->poll_invoked);
281 seq_printf(m, "success=%lu\n", hctx->poll_success);
282 return 0;
283}
284
285static int hctx_io_poll_open(struct inode *inode, struct file *file)
286{
287 return single_open(file, hctx_io_poll_show, inode->i_private);
288}
289
290static ssize_t hctx_io_poll_write(struct file *file, const char __user *buf,
291 size_t count, loff_t *ppos)
292{
293 struct seq_file *m = file->private_data;
294 struct blk_mq_hw_ctx *hctx = m->private;
295
296 hctx->poll_considered = hctx->poll_invoked = hctx->poll_success = 0;
297 return count;
298}
299
300static const struct file_operations hctx_io_poll_fops = {
301 .open = hctx_io_poll_open,
302 .read = seq_read,
303 .write = hctx_io_poll_write,
304 .llseek = seq_lseek,
305 .release = single_release,
306};
307
308static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)
309{
310 seq_printf(m, "samples=%d, mean=%lld, min=%llu, max=%llu",
311 stat->nr_samples, stat->mean, stat->min, stat->max);
312}
313
314static int hctx_stats_show(struct seq_file *m, void *v)
315{
316 struct blk_mq_hw_ctx *hctx = m->private;
317 struct blk_rq_stat stat[2];
318
319 blk_stat_init(&stat[BLK_STAT_READ]);
320 blk_stat_init(&stat[BLK_STAT_WRITE]);
321
322 blk_hctx_stat_get(hctx, stat);
323
324 seq_puts(m, "read: ");
325 print_stat(m, &stat[BLK_STAT_READ]);
326 seq_puts(m, "\n");
327
328 seq_puts(m, "write: ");
329 print_stat(m, &stat[BLK_STAT_WRITE]);
330 seq_puts(m, "\n");
331 return 0;
332}
333
334static int hctx_stats_open(struct inode *inode, struct file *file)
335{
336 return single_open(file, hctx_stats_show, inode->i_private);
337}
338
339static ssize_t hctx_stats_write(struct file *file, const char __user *buf,
340 size_t count, loff_t *ppos)
341{
342 struct seq_file *m = file->private_data;
343 struct blk_mq_hw_ctx *hctx = m->private;
344 struct blk_mq_ctx *ctx;
345 int i;
346
347 hctx_for_each_ctx(hctx, ctx, i) {
348 blk_stat_init(&ctx->stat[BLK_STAT_READ]);
349 blk_stat_init(&ctx->stat[BLK_STAT_WRITE]);
350 }
351 return count;
352}
353
354static const struct file_operations hctx_stats_fops = {
355 .open = hctx_stats_open,
356 .read = seq_read,
357 .write = hctx_stats_write,
358 .llseek = seq_lseek,
359 .release = single_release,
360};
361
362static int hctx_dispatched_show(struct seq_file *m, void *v)
363{
364 struct blk_mq_hw_ctx *hctx = m->private;
365 int i;
366
367 seq_printf(m, "%8u\t%lu\n", 0U, hctx->dispatched[0]);
368
369 for (i = 1; i < BLK_MQ_MAX_DISPATCH_ORDER - 1; i++) {
370 unsigned int d = 1U << (i - 1);
371
372 seq_printf(m, "%8u\t%lu\n", d, hctx->dispatched[i]);
373 }
374
375 seq_printf(m, "%8u+\t%lu\n", 1U << (i - 1), hctx->dispatched[i]);
376 return 0;
377}
378
379static int hctx_dispatched_open(struct inode *inode, struct file *file)
380{
381 return single_open(file, hctx_dispatched_show, inode->i_private);
382}
383
384static ssize_t hctx_dispatched_write(struct file *file, const char __user *buf,
385 size_t count, loff_t *ppos)
386{
387 struct seq_file *m = file->private_data;
388 struct blk_mq_hw_ctx *hctx = m->private;
389 int i;
390
391 for (i = 0; i < BLK_MQ_MAX_DISPATCH_ORDER; i++)
392 hctx->dispatched[i] = 0;
393 return count;
394}
395
396static const struct file_operations hctx_dispatched_fops = {
397 .open = hctx_dispatched_open,
398 .read = seq_read,
399 .write = hctx_dispatched_write,
400 .llseek = seq_lseek,
401 .release = single_release,
402};
403
4a46f05e
OS
404static int hctx_queued_show(struct seq_file *m, void *v)
405{
406 struct blk_mq_hw_ctx *hctx = m->private;
407
408 seq_printf(m, "%lu\n", hctx->queued);
409 return 0;
410}
411
412static int hctx_queued_open(struct inode *inode, struct file *file)
413{
414 return single_open(file, hctx_queued_show, inode->i_private);
415}
416
417static ssize_t hctx_queued_write(struct file *file, const char __user *buf,
418 size_t count, loff_t *ppos)
419{
420 struct seq_file *m = file->private_data;
421 struct blk_mq_hw_ctx *hctx = m->private;
422
423 hctx->queued = 0;
424 return count;
425}
426
427static const struct file_operations hctx_queued_fops = {
428 .open = hctx_queued_open,
429 .read = seq_read,
430 .write = hctx_queued_write,
431 .llseek = seq_lseek,
432 .release = single_release,
433};
434
435static int hctx_run_show(struct seq_file *m, void *v)
436{
437 struct blk_mq_hw_ctx *hctx = m->private;
438
439 seq_printf(m, "%lu\n", hctx->run);
440 return 0;
441}
442
443static int hctx_run_open(struct inode *inode, struct file *file)
444{
445 return single_open(file, hctx_run_show, inode->i_private);
446}
447
448static ssize_t hctx_run_write(struct file *file, const char __user *buf,
449 size_t count, loff_t *ppos)
450{
451 struct seq_file *m = file->private_data;
452 struct blk_mq_hw_ctx *hctx = m->private;
453
454 hctx->run = 0;
455 return count;
456}
457
458static const struct file_operations hctx_run_fops = {
459 .open = hctx_run_open,
460 .read = seq_read,
461 .write = hctx_run_write,
462 .llseek = seq_lseek,
463 .release = single_release,
464};
465
466static int hctx_active_show(struct seq_file *m, void *v)
467{
468 struct blk_mq_hw_ctx *hctx = m->private;
469
470 seq_printf(m, "%d\n", atomic_read(&hctx->nr_active));
471 return 0;
472}
473
474static int hctx_active_open(struct inode *inode, struct file *file)
475{
476 return single_open(file, hctx_active_show, inode->i_private);
477}
478
479static const struct file_operations hctx_active_fops = {
480 .open = hctx_active_open,
481 .read = seq_read,
482 .llseek = seq_lseek,
483 .release = single_release,
484};
485
950cd7e9 486static void *ctx_rq_list_start(struct seq_file *m, loff_t *pos)
f3bcb0e6 487 __acquires(&ctx->lock)
950cd7e9
OS
488{
489 struct blk_mq_ctx *ctx = m->private;
490
491 spin_lock(&ctx->lock);
492 return seq_list_start(&ctx->rq_list, *pos);
493}
494
495static void *ctx_rq_list_next(struct seq_file *m, void *v, loff_t *pos)
496{
497 struct blk_mq_ctx *ctx = m->private;
498
499 return seq_list_next(v, &ctx->rq_list, pos);
500}
501
502static void ctx_rq_list_stop(struct seq_file *m, void *v)
f3bcb0e6 503 __releases(&ctx->lock)
950cd7e9
OS
504{
505 struct blk_mq_ctx *ctx = m->private;
506
507 spin_unlock(&ctx->lock);
508}
509
510static const struct seq_operations ctx_rq_list_seq_ops = {
511 .start = ctx_rq_list_start,
512 .next = ctx_rq_list_next,
513 .stop = ctx_rq_list_stop,
514 .show = blk_mq_debugfs_rq_show,
515};
516
517static int ctx_rq_list_open(struct inode *inode, struct file *file)
518{
519 return blk_mq_debugfs_seq_open(inode, file, &ctx_rq_list_seq_ops);
520}
521
522static const struct file_operations ctx_rq_list_fops = {
523 .open = ctx_rq_list_open,
524 .read = seq_read,
525 .llseek = seq_lseek,
526 .release = seq_release,
527};
528
4a46f05e
OS
529static int ctx_dispatched_show(struct seq_file *m, void *v)
530{
531 struct blk_mq_ctx *ctx = m->private;
532
533 seq_printf(m, "%lu %lu\n", ctx->rq_dispatched[1], ctx->rq_dispatched[0]);
534 return 0;
535}
536
537static int ctx_dispatched_open(struct inode *inode, struct file *file)
538{
539 return single_open(file, ctx_dispatched_show, inode->i_private);
540}
541
542static ssize_t ctx_dispatched_write(struct file *file, const char __user *buf,
543 size_t count, loff_t *ppos)
544{
545 struct seq_file *m = file->private_data;
546 struct blk_mq_ctx *ctx = m->private;
547
548 ctx->rq_dispatched[0] = ctx->rq_dispatched[1] = 0;
549 return count;
550}
551
552static const struct file_operations ctx_dispatched_fops = {
553 .open = ctx_dispatched_open,
554 .read = seq_read,
555 .write = ctx_dispatched_write,
556 .llseek = seq_lseek,
557 .release = single_release,
558};
559
560static int ctx_merged_show(struct seq_file *m, void *v)
561{
562 struct blk_mq_ctx *ctx = m->private;
563
564 seq_printf(m, "%lu\n", ctx->rq_merged);
565 return 0;
566}
567
568static int ctx_merged_open(struct inode *inode, struct file *file)
569{
570 return single_open(file, ctx_merged_show, inode->i_private);
571}
572
573static ssize_t ctx_merged_write(struct file *file, const char __user *buf,
574 size_t count, loff_t *ppos)
575{
576 struct seq_file *m = file->private_data;
577 struct blk_mq_ctx *ctx = m->private;
578
579 ctx->rq_merged = 0;
580 return count;
581}
582
583static const struct file_operations ctx_merged_fops = {
584 .open = ctx_merged_open,
585 .read = seq_read,
586 .write = ctx_merged_write,
587 .llseek = seq_lseek,
588 .release = single_release,
589};
590
591static int ctx_completed_show(struct seq_file *m, void *v)
592{
593 struct blk_mq_ctx *ctx = m->private;
594
595 seq_printf(m, "%lu %lu\n", ctx->rq_completed[1], ctx->rq_completed[0]);
596 return 0;
597}
598
599static int ctx_completed_open(struct inode *inode, struct file *file)
600{
601 return single_open(file, ctx_completed_show, inode->i_private);
602}
603
604static ssize_t ctx_completed_write(struct file *file, const char __user *buf,
605 size_t count, loff_t *ppos)
606{
607 struct seq_file *m = file->private_data;
608 struct blk_mq_ctx *ctx = m->private;
609
610 ctx->rq_completed[0] = ctx->rq_completed[1] = 0;
611 return count;
612}
613
614static const struct file_operations ctx_completed_fops = {
615 .open = ctx_completed_open,
616 .read = seq_read,
617 .write = ctx_completed_write,
618 .llseek = seq_lseek,
619 .release = single_release,
620};
621
07e4fead 622static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = {
9abb2ad2
OS
623 {"state", 0400, &hctx_state_fops},
624 {"flags", 0400, &hctx_flags_fops},
950cd7e9 625 {"dispatch", 0400, &hctx_dispatch_fops},
0bfa5288 626 {"ctx_map", 0400, &hctx_ctx_map_fops},
d96b37c0 627 {"tags", 0400, &hctx_tags_fops},
d7e3621a 628 {"tags_bitmap", 0400, &hctx_tags_bitmap_fops},
d96b37c0 629 {"sched_tags", 0400, &hctx_sched_tags_fops},
d7e3621a 630 {"sched_tags_bitmap", 0400, &hctx_sched_tags_bitmap_fops},
be215473
OS
631 {"io_poll", 0600, &hctx_io_poll_fops},
632 {"stats", 0600, &hctx_stats_fops},
633 {"dispatched", 0600, &hctx_dispatched_fops},
4a46f05e
OS
634 {"queued", 0600, &hctx_queued_fops},
635 {"run", 0600, &hctx_run_fops},
636 {"active", 0400, &hctx_active_fops},
07e4fead
OS
637};
638
639static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
950cd7e9 640 {"rq_list", 0400, &ctx_rq_list_fops},
4a46f05e
OS
641 {"dispatched", 0600, &ctx_dispatched_fops},
642 {"merged", 0600, &ctx_merged_fops},
643 {"completed", 0600, &ctx_completed_fops},
07e4fead
OS
644};
645
646int blk_mq_debugfs_register(struct request_queue *q, const char *name)
647{
648 if (!block_debugfs_root)
649 return -ENOENT;
650
651 q->debugfs_dir = debugfs_create_dir(name, block_debugfs_root);
652 if (!q->debugfs_dir)
653 goto err;
654
655 if (blk_mq_debugfs_register_hctxs(q))
656 goto err;
657
658 return 0;
659
660err:
661 blk_mq_debugfs_unregister(q);
662 return -ENOMEM;
663}
664
665void blk_mq_debugfs_unregister(struct request_queue *q)
666{
667 debugfs_remove_recursive(q->debugfs_dir);
668 q->mq_debugfs_dir = NULL;
669 q->debugfs_dir = NULL;
670}
671
672static int blk_mq_debugfs_register_ctx(struct request_queue *q,
673 struct blk_mq_ctx *ctx,
674 struct dentry *hctx_dir)
675{
676 struct dentry *ctx_dir;
677 char name[20];
678 int i;
679
680 snprintf(name, sizeof(name), "cpu%u", ctx->cpu);
681 ctx_dir = debugfs_create_dir(name, hctx_dir);
682 if (!ctx_dir)
683 return -ENOMEM;
684
685 for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_ctx_attrs); i++) {
686 const struct blk_mq_debugfs_attr *attr;
687
688 attr = &blk_mq_debugfs_ctx_attrs[i];
689 if (!debugfs_create_file(attr->name, attr->mode, ctx_dir, ctx,
690 attr->fops))
691 return -ENOMEM;
692 }
693
694 return 0;
695}
696
697static int blk_mq_debugfs_register_hctx(struct request_queue *q,
698 struct blk_mq_hw_ctx *hctx)
699{
700 struct blk_mq_ctx *ctx;
701 struct dentry *hctx_dir;
702 char name[20];
703 int i;
704
705 snprintf(name, sizeof(name), "%u", hctx->queue_num);
706 hctx_dir = debugfs_create_dir(name, q->mq_debugfs_dir);
707 if (!hctx_dir)
708 return -ENOMEM;
709
710 for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_hctx_attrs); i++) {
711 const struct blk_mq_debugfs_attr *attr;
712
713 attr = &blk_mq_debugfs_hctx_attrs[i];
714 if (!debugfs_create_file(attr->name, attr->mode, hctx_dir, hctx,
715 attr->fops))
716 return -ENOMEM;
717 }
718
719 hctx_for_each_ctx(hctx, ctx, i) {
720 if (blk_mq_debugfs_register_ctx(q, ctx, hctx_dir))
721 return -ENOMEM;
722 }
723
724 return 0;
725}
726
727int blk_mq_debugfs_register_hctxs(struct request_queue *q)
728{
729 struct blk_mq_hw_ctx *hctx;
730 int i;
731
732 if (!q->debugfs_dir)
733 return -ENOENT;
734
735 q->mq_debugfs_dir = debugfs_create_dir("mq", q->debugfs_dir);
736 if (!q->mq_debugfs_dir)
737 goto err;
738
739 queue_for_each_hw_ctx(q, hctx, i) {
740 if (blk_mq_debugfs_register_hctx(q, hctx))
741 goto err;
742 }
743
744 return 0;
745
746err:
747 blk_mq_debugfs_unregister_hctxs(q);
748 return -ENOMEM;
749}
750
751void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
752{
753 debugfs_remove_recursive(q->mq_debugfs_dir);
754 q->mq_debugfs_dir = NULL;
755}
756
757void blk_mq_debugfs_init(void)
758{
759 block_debugfs_root = debugfs_create_dir("block", NULL);
760}