From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Dave Chinner <david@fromorbit.com>,
Al Viro <viro@zeniv.linux.org.uk>,
linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH v3 2/6] fs: add optional iostats counters to struct super_block
Date: Tue, 1 Mar 2022 20:42:17 +0200 [thread overview]
Message-ID: <20220301184221.371853-3-amir73il@gmail.com> (raw)
In-Reply-To: <20220301184221.371853-1-amir73il@gmail.com>
With CONFIG_FS_IOSTATS, filesystem can attach an array of counters to
struct super_block by calling sb_iostats_init().
These counters will be used to collect per-sb I/O statistics and display
them in /proc/<pid>/mountstats.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/Kconfig | 8 +++
fs/super.c | 2 +
include/linux/fs.h | 10 ++-
include/linux/fs_iostats.h | 127 +++++++++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+), 2 deletions(-)
create mode 100644 include/linux/fs_iostats.h
diff --git a/fs/Kconfig b/fs/Kconfig
index 6c7dc1387beb..394d9da6bda9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -15,6 +15,14 @@ config VALIDATE_FS_PARSER
Enable this to perform validation of the parameter description for a
filesystem when it is registered.
+config FS_IOSTATS
+ bool "Enable generic filesystem I/O statistics"
+ help
+ Enable this to allow collecting filesystem I/O statistics and display
+ them in /proc/<pid>/mountstats.
+
+ Say N if unsure.
+
config FS_IOMAP
bool
diff --git a/fs/super.c b/fs/super.c
index f1d4a193602d..c447cadb402b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -36,6 +36,7 @@
#include <linux/lockdep.h>
#include <linux/user_namespace.h>
#include <linux/fs_context.h>
+#include <linux/fs_iostats.h>
#include <uapi/linux/mount.h>
#include "internal.h"
@@ -290,6 +291,7 @@ static void __put_super(struct super_block *s)
WARN_ON(s->s_dentry_lru.node);
WARN_ON(s->s_inode_lru.node);
WARN_ON(!list_empty(&s->s_mounts));
+ sb_iostats_destroy(s);
security_sb_free(s);
fscrypt_sb_free(s);
put_user_ns(s->s_user_ns);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e2d892b201b0..a71c94cbb6c1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1454,6 +1454,8 @@ struct sb_writers {
struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
};
+struct sb_iostats;
+
struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t */
@@ -1508,8 +1510,12 @@ struct super_block {
/* Granularity of c/m/atime in ns (cannot be worse than a second) */
u32 s_time_gran;
/* Time limits for c/m/atime in seconds */
- time64_t s_time_min;
- time64_t s_time_max;
+ time64_t s_time_min;
+ time64_t s_time_max;
+#ifdef CONFIG_FS_IOSTATS
+ /* Optional per-sb I/O stats */
+ struct sb_iostats *s_iostats;
+#endif
#ifdef CONFIG_FSNOTIFY
__u32 s_fsnotify_mask;
struct fsnotify_mark_connector __rcu *s_fsnotify_marks;
diff --git a/include/linux/fs_iostats.h b/include/linux/fs_iostats.h
new file mode 100644
index 000000000000..60d1efbea7d9
--- /dev/null
+++ b/include/linux/fs_iostats.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_FS_IOSTATS_H
+#define _LINUX_FS_IOSTATS_H
+
+#include <linux/fs.h>
+#include <linux/percpu_counter.h>
+#include <linux/slab.h>
+
+/* Similar to task_io_accounting members */
+enum {
+ SB_IOSTATS_CHARS_RD, /* bytes read via syscalls */
+ SB_IOSTATS_CHARS_WR, /* bytes written via syscalls */
+ SB_IOSTATS_SYSCALLS_RD, /* # of read syscalls */
+ SB_IOSTATS_SYSCALLS_WR, /* # of write syscalls */
+ SB_IOSTATS_COUNTERS_NUM
+};
+
+struct sb_iostats {
+ time64_t start_time;
+ struct percpu_counter counter[SB_IOSTATS_COUNTERS_NUM];
+};
+
+#ifdef CONFIG_FS_IOSTATS
+static inline struct sb_iostats *sb_iostats(struct super_block *sb)
+{
+ return sb->s_iostats;
+}
+
+static inline bool sb_has_iostats(struct super_block *sb)
+{
+ return !!sb->s_iostats;
+}
+
+static inline void sb_iostats_destroy(struct super_block *sb)
+{
+ if (!sb->s_iostats)
+ return;
+
+ percpu_counters_destroy(sb->s_iostats->counter,
+ SB_IOSTATS_COUNTERS_NUM);
+ kfree(sb->s_iostats);
+ sb->s_iostats = NULL;
+}
+
+/* Initialize per-sb I/O stats */
+static inline int sb_iostats_init(struct super_block *sb)
+{
+ int err;
+
+ sb->s_iostats = kmalloc(sizeof(struct sb_iostats), GFP_KERNEL);
+ if (!sb->s_iostats)
+ return -ENOMEM;
+
+ err = percpu_counters_init(sb->s_iostats->counter,
+ SB_IOSTATS_COUNTERS_NUM, 0, GFP_KERNEL);
+ if (err) {
+ kfree(sb->s_iostats);
+ sb->s_iostats = NULL;
+ return err;
+ }
+
+ sb->s_iostats->start_time = ktime_get_seconds();
+ return 0;
+}
+
+static inline void sb_iostats_counter_inc(struct super_block *sb, int id)
+{
+ if (!sb->s_iostats)
+ return;
+
+ percpu_counter_inc(&sb->s_iostats->counter[id]);
+}
+
+static inline void sb_iostats_counter_add(struct super_block *sb, int id,
+ s64 amt)
+{
+ if (!sb->s_iostats)
+ return;
+
+ percpu_counter_add(&sb->s_iostats->counter[id], amt);
+}
+
+static inline s64 sb_iostats_counter_read(struct super_block *sb, int id)
+{
+ if (!sb->s_iostats)
+ return 0;
+
+ return percpu_counter_read_positive(&sb->s_iostats->counter[id]);
+}
+
+#else /* !CONFIG_FS_IOSTATS */
+
+static inline struct sb_iostats *sb_iostats(struct super_block *sb)
+{
+ return NULL;
+}
+
+static inline bool sb_has_iostats(struct super_block *sb)
+{
+ return false;
+}
+
+static inline int sb_iostats_init(struct super_block *sb)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void sb_iostats_destroy(struct super_block *sb)
+{
+}
+
+static inline void sb_iostats_counter_inc(struct super_block *sb, int id)
+{
+}
+
+static inline void sb_iostats_counter_add(struct super_block *sb, int id,
+ s64 amt)
+{
+}
+
+static inline s64 sb_iostats_counter_read(struct super_block *sb, int id)
+{
+ return 0;
+}
+#endif
+
+#endif /* _LINUX_FS_IOSTATS_H */
--
2.25.1
next prev parent reply other threads:[~2022-03-01 18:42 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-01 18:42 [PATCH v3 0/6] Generic per-sb io stats Amir Goldstein
2022-03-01 18:42 ` [PATCH v3 1/6] lib/percpu_counter: add helpers for arrays of counters Amir Goldstein
2022-03-01 18:42 ` Amir Goldstein [this message]
2022-03-01 18:42 ` [PATCH v3 3/6] fs: collect per-sb io stats Amir Goldstein
2022-03-01 18:42 ` [PATCH v3 4/6] fs: report " Amir Goldstein
2022-03-01 18:42 ` [PATCH v3 5/6] ovl: opt-in for " Amir Goldstein
2022-03-01 18:42 ` [PATCH v3 6/6] fuse: " Amir Goldstein
2022-03-02 6:59 ` [PATCH v3 0/6] Generic " Dave Chinner
2022-03-02 7:43 ` Amir Goldstein
2022-03-02 8:26 ` Dave Chinner
2022-03-02 8:34 ` Amir Goldstein
2022-03-02 16:59 ` Amir Goldstein
2022-03-02 21:12 ` Dave Chinner
2022-03-02 22:04 ` nfs generic/373 failure after "fs: allow cross-vfsmount reflink/dedupe" J. Bruce Fields
2022-03-02 22:26 ` Josef Bacik
2022-03-02 22:42 ` J. Bruce Fields
2022-03-02 23:45 ` Josef Bacik
2022-03-03 0:07 ` J. Bruce Fields
2022-03-03 0:29 ` Josef Bacik
2022-03-03 0:50 ` J. Bruce Fields
2022-03-04 20:03 ` J. Bruce Fields
2022-03-03 6:50 ` [PATCH v3 0/6] Generic per-sb io stats Amir Goldstein
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220301184221.371853-3-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=david@fromorbit.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.