[TCWG CI] Regression caused by linux: btrfs: Add the capability of getting commit stats in BTRFS: commit 55bc1b4598a319f2bc8d558caf81244c2a15de3b Author: Ioannis Angelakopoulos iangelak@fb.com
btrfs: Add the capability of getting commit stats in BTRFS
Results regressed to # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1: -5 # build_abe qemu: -2 # linux_n_obj: 20671 # First few build errors in logs: # 00:15:03 fs/btrfs/transaction.c:2091:31: error: ‘struct btrfs_commit_stats’ has no member named ‘commit_counter’; did you mean ‘commit_count’? # 00:15:03 make[2]: *** [fs/btrfs/transaction.o] Error 1 # 00:18:18 make[1]: *** [fs/btrfs] Error 2 # 00:19:58 make: *** [fs] Error 2
from # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1: -5 # build_abe qemu: -2 # linux_n_obj: 20762 # linux build successful: all
THIS IS THE END OF INTERESTING STUFF. BELOW ARE LINKS TO BUILDS, REPRODUCTION INSTRUCTIONS, AND THE RAW COMMIT.
This commit has regressed these CI configurations: - tcwg_kernel/gnu-release-arm-next-allyesconfig
First_bad build: https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... Last_good build: https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... Baseline build: https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... Even more details: https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes...
Reproduce builds: <cut> mkdir investigate-linux-55bc1b4598a319f2bc8d558caf81244c2a15de3b cd investigate-linux-55bc1b4598a319f2bc8d558caf81244c2a15de3b
# Fetch scripts git clone https://git.linaro.org/toolchain/jenkins-scripts
# Fetch manifests and test.sh script mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-release-arm-next-allyes... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_kernel-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh) mkdir -p ./bisect rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /linux/ ./ ./bisect/baseline/
cd linux
# Reproduce first_bad build git checkout --detach 55bc1b4598a319f2bc8d558caf81244c2a15de3b ../artifacts/test.sh
# Reproduce last_good build git checkout --detach bed5d797ab6d6268564a0c5353d2e41b87a28a6e ../artifacts/test.sh
cd .. </cut>
Full commit (up to 1000 lines): <cut> commit 55bc1b4598a319f2bc8d558caf81244c2a15de3b Author: Ioannis Angelakopoulos iangelak@fb.com Date: Tue Jun 14 15:22:32 2022 -0700
btrfs: Add the capability of getting commit stats in BTRFS
First we add "struct btrfs_commit_stats" data structure under "fs_info" in fs/btrfs/ctree.h to store the commit stats for BTRFS that will be exposed through sysfs.
The stats exposed are: 1) The number of commits so far, 2) The duration of the last commit in ms, 3) The maximum commit duration seen so far in ms and 4) The total duration for all commits so far in ms.
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.
Signed-off-by: Ioannis Angelakopoulos iangelak@fb.com Signed-off-by: David Sterba dsterba@suse.com --- fs/btrfs/ctree.h | 14 ++++++++++++++ fs/btrfs/transaction.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 13d74948c542..8f7eb2d344ce 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -660,6 +660,18 @@ enum btrfs_exclusive_operation { 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 */ + u64 max_commit_dur; + /* The last commit duration */ + u64 last_commit_dur; + /* The total commit duration */ + u64 total_commit_dur; +}; + struct btrfs_fs_info { u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; unsigned long flags; @@ -1069,6 +1081,8 @@ struct btrfs_fs_info { spinlock_t zone_active_bgs_lock; struct list_head zone_active_bgs;
+ struct btrfs_commit_stats commit_stats; + #ifdef CONFIG_BTRFS_FS_REF_VERIFY spinlock_t ref_verify_lock; struct rb_root block_tree; diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 06c0a958d114..9cb09aa05275 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -10,6 +10,7 @@ #include <linux/pagemap.h> #include <linux/blkdev.h> #include <linux/uuid.h> +#include <linux/timekeeping.h> #include "misc.h" #include "ctree.h" #include "disk-io.h" @@ -2084,12 +2085,24 @@ static void add_pending_snapshot(struct btrfs_trans_handle *trans) 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_counter += 1; + 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) { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_transaction *prev_trans = NULL; int ret; + ktime_t start_time; + ktime_t interval;
ASSERT(refcount_read(&trans->use_count) == 1);
@@ -2214,6 +2227,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);
ret = btrfs_start_delalloc_flush(fs_info); @@ -2455,6 +2474,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
trace_btrfs_transaction_commit(fs_info);
+ interval = ktime_get_ns() - start_time; + btrfs_scrub_continue(fs_info);
if (current->journal_info == trans) @@ -2462,6 +2483,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
kmem_cache_free(btrfs_trans_handle_cachep, trans);
+ /* + * Protect the commit stats updates from concurrent updates through + * sysfs. + */ + spin_lock(&fs_info->super_lock); + update_commit_stats(fs_info, interval); + spin_unlock(&fs_info->super_lock); + return ret;
unlock_reloc: </cut>