Commit e55958c8 authored by Ioannis Angelakopoulos's avatar Ioannis Angelakopoulos Committed by David Sterba

btrfs: collect commit stats, count, duration

Track several stats about transaction commit, to be later exported via
sysfs:

- number of commits so far
- duration of the last commit in ns
- maximum commit duration seen so far in ns
- total duration for all commits so far in ns

The update of the commit stats occurs after the commit thread has gone
through all the logic that checks if there is another thread committing
at the same time. This means that we only account for actual commit work
in the commit stats we report and not the time the thread spends waiting
until it is ready to do the commit work.
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarIoannis Angelakopoulos <iangelak@fb.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent f3e90c1c
...@@ -667,6 +667,18 @@ enum btrfs_exclusive_operation { ...@@ -667,6 +667,18 @@ enum btrfs_exclusive_operation {
BTRFS_EXCLOP_SWAP_ACTIVATE, BTRFS_EXCLOP_SWAP_ACTIVATE,
}; };
/* Store data about transaction commits, exported via sysfs. */
struct btrfs_commit_stats {
/* Total number of commits */
u64 commit_count;
/* The maximum commit duration so far in ns */
u64 max_commit_dur;
/* The last commit duration in ns */
u64 last_commit_dur;
/* The total commit duration in ns */
u64 total_commit_dur;
};
struct btrfs_fs_info { struct btrfs_fs_info {
u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
unsigned long flags; unsigned long flags;
...@@ -1075,6 +1087,9 @@ struct btrfs_fs_info { ...@@ -1075,6 +1087,9 @@ struct btrfs_fs_info {
spinlock_t zone_active_bgs_lock; spinlock_t zone_active_bgs_lock;
struct list_head zone_active_bgs; struct list_head zone_active_bgs;
/* Updates are not protected by any lock */
struct btrfs_commit_stats commit_stats;
#ifdef CONFIG_BTRFS_FS_REF_VERIFY #ifdef CONFIG_BTRFS_FS_REF_VERIFY
spinlock_t ref_verify_lock; spinlock_t ref_verify_lock;
struct rb_root block_tree; struct rb_root block_tree;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/uuid.h> #include <linux/uuid.h>
#include <linux/timekeeping.h>
#include "misc.h" #include "misc.h"
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
...@@ -2098,12 +2099,23 @@ static void add_pending_snapshot(struct btrfs_trans_handle *trans) ...@@ -2098,12 +2099,23 @@ static void add_pending_snapshot(struct btrfs_trans_handle *trans)
list_add(&trans->pending_snapshot->list, &cur_trans->pending_snapshots); list_add(&trans->pending_snapshot->list, &cur_trans->pending_snapshots);
} }
static void update_commit_stats(struct btrfs_fs_info *fs_info, ktime_t interval)
{
fs_info->commit_stats.commit_count++;
fs_info->commit_stats.last_commit_dur = interval;
fs_info->commit_stats.max_commit_dur =
max_t(u64, fs_info->commit_stats.max_commit_dur, interval);
fs_info->commit_stats.total_commit_dur += interval;
}
int btrfs_commit_transaction(struct btrfs_trans_handle *trans) int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
{ {
struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_transaction *cur_trans = trans->transaction;
struct btrfs_transaction *prev_trans = NULL; struct btrfs_transaction *prev_trans = NULL;
int ret; int ret;
ktime_t start_time;
ktime_t interval;
ASSERT(refcount_read(&trans->use_count) == 1); ASSERT(refcount_read(&trans->use_count) == 1);
...@@ -2228,6 +2240,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) ...@@ -2228,6 +2240,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
} }
} }
/*
* Get the time spent on the work done by the commit thread and not
* the time spent waiting on a previous commit
*/
start_time = ktime_get_ns();
extwriter_counter_dec(cur_trans, trans->type); extwriter_counter_dec(cur_trans, trans->type);
ret = btrfs_start_delalloc_flush(fs_info); ret = btrfs_start_delalloc_flush(fs_info);
...@@ -2469,6 +2487,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) ...@@ -2469,6 +2487,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
trace_btrfs_transaction_commit(fs_info); trace_btrfs_transaction_commit(fs_info);
interval = ktime_get_ns() - start_time;
btrfs_scrub_continue(fs_info); btrfs_scrub_continue(fs_info);
if (current->journal_info == trans) if (current->journal_info == trans)
...@@ -2476,6 +2496,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) ...@@ -2476,6 +2496,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
kmem_cache_free(btrfs_trans_handle_cachep, trans); kmem_cache_free(btrfs_trans_handle_cachep, trans);
update_commit_stats(fs_info, interval);
return ret; return ret;
unlock_reloc: unlock_reloc:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment