linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/2] btrfs: Expose commit stats through sysfs
@ 2022-06-21 22:59 Ioannis Angelakopoulos
  2022-06-21 22:59 ` [PATCH v4 1/2] btrfs: Add the capability of getting commit stats Ioannis Angelakopoulos
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Ioannis Angelakopoulos @ 2022-06-21 22:59 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

With this patch series we add the capability to btrfs to expose some
commit stats through sysfs that might be useful for performance monitoring
and debugging purposes.

Specifically, through sysfs we expose the following data:
  1) A counter for the commits that occurred so far.
  2) The duration in ms of the last commit.
  3) The maximum commit duration in ms seen so far.
  4) The total duration in ms of the commits seen so far.

The user also has the capability to reset the maximum commit duration
back to zero, again through sysfs.

Changes from v3:

1) Fixed a mistake when using div_u64 that would break the kernel build

Changes from v2:

1) Only the maximum duration can now be zeroed out through sysfs to
prevent loss of data if multiple threads try to reset the commit stats
simultaneously
2) Removed the lock that protected the concurrent resetting and updating
of the commit stats, since only the maximum commit duration can be
cleared out now (any races can be ignored for this stat).
3) Added div_u64 when converting from ns to ms, to also support 32-bit
4) Made the output from sysfs easier to use with "grep"

Changes from v1:

1) Edited out unnecessary comments
2) Made the memory allocation of "btrfs_commit_stats" under "fs_info" in
fs/btrfs/ctree.h static instead of dynamic
3) Transferred the conversion from ns to ms at the point where commit
stats get printed in sysfs, for better precision
4) Changed the lock that protects the update of the commit stats from
"trans_lock" to "super_lock"
5) Changed the printing of the commits stats in sysfs to conform with
the sysfs output

Ioannis Angelakopoulos (2):
  btrfs: Add the capability of getting commit stats
  btrfs: Expose the commit stats through sysfs

 fs/btrfs/ctree.h       | 14 +++++++++++++
 fs/btrfs/sysfs.c       | 45 ++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/transaction.c | 22 +++++++++++++++++++++
 3 files changed, 81 insertions(+)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 1/2] btrfs: Add the capability of getting commit stats
  2022-06-21 22:59 [PATCH v4 0/2] btrfs: Expose commit stats through sysfs Ioannis Angelakopoulos
@ 2022-06-21 22:59 ` Ioannis Angelakopoulos
  2022-06-21 22:59 ` [PATCH v4 2/2] btrfs: Expose the commit stats through sysfs Ioannis Angelakopoulos
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Ioannis Angelakopoulos @ 2022-06-21 22:59 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

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>
---
 fs/btrfs/ctree.h       | 14 ++++++++++++++
 fs/btrfs/transaction.c | 22 ++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1347c92234a5..2bd4a53c0046 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -667,6 +667,18 @@ enum btrfs_exclusive_operation {
 	BTRFS_EXCLOP_SWAP_ACTIVATE,
 };
 
+/* Storing data about btrfs commits. The data are accessible over sysfs */
+struct btrfs_commit_stats {
+	/* Total number of commits */
+	u64 commit_counter;
+	/* 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;
@@ -1076,6 +1088,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..5b9451b3b005 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,23 @@ 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++;
+	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 +2226,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 +2473,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 +2482,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
 
 	kmem_cache_free(btrfs_trans_handle_cachep, trans);
 
+	update_commit_stats(fs_info, interval);
+
 	return ret;
 
 unlock_reloc:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 2/2] btrfs: Expose the commit stats through sysfs
  2022-06-21 22:59 [PATCH v4 0/2] btrfs: Expose commit stats through sysfs Ioannis Angelakopoulos
  2022-06-21 22:59 ` [PATCH v4 1/2] btrfs: Add the capability of getting commit stats Ioannis Angelakopoulos
@ 2022-06-21 22:59 ` Ioannis Angelakopoulos
  2022-06-22 13:56 ` [PATCH v4 0/2] btrfs: Expose " Nikolay Borisov
  2022-06-22 16:25 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: Ioannis Angelakopoulos @ 2022-06-21 22:59 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

Create a new sysfs entry named "commit_stats" under /sys/fs/btrfs/<UUID>/
for each mounted btrfs filesystem. The entry exposes: 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 function "btrfs_commit_stats_show" in fs/btrfs/sysfs.c is responsible
for exposing the stats to user space.

The function "btrfs_commit_stats_store" in fs/btrfs/sysfs.c is responsible
for resetting the maximum commit duration to zero. This benefits
applications that want to sample the maximum commit duration over a long
time period. Only the maximum commit duration is reset to zero in order to
avoid loss of data if multiple threads are trying to reset the commit stats
data at the same time.

Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
---
 fs/btrfs/sysfs.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index db3736de14a5..c17e29f2f004 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -10,6 +10,7 @@
 #include <linux/completion.h>
 #include <linux/bug.h>
 #include <crypto/hash.h>
+#include <linux/math64.h>
 
 #include "ctree.h"
 #include "discard.h"
@@ -991,6 +992,49 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
 
 BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show);
 
+static ssize_t btrfs_commit_stats_show(struct kobject *kobj,
+				struct kobj_attribute *a, char *buf)
+{
+	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
+
+	return sysfs_emit(buf,
+		"commits %llu\n"
+		"last_commit_dur_ms %llu\n"
+		"max_commit_dur_ms %llu\n"
+		"total_commit_dur_ms %llu\n",
+		fs_info->commit_stats.commit_counter,
+		div_u64(fs_info->commit_stats.last_commit_dur, NSEC_PER_MSEC),
+		div_u64(fs_info->commit_stats.max_commit_dur, NSEC_PER_MSEC),
+		div_u64(fs_info->commit_stats.total_commit_dur, NSEC_PER_MSEC));
+}
+
+static ssize_t btrfs_commit_stats_store(struct kobject *kobj,
+						struct kobj_attribute *a,
+						const char *buf, size_t len)
+{
+	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
+	unsigned long val;
+	int ret;
+
+	if (!fs_info)
+		return -EPERM;
+
+	if (!capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+	if (val)
+		return -EINVAL;
+
+	fs_info->commit_stats.max_commit_dur = 0;
+
+	return len;
+}
+BTRFS_ATTR_RW(, commit_stats, btrfs_commit_stats_show,
+			  btrfs_commit_stats_store);
+
 static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
 				struct kobj_attribute *a, char *buf)
 {
@@ -1230,6 +1274,7 @@ static const struct attribute *btrfs_attrs[] = {
 	BTRFS_ATTR_PTR(, generation),
 	BTRFS_ATTR_PTR(, read_policy),
 	BTRFS_ATTR_PTR(, bg_reclaim_threshold),
+	BTRFS_ATTR_PTR(, commit_stats),
 	NULL,
 };
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 0/2] btrfs: Expose commit stats through sysfs
  2022-06-21 22:59 [PATCH v4 0/2] btrfs: Expose commit stats through sysfs Ioannis Angelakopoulos
  2022-06-21 22:59 ` [PATCH v4 1/2] btrfs: Add the capability of getting commit stats Ioannis Angelakopoulos
  2022-06-21 22:59 ` [PATCH v4 2/2] btrfs: Expose the commit stats through sysfs Ioannis Angelakopoulos
@ 2022-06-22 13:56 ` Nikolay Borisov
  2022-06-22 16:25 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: Nikolay Borisov @ 2022-06-22 13:56 UTC (permalink / raw)
  To: Ioannis Angelakopoulos, linux-btrfs, kernel-team



On 22.06.22 г. 1:59 ч., Ioannis Angelakopoulos wrote:
> With this patch series we add the capability to btrfs to expose some
> commit stats through sysfs that might be useful for performance monitoring
> and debugging purposes.
> 
> Specifically, through sysfs we expose the following data:
>    1) A counter for the commits that occurred so far.
>    2) The duration in ms of the last commit.
>    3) The maximum commit duration in ms seen so far.
>    4) The total duration in ms of the commits seen so far.
> 
> The user also has the capability to reset the maximum commit duration
> back to zero, again through sysfs.
> 
> Changes from v3:
> 
> 1) Fixed a mistake when using div_u64 that would break the kernel build
> 
> Changes from v2:
> 
> 1) Only the maximum duration can now be zeroed out through sysfs to
> prevent loss of data if multiple threads try to reset the commit stats
> simultaneously
> 2) Removed the lock that protected the concurrent resetting and updating
> of the commit stats, since only the maximum commit duration can be
> cleared out now (any races can be ignored for this stat).
> 3) Added div_u64 when converting from ns to ms, to also support 32-bit
> 4) Made the output from sysfs easier to use with "grep"
> 
> Changes from v1:
> 
> 1) Edited out unnecessary comments
> 2) Made the memory allocation of "btrfs_commit_stats" under "fs_info" in
> fs/btrfs/ctree.h static instead of dynamic
> 3) Transferred the conversion from ns to ms at the point where commit
> stats get printed in sysfs, for better precision
> 4) Changed the lock that protects the update of the commit stats from
> "trans_lock" to "super_lock"
> 5) Changed the printing of the commits stats in sysfs to conform with
> the sysfs output
> 
> Ioannis Angelakopoulos (2):
>    btrfs: Add the capability of getting commit stats
>    btrfs: Expose the commit stats through sysfs
> 
>   fs/btrfs/ctree.h       | 14 +++++++++++++
>   fs/btrfs/sysfs.c       | 45 ++++++++++++++++++++++++++++++++++++++++++
>   fs/btrfs/transaction.c | 22 +++++++++++++++++++++
>   3 files changed, 81 insertions(+)
> 


Reviewed-by: Nikolay Borisov <nborisov@suse.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 0/2] btrfs: Expose commit stats through sysfs
  2022-06-21 22:59 [PATCH v4 0/2] btrfs: Expose commit stats through sysfs Ioannis Angelakopoulos
                   ` (2 preceding siblings ...)
  2022-06-22 13:56 ` [PATCH v4 0/2] btrfs: Expose " Nikolay Borisov
@ 2022-06-22 16:25 ` David Sterba
  3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2022-06-22 16:25 UTC (permalink / raw)
  To: Ioannis Angelakopoulos; +Cc: linux-btrfs, kernel-team

On Tue, Jun 21, 2022 at 03:59:17PM -0700, Ioannis Angelakopoulos wrote:
> With this patch series we add the capability to btrfs to expose some
> commit stats through sysfs that might be useful for performance monitoring
> and debugging purposes.
> 
> Specifically, through sysfs we expose the following data:
>   1) A counter for the commits that occurred so far.
>   2) The duration in ms of the last commit.
>   3) The maximum commit duration in ms seen so far.
>   4) The total duration in ms of the commits seen so far.
> 
> The user also has the capability to reset the maximum commit duration
> back to zero, again through sysfs.
> 
> Changes from v3:
> 
> 1) Fixed a mistake when using div_u64 that would break the kernel build
> 
> Changes from v2:
> 
> 1) Only the maximum duration can now be zeroed out through sysfs to
> prevent loss of data if multiple threads try to reset the commit stats
> simultaneously
> 2) Removed the lock that protected the concurrent resetting and updating
> of the commit stats, since only the maximum commit duration can be
> cleared out now (any races can be ignored for this stat).
> 3) Added div_u64 when converting from ns to ms, to also support 32-bit
> 4) Made the output from sysfs easier to use with "grep"
> 
> Changes from v1:
> 
> 1) Edited out unnecessary comments
> 2) Made the memory allocation of "btrfs_commit_stats" under "fs_info" in
> fs/btrfs/ctree.h static instead of dynamic
> 3) Transferred the conversion from ns to ms at the point where commit
> stats get printed in sysfs, for better precision
> 4) Changed the lock that protects the update of the commit stats from
> "trans_lock" to "super_lock"
> 5) Changed the printing of the commits stats in sysfs to conform with
> the sysfs output
> 
> Ioannis Angelakopoulos (2):
>   btrfs: Add the capability of getting commit stats
>   btrfs: Expose the commit stats through sysfs

Added to misc-next, with some minor fixups, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-06-22 16:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-21 22:59 [PATCH v4 0/2] btrfs: Expose commit stats through sysfs Ioannis Angelakopoulos
2022-06-21 22:59 ` [PATCH v4 1/2] btrfs: Add the capability of getting commit stats Ioannis Angelakopoulos
2022-06-21 22:59 ` [PATCH v4 2/2] btrfs: Expose the commit stats through sysfs Ioannis Angelakopoulos
2022-06-22 13:56 ` [PATCH v4 0/2] btrfs: Expose " Nikolay Borisov
2022-06-22 16:25 ` David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).