Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.11-rc7 772 lines 19 kB view raw
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 26struct blk_mq_debugfs_attr { 27 const char *name; 28 umode_t mode; 29 const struct file_operations *fops; 30}; 31 32static 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 46static 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 54static int hctx_state_open(struct inode *inode, struct file *file) 55{ 56 return single_open(file, hctx_state_show, inode->i_private); 57} 58 59static 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 66static 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 74static int hctx_flags_open(struct inode *inode, struct file *file) 75{ 76 return single_open(file, hctx_flags_show, inode->i_private); 77} 78 79static 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 86static 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 96static 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 105static 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 112static 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 120static 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 127static 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 132static 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 139static 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 147static 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 152static 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 159static 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 176static 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 189out: 190 return res; 191} 192 193static int hctx_tags_open(struct inode *inode, struct file *file) 194{ 195 return single_open(file, hctx_tags_show, inode->i_private); 196} 197 198static 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 205static 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 218out: 219 return res; 220} 221 222static 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 227static 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 234static 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 247out: 248 return res; 249} 250 251static 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 256static 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 263static 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 276out: 277 return res; 278} 279 280static 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 285static 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 292static 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 302static 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 307static 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 317static 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 325static 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 331static 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 351static int hctx_stats_open(struct inode *inode, struct file *file) 352{ 353 return single_open(file, hctx_stats_show, inode->i_private); 354} 355 356static 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 371static 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 379static 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 396static int hctx_dispatched_open(struct inode *inode, struct file *file) 397{ 398 return single_open(file, hctx_dispatched_show, inode->i_private); 399} 400 401static 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 413static 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 421static 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 429static int hctx_queued_open(struct inode *inode, struct file *file) 430{ 431 return single_open(file, hctx_queued_show, inode->i_private); 432} 433 434static 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 444static 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 452static 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 460static int hctx_run_open(struct inode *inode, struct file *file) 461{ 462 return single_open(file, hctx_run_show, inode->i_private); 463} 464 465static 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 475static 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 483static 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 491static int hctx_active_open(struct inode *inode, struct file *file) 492{ 493 return single_open(file, hctx_active_show, inode->i_private); 494} 495 496static 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 503static 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 512static 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 519static 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 527static 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 534static 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 539static 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 546static 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 554static int ctx_dispatched_open(struct inode *inode, struct file *file) 555{ 556 return single_open(file, ctx_dispatched_show, inode->i_private); 557} 558 559static 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 569static 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 577static 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 585static int ctx_merged_open(struct inode *inode, struct file *file) 586{ 587 return single_open(file, ctx_merged_show, inode->i_private); 588} 589 590static 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 600static 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 608static 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 616static int ctx_completed_open(struct inode *inode, struct file *file) 617{ 618 return single_open(file, ctx_completed_show, inode->i_private); 619} 620 621static 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 631static 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 639static 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 657static 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 665int 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 679err: 680 blk_mq_debugfs_unregister(q); 681 return -ENOMEM; 682} 683 684void 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 691static 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 702static 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 720static 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 744int 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 763err: 764 blk_mq_debugfs_unregister_hctxs(q); 765 return -ENOMEM; 766} 767 768void 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}