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" 23 #include "blk-mq-tag.h" 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 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 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 87 static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v) 88 { 89 struct request *rq = list_entry_rq(v); 90 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); 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 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 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 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 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 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 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 402 static int hctx_queued_show(struct seq_file *m, void *v) 403 { 404 struct blk_mq_hw_ctx *hctx = m->private; 405 406 seq_printf(m, "%lu\n", hctx->queued); 407 return 0; 408 } 409 410 static int hctx_queued_open(struct inode *inode, struct file *file) 411 { 412 return single_open(file, hctx_queued_show, inode->i_private); 413 } 414 415 static ssize_t hctx_queued_write(struct file *file, const char __user *buf, 416 size_t count, loff_t *ppos) 417 { 418 struct seq_file *m = file->private_data; 419 struct blk_mq_hw_ctx *hctx = m->private; 420 421 hctx->queued = 0; 422 return count; 423 } 424 425 static const struct file_operations hctx_queued_fops = { 426 .open = hctx_queued_open, 427 .read = seq_read, 428 .write = hctx_queued_write, 429 .llseek = seq_lseek, 430 .release = single_release, 431 }; 432 433 static int hctx_run_show(struct seq_file *m, void *v) 434 { 435 struct blk_mq_hw_ctx *hctx = m->private; 436 437 seq_printf(m, "%lu\n", hctx->run); 438 return 0; 439 } 440 441 static int hctx_run_open(struct inode *inode, struct file *file) 442 { 443 return single_open(file, hctx_run_show, inode->i_private); 444 } 445 446 static ssize_t hctx_run_write(struct file *file, const char __user *buf, 447 size_t count, loff_t *ppos) 448 { 449 struct seq_file *m = file->private_data; 450 struct blk_mq_hw_ctx *hctx = m->private; 451 452 hctx->run = 0; 453 return count; 454 } 455 456 static const struct file_operations hctx_run_fops = { 457 .open = hctx_run_open, 458 .read = seq_read, 459 .write = hctx_run_write, 460 .llseek = seq_lseek, 461 .release = single_release, 462 }; 463 464 static int hctx_active_show(struct seq_file *m, void *v) 465 { 466 struct blk_mq_hw_ctx *hctx = m->private; 467 468 seq_printf(m, "%d\n", atomic_read(&hctx->nr_active)); 469 return 0; 470 } 471 472 static int hctx_active_open(struct inode *inode, struct file *file) 473 { 474 return single_open(file, hctx_active_show, inode->i_private); 475 } 476 477 static const struct file_operations hctx_active_fops = { 478 .open = hctx_active_open, 479 .read = seq_read, 480 .llseek = seq_lseek, 481 .release = single_release, 482 }; 483 484 static void *ctx_rq_list_start(struct seq_file *m, loff_t *pos) 485 { 486 struct blk_mq_ctx *ctx = m->private; 487 488 spin_lock(&ctx->lock); 489 return seq_list_start(&ctx->rq_list, *pos); 490 } 491 492 static void *ctx_rq_list_next(struct seq_file *m, void *v, loff_t *pos) 493 { 494 struct blk_mq_ctx *ctx = m->private; 495 496 return seq_list_next(v, &ctx->rq_list, pos); 497 } 498 499 static void ctx_rq_list_stop(struct seq_file *m, void *v) 500 { 501 struct blk_mq_ctx *ctx = m->private; 502 503 spin_unlock(&ctx->lock); 504 } 505 506 static const struct seq_operations ctx_rq_list_seq_ops = { 507 .start = ctx_rq_list_start, 508 .next = ctx_rq_list_next, 509 .stop = ctx_rq_list_stop, 510 .show = blk_mq_debugfs_rq_show, 511 }; 512 513 static int ctx_rq_list_open(struct inode *inode, struct file *file) 514 { 515 return blk_mq_debugfs_seq_open(inode, file, &ctx_rq_list_seq_ops); 516 } 517 518 static const struct file_operations ctx_rq_list_fops = { 519 .open = ctx_rq_list_open, 520 .read = seq_read, 521 .llseek = seq_lseek, 522 .release = seq_release, 523 }; 524 525 static int ctx_dispatched_show(struct seq_file *m, void *v) 526 { 527 struct blk_mq_ctx *ctx = m->private; 528 529 seq_printf(m, "%lu %lu\n", ctx->rq_dispatched[1], ctx->rq_dispatched[0]); 530 return 0; 531 } 532 533 static int ctx_dispatched_open(struct inode *inode, struct file *file) 534 { 535 return single_open(file, ctx_dispatched_show, inode->i_private); 536 } 537 538 static ssize_t ctx_dispatched_write(struct file *file, const char __user *buf, 539 size_t count, loff_t *ppos) 540 { 541 struct seq_file *m = file->private_data; 542 struct blk_mq_ctx *ctx = m->private; 543 544 ctx->rq_dispatched[0] = ctx->rq_dispatched[1] = 0; 545 return count; 546 } 547 548 static const struct file_operations ctx_dispatched_fops = { 549 .open = ctx_dispatched_open, 550 .read = seq_read, 551 .write = ctx_dispatched_write, 552 .llseek = seq_lseek, 553 .release = single_release, 554 }; 555 556 static int ctx_merged_show(struct seq_file *m, void *v) 557 { 558 struct blk_mq_ctx *ctx = m->private; 559 560 seq_printf(m, "%lu\n", ctx->rq_merged); 561 return 0; 562 } 563 564 static int ctx_merged_open(struct inode *inode, struct file *file) 565 { 566 return single_open(file, ctx_merged_show, inode->i_private); 567 } 568 569 static ssize_t ctx_merged_write(struct file *file, const char __user *buf, 570 size_t count, loff_t *ppos) 571 { 572 struct seq_file *m = file->private_data; 573 struct blk_mq_ctx *ctx = m->private; 574 575 ctx->rq_merged = 0; 576 return count; 577 } 578 579 static const struct file_operations ctx_merged_fops = { 580 .open = ctx_merged_open, 581 .read = seq_read, 582 .write = ctx_merged_write, 583 .llseek = seq_lseek, 584 .release = single_release, 585 }; 586 587 static int ctx_completed_show(struct seq_file *m, void *v) 588 { 589 struct blk_mq_ctx *ctx = m->private; 590 591 seq_printf(m, "%lu %lu\n", ctx->rq_completed[1], ctx->rq_completed[0]); 592 return 0; 593 } 594 595 static int ctx_completed_open(struct inode *inode, struct file *file) 596 { 597 return single_open(file, ctx_completed_show, inode->i_private); 598 } 599 600 static ssize_t ctx_completed_write(struct file *file, const char __user *buf, 601 size_t count, loff_t *ppos) 602 { 603 struct seq_file *m = file->private_data; 604 struct blk_mq_ctx *ctx = m->private; 605 606 ctx->rq_completed[0] = ctx->rq_completed[1] = 0; 607 return count; 608 } 609 610 static const struct file_operations ctx_completed_fops = { 611 .open = ctx_completed_open, 612 .read = seq_read, 613 .write = ctx_completed_write, 614 .llseek = seq_lseek, 615 .release = single_release, 616 }; 617 618 static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = { 619 {"state", 0400, &hctx_state_fops}, 620 {"flags", 0400, &hctx_flags_fops}, 621 {"dispatch", 0400, &hctx_dispatch_fops}, 622 {"ctx_map", 0400, &hctx_ctx_map_fops}, 623 {"tags", 0400, &hctx_tags_fops}, 624 {"tags_bitmap", 0400, &hctx_tags_bitmap_fops}, 625 {"sched_tags", 0400, &hctx_sched_tags_fops}, 626 {"sched_tags_bitmap", 0400, &hctx_sched_tags_bitmap_fops}, 627 {"io_poll", 0600, &hctx_io_poll_fops}, 628 {"stats", 0600, &hctx_stats_fops}, 629 {"dispatched", 0600, &hctx_dispatched_fops}, 630 {"queued", 0600, &hctx_queued_fops}, 631 {"run", 0600, &hctx_run_fops}, 632 {"active", 0400, &hctx_active_fops}, 633 }; 634 635 static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = { 636 {"rq_list", 0400, &ctx_rq_list_fops}, 637 {"dispatched", 0600, &ctx_dispatched_fops}, 638 {"merged", 0600, &ctx_merged_fops}, 639 {"completed", 0600, &ctx_completed_fops}, 640 }; 641 642 int blk_mq_debugfs_register(struct request_queue *q, const char *name) 643 { 644 if (!block_debugfs_root) 645 return -ENOENT; 646 647 q->debugfs_dir = debugfs_create_dir(name, block_debugfs_root); 648 if (!q->debugfs_dir) 649 goto err; 650 651 if (blk_mq_debugfs_register_hctxs(q)) 652 goto err; 653 654 return 0; 655 656 err: 657 blk_mq_debugfs_unregister(q); 658 return -ENOMEM; 659 } 660 661 void blk_mq_debugfs_unregister(struct request_queue *q) 662 { 663 debugfs_remove_recursive(q->debugfs_dir); 664 q->mq_debugfs_dir = NULL; 665 q->debugfs_dir = NULL; 666 } 667 668 static int blk_mq_debugfs_register_ctx(struct request_queue *q, 669 struct blk_mq_ctx *ctx, 670 struct dentry *hctx_dir) 671 { 672 struct dentry *ctx_dir; 673 char name[20]; 674 int i; 675 676 snprintf(name, sizeof(name), "cpu%u", ctx->cpu); 677 ctx_dir = debugfs_create_dir(name, hctx_dir); 678 if (!ctx_dir) 679 return -ENOMEM; 680 681 for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_ctx_attrs); i++) { 682 const struct blk_mq_debugfs_attr *attr; 683 684 attr = &blk_mq_debugfs_ctx_attrs[i]; 685 if (!debugfs_create_file(attr->name, attr->mode, ctx_dir, ctx, 686 attr->fops)) 687 return -ENOMEM; 688 } 689 690 return 0; 691 } 692 693 static int blk_mq_debugfs_register_hctx(struct request_queue *q, 694 struct blk_mq_hw_ctx *hctx) 695 { 696 struct blk_mq_ctx *ctx; 697 struct dentry *hctx_dir; 698 char name[20]; 699 int i; 700 701 snprintf(name, sizeof(name), "%u", hctx->queue_num); 702 hctx_dir = debugfs_create_dir(name, q->mq_debugfs_dir); 703 if (!hctx_dir) 704 return -ENOMEM; 705 706 for (i = 0; i < ARRAY_SIZE(blk_mq_debugfs_hctx_attrs); i++) { 707 const struct blk_mq_debugfs_attr *attr; 708 709 attr = &blk_mq_debugfs_hctx_attrs[i]; 710 if (!debugfs_create_file(attr->name, attr->mode, hctx_dir, hctx, 711 attr->fops)) 712 return -ENOMEM; 713 } 714 715 hctx_for_each_ctx(hctx, ctx, i) { 716 if (blk_mq_debugfs_register_ctx(q, ctx, hctx_dir)) 717 return -ENOMEM; 718 } 719 720 return 0; 721 } 722 723 int blk_mq_debugfs_register_hctxs(struct request_queue *q) 724 { 725 struct blk_mq_hw_ctx *hctx; 726 int i; 727 728 if (!q->debugfs_dir) 729 return -ENOENT; 730 731 q->mq_debugfs_dir = debugfs_create_dir("mq", q->debugfs_dir); 732 if (!q->mq_debugfs_dir) 733 goto err; 734 735 queue_for_each_hw_ctx(q, hctx, i) { 736 if (blk_mq_debugfs_register_hctx(q, hctx)) 737 goto err; 738 } 739 740 return 0; 741 742 err: 743 blk_mq_debugfs_unregister_hctxs(q); 744 return -ENOMEM; 745 } 746 747 void blk_mq_debugfs_unregister_hctxs(struct request_queue *q) 748 { 749 debugfs_remove_recursive(q->mq_debugfs_dir); 750 q->mq_debugfs_dir = NULL; 751 } 752 753 void blk_mq_debugfs_init(void) 754 { 755 block_debugfs_root = debugfs_create_dir("block", NULL); 756 } 757