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