diff options
author | Daniel Hill <daniel@gluo.nz> | 2022-07-14 20:33:09 +1200 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:35 -0400 |
commit | c807ca95a6e20bedbbb84287bc7087c2b2b775de (patch) | |
tree | 0add067029709ede728fd48ca3761325fe1cd8fc /fs/bcachefs/debug.c | |
parent | 25055c690f9ab3d4fb72b8a07323bf952c2682dc (diff) | |
download | lwn-c807ca95a6e20bedbbb84287bc7087c2b2b775de.tar.gz lwn-c807ca95a6e20bedbbb84287bc7087c2b2b775de.zip |
bcachefs: added lock held time stats
We now record the length of time btree locks are held and expose this in debugfs.
Enabled via CONFIG_BCACHEFS_LOCK_TIME_STATS.
Signed-off-by: Daniel Hill <daniel@gluo.nz>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/debug.c')
-rw-r--r-- | fs/bcachefs/debug.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c index 0f25b75e3de7..45f5229f20eb 100644 --- a/fs/bcachefs/debug.c +++ b/fs/bcachefs/debug.c @@ -638,6 +638,75 @@ static const struct file_operations journal_pins_ops = { .read = bch2_journal_pins_read, }; +static int lock_held_stats_open(struct inode *inode, struct file *file) +{ + struct bch_fs *c = inode->i_private; + struct dump_iter *i; + + i = kzalloc(sizeof(struct dump_iter), GFP_KERNEL); + + if (!i) + return -ENOMEM; + + i->iter = 0; + i->c = c; + i->buf = PRINTBUF; + file->private_data = i; + + return 0; +} + +static int lock_held_stats_release(struct inode *inode, struct file *file) +{ + struct dump_iter *i = file->private_data; + + printbuf_exit(&i->buf); + kfree(i); + + return 0; +} + +static ssize_t lock_held_stats_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + struct dump_iter *i = file->private_data; + struct lock_held_stats *lhs = &i->c->lock_held_stats; + int err; + + i->ubuf = buf; + i->size = size; + i->ret = 0; + + while (lhs->names[i->iter] != 0 && i->iter < BCH_LOCK_TIME_NR) { + err = flush_buf(i); + if (err) + return err; + + if (!i->size) + break; + + prt_printf(&i->buf, "%s:", lhs->names[i->iter]); + prt_newline(&i->buf); + printbuf_indent_add(&i->buf, 8); + bch2_time_stats_to_text(&i->buf, &lhs->times[i->iter]); + printbuf_indent_sub(&i->buf, 8); + prt_newline(&i->buf); + i->iter++; + } + + if (i->buf.allocation_failure) + return -ENOMEM; + + return i->ret; +} + +static const struct file_operations lock_held_stats_op = { + .owner = THIS_MODULE, + .open = lock_held_stats_open, + .release = lock_held_stats_release, + .read = lock_held_stats_read, +}; + void bch2_fs_debug_exit(struct bch_fs *c) { if (!IS_ERR_OR_NULL(c->fs_debug_dir)) @@ -668,6 +737,11 @@ void bch2_fs_debug_init(struct bch_fs *c) debugfs_create_file("journal_pins", 0400, c->fs_debug_dir, c->btree_debug, &journal_pins_ops); + if (IS_ENABLED(CONFIG_BCACHEFS_LOCK_TIME_STATS)) { + debugfs_create_file("lock_held_stats", 0400, c->fs_debug_dir, + c, &lock_held_stats_op); + } + c->btree_debug_dir = debugfs_create_dir("btrees", c->fs_debug_dir); if (IS_ERR_OR_NULL(c->btree_debug_dir)) return; |