[Devel] [PATCH v2 14/14] fs/fuse kio: implement cs_stats statistics info
Pavel Butsykin
pbutsykin at virtuozzo.com
Fri May 24 18:55:03 MSK 2019
This statistic shows information about all cs's, directed to show how much and
what type of load the chunk servers are loaded on. Made by analogy with
.vstorage.info/cs_stats statistics of user-mod client.
example:
# csid rpc rd_ops wr_ops sync_ops net_lat io_lat avg_in_flight
1025 5=WORK 4909 0 0 (95% <= 20, 99% <= 20) (95% <= 20, 99% <= 20) 128877
Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
fs/fuse/kio/pcs/fuse_stat.c | 96 +++++++++++++++++++++++++++++++++++++++++++++
fs/fuse/kio/pcs/fuse_stat.h | 1 +
fs/fuse/kio/pcs/pcs_cs.c | 2 +
fs/fuse/kio/pcs/pcs_cs.h | 15 +++++++
4 files changed, 114 insertions(+)
diff --git a/fs/fuse/kio/pcs/fuse_stat.c b/fs/fuse/kio/pcs/fuse_stat.c
index f54f29c5bae8..c2bb29404f2e 100644
--- a/fs/fuse/kio/pcs/fuse_stat.c
+++ b/fs/fuse/kio/pcs/fuse_stat.c
@@ -308,6 +308,96 @@ static void latency_percl_print(struct fuse_lat_stat *s, struct seq_file *m)
seq_printf(m, ")%*s", max(icnt, 0), "");
}
+static int do_show_cs_stats(struct pcs_cs *cs, void *ctx)
+{
+ struct seq_file *m = ctx;
+ int rpc_state = cs->rpc ? cs->rpc->state : PCS_RPC_UNCONN;
+ unsigned int in_flight_avg = cs->in_flight_avg;
+ struct fuse_lat_stat iolat, netlat;
+ struct pcs_perf_rate_cnt read_ops_rate, write_ops_rate, sync_ops_rate;
+ unsigned seq;
+
+ do {
+ int cpu;
+ bool inited = false;
+
+ seq = read_seqbegin(&cs->stat.seqlock);
+ for_each_possible_cpu(cpu) {
+ struct fuse_lat_stat *pcpu_iolat, *pcpu_netlat;
+ struct pcs_perf_rate_cnt *pcpu_read_rate,
+ *pcpu_write_rate,
+ *pcpu_sync_rate;
+
+ pcpu_iolat = per_cpu_ptr(cs->stat.iolat, cpu);
+ pcpu_netlat = per_cpu_ptr(cs->stat.netlat, cpu);
+ pcpu_read_rate = per_cpu_ptr(cs->stat.read_ops_rate, cpu);
+ pcpu_write_rate = per_cpu_ptr(cs->stat.write_ops_rate, cpu);
+ pcpu_sync_rate = per_cpu_ptr(cs->stat.sync_ops_rate, cpu);
+
+ if (!inited) {
+ iolat = *pcpu_iolat;
+ netlat = *pcpu_netlat;
+ read_ops_rate = *pcpu_read_rate;
+ write_ops_rate = *pcpu_write_rate;
+ sync_ops_rate = *pcpu_sync_rate;
+ inited = true;
+ continue;
+ }
+ fuse_iolat_sum(&iolat, pcpu_iolat);
+ fuse_iolat_sum(&netlat, pcpu_netlat);
+ pcs_cs_stat_rate_sum(&read_ops_rate, pcpu_read_rate);
+ pcs_cs_stat_rate_sum(&write_ops_rate, pcpu_write_rate);
+ pcs_cs_stat_rate_sum(&sync_ops_rate, pcpu_sync_rate);
+ }
+ } while (read_seqretry(&cs->stat.seqlock, seq));
+
+ seq_printf(m, "%-10llu %d=%-8s %-10llu %-10llu %-11llu",
+ NODE_ARGS(cs->id), rpc_state, pcs_rpc_state_name(rpc_state),
+ read_ops_rate.rate / STAT_TIMER_PERIOD,
+ write_ops_rate.rate / STAT_TIMER_PERIOD,
+ sync_ops_rate.rate / STAT_TIMER_PERIOD);
+ latency_percl_print(&iolat, m);
+ latency_percl_print(&netlat, m);
+ seq_printf(m, "%-10u\n", in_flight_avg);
+ return 0;
+}
+
+static int pcs_fuse_cs_stats_show(struct seq_file *m, void *v)
+{
+ struct inode *inode = m->private;
+ struct pcs_cluster_core *cc;
+ struct pcs_fuse_stat *stat;
+
+ if (!inode)
+ return 0;
+
+ mutex_lock(&fuse_mutex);
+ stat = inode->i_private;
+ if (!stat)
+ goto out;
+
+ seq_printf(m, "# csid rpc rd_ops wr_ops sync_ops net_lat\t\t\tio_lat\t\t\t avg_in_flight\n");
+
+ cc = container_of(stat, struct pcs_cluster_core, stat);
+ pcs_cs_for_each_entry(&cc->css, do_show_cs_stats, m);
+out:
+ mutex_unlock(&fuse_mutex);
+ return 0;
+}
+
+static int pcs_fuse_cs_stats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pcs_fuse_cs_stats_show, inode);
+}
+
+static const struct file_operations pcs_fuse_cs_stats_ops = {
+ .owner = THIS_MODULE,
+ .open = pcs_fuse_cs_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static void fuse_kio_fstat_lat_itr(struct fuse_file *ff,
struct pcs_dentry_info *di, void *ctx)
{
@@ -612,6 +702,7 @@ static void pcs_fuse_stat_work(struct work_struct *w)
fuse_iostat_up(&stat->io);
fuse_stat_files_up(cc);
+ pcs_cs_set_stat_up(&cc->css);
mod_delayed_work(cc->wq, &cc->stat.work, STAT_TIMER_PERIOD * HZ);
}
@@ -749,6 +840,9 @@ void pcs_fuse_stat_init(struct pcs_fuse_stat *stat)
stat->fstat_lat = fuse_kio_add_dentry(stat->kio_stat, fc, "fstat_lat",
S_IFREG | S_IRUSR, 1, NULL,
&pcs_fuse_fstat_lat_ops, stat);
+ stat->cs_stats = fuse_kio_add_dentry(stat->kio_stat, fc, "cs_stats",
+ S_IFREG | S_IRUSR, 1, NULL,
+ &pcs_fuse_cs_stats_ops, stat);
mutex_unlock(&fuse_mutex);
return;
@@ -773,6 +867,8 @@ void pcs_fuse_stat_fini(struct pcs_fuse_stat *stat)
fuse_kio_rm_dentry(stat->fstat);
if (stat->fstat_lat)
fuse_kio_rm_dentry(stat->fstat_lat);
+ if (stat->cs_stats)
+ fuse_kio_rm_dentry(stat->cs_stats);
fuse_kio_rm_dentry(stat->kio_stat);
}
mutex_unlock(&fuse_mutex);
diff --git a/fs/fuse/kio/pcs/fuse_stat.h b/fs/fuse/kio/pcs/fuse_stat.h
index b6d513bed7ea..438836898437 100644
--- a/fs/fuse/kio/pcs/fuse_stat.h
+++ b/fs/fuse/kio/pcs/fuse_stat.h
@@ -36,6 +36,7 @@ struct pcs_fuse_stat {
struct dentry *requests;
struct dentry *fstat;
struct dentry *fstat_lat;
+ struct dentry *cs_stats;
};
enum {
diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c
index 93b121127595..7f90089f16fb 100644
--- a/fs/fuse/kio/pcs/pcs_cs.c
+++ b/fs/fuse/kio/pcs/pcs_cs.c
@@ -1198,7 +1198,9 @@ int pcs_cs_for_each_entry(struct pcs_cs_set *set, int (*cb)(struct pcs_cs *cs, v
spin_lock(&set->lock);
for (i = 0; i < PCS_CS_HASH_SIZE; i++) {
hlist_for_each_entry_safe(cs, node, &set->ht[i], hlist) {
+ rcu_read_lock();
rc = cb(cs, arg);
+ rcu_read_unlock();
if (rc < 0) {
spin_lock(&set->lock);
return rc;
diff --git a/fs/fuse/kio/pcs/pcs_cs.h b/fs/fuse/kio/pcs/pcs_cs.h
index 8bdd056b5196..a5e3abc5703c 100644
--- a/fs/fuse/kio/pcs/pcs_cs.h
+++ b/fs/fuse/kio/pcs/pcs_cs.h
@@ -159,6 +159,21 @@ int pcs_cs_for_each_entry(struct pcs_cs_set *set, int (*cb)(struct pcs_cs *cs, v
void pcs_cs_update_stat(struct pcs_cs *cs, u32 iolat, u32 netlat, int op_type);
+static inline void pcs_cs_stat_rate_sum(struct pcs_perf_rate_cnt *s,
+ struct pcs_perf_rate_cnt *add)
+{
+ if (!add->total)
+ return;
+
+ if (!s->total)
+ *s = *add;
+ else {
+ s->total += add->total;
+ s->last_total += add->last_total;
+ s->rate += add->rate;
+ }
+}
+
static inline void pcs_cs_stat_up(struct pcs_cs *cs)
{
int cpu;
--
2.15.1
More information about the Devel
mailing list