[Devel] [PATCH 12/15] fs/fuse kio: implement cs statistics accounting
Pavel Butsykin
pbutsykin at virtuozzo.com
Fri May 17 16:20:45 MSK 2019
This is preparation patch that adds the implementation of calculating statistics
for cs objects. Backport from user-mod vstorage client.
Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
fs/fuse/kio/pcs/pcs_cs.c | 3 ++
fs/fuse/kio/pcs/pcs_cs.h | 6 ++--
fs/fuse/kio/pcs/pcs_perfcounters.h | 64 +++++++++++++++++++++++++++++++--
fs/fuse/kio/pcs/pcs_perfcounters_stub.h | 30 ----------------
4 files changed, 68 insertions(+), 35 deletions(-)
delete mode 100644 fs/fuse/kio/pcs/pcs_perfcounters_stub.h
diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c
index 28dfc10246de..b41284fe9205 100644
--- a/fs/fuse/kio/pcs/pcs_cs.c
+++ b/fs/fuse/kio/pcs/pcs_cs.c
@@ -77,6 +77,7 @@ struct pcs_cs *pcs_cs_alloc(struct pcs_cs_set *css,
}
cs->rpc->private = cs;
INIT_LIST_HEAD(&cs->map_list);
+ spin_lock_init(&cs->stat.lock);
return cs;
}
@@ -296,6 +297,7 @@ void cs_log_io_times(struct pcs_int_request * ireq, struct pcs_msg * resp, unsig
void pcs_cs_update_stat(struct pcs_cs *cs, u32 iolat, u32 netlat, int op_type)
{
+ spin_lock(&cs->stat.lock);
pcs_perfcounter_stat_update(&cs->stat.iolat, iolat);
pcs_perfcounter_stat_update(&cs->stat.netlat, netlat);
switch (op_type) {
@@ -310,6 +312,7 @@ void pcs_cs_update_stat(struct pcs_cs *cs, u32 iolat, u32 netlat, int op_type)
cs->stat.sync_ops_rate.total++;
break;
}
+ spin_unlock(&cs->stat.lock);
}
static void cs_response_done(struct pcs_msg *msg)
diff --git a/fs/fuse/kio/pcs/pcs_cs.h b/fs/fuse/kio/pcs/pcs_cs.h
index 1fb40936d046..f20b4f584861 100644
--- a/fs/fuse/kio/pcs/pcs_cs.h
+++ b/fs/fuse/kio/pcs/pcs_cs.h
@@ -95,6 +95,7 @@ struct pcs_cs {
struct pcs_perf_rate_cnt read_ops_rate;
struct pcs_perf_rate_cnt write_ops_rate;
struct pcs_perf_rate_cnt sync_ops_rate;
+ spinlock_t lock;
} stat;
};
@@ -160,14 +161,13 @@ void pcs_cs_update_stat(struct pcs_cs *cs, u32 iolat, u32 netlat, int op_type);
static inline void pcs_cs_stat_up(struct pcs_cs *cs)
{
-#if 0
- /* TODO: temproraly disable perf counters */
+ spin_lock(&cs->stat.lock);
pcs_perfcounter_stat_up(&cs->stat.iolat);
pcs_perfcounter_stat_up(&cs->stat.netlat);
pcs_perfcounter_up_rate(&cs->stat.write_ops_rate);
pcs_perfcounter_up_rate(&cs->stat.read_ops_rate);
pcs_perfcounter_up_rate(&cs->stat.sync_ops_rate);
-#endif
+ spin_unlock(&cs->stat.lock);
}
static inline bool cs_is_blacklisted(struct pcs_cs *cs)
diff --git a/fs/fuse/kio/pcs/pcs_perfcounters.h b/fs/fuse/kio/pcs/pcs_perfcounters.h
index f902ce06d72d..0320981d0e7e 100644
--- a/fs/fuse/kio/pcs/pcs_perfcounters.h
+++ b/fs/fuse/kio/pcs/pcs_perfcounters.h
@@ -1,7 +1,67 @@
#ifndef _PCS_PERFCOUNTERS_H_
#define _PCS_PERFCOUNTERS_H_ 1
-/* TODO:!!! this is stump for flow_detection */
-#include "pcs_perfcounters_stub.h"
+/* Average calculation */
+#define AV_SHIFT 11
+#define AV_EXP_1 1884 /* 1 min average */
+#define AV_EXP_5 2014 /* 5 min average */
+#define AV_EXP_15 2037 /* 15 min average */
+
+/* The following macro update accumulated average value av producing the average left-shifted by AV_SHIFT bits */
+#define AV_UPDATE(av, val, exp) (((av)*(exp)>>AV_SHIFT) + (val)*((1<<AV_SHIFT)-(exp)))
+
+struct pcs_perf_stat_cnt {
+ u64 val_total;
+ u64 events;
+ u64 curr_max;
+ u64 events_last;
+ u64 avg;
+ u64 maximum;
+};
+
+/* Generic event rate counter */
+struct pcs_perf_rate_cnt {
+ /* Total number of events */
+ u64 total;
+ u64 last_total;
+ /* The number of events for the last 5 sec interval */
+ u64 rate;
+ /* The number of events per 5 sec averaged over 1, 5, 15 min and shifted by AV_SHIFT to the left */
+ u64 av1;
+ u64 av5;
+ u64 av15;
+};
+
+static inline void pcs_perfcounter_stat_update(struct pcs_perf_stat_cnt *cnt, u64 val)
+{
+ if (cnt->curr_max < val)
+ cnt->curr_max = val;
+
+ cnt->val_total += val;
+ cnt->events++;
+}
+
+static inline void pcs_perfcounter_stat_up(struct pcs_perf_stat_cnt *cnt)
+{
+ cnt->avg = (cnt->events) ? cnt->val_total / cnt->events : 0;
+ cnt->maximum = cnt->curr_max;
+ cnt->events_last = cnt->events;
+ cnt->val_total = cnt->events = cnt->curr_max = 0;
+}
+
+static inline void pcs_perfcounter_up_rate(struct pcs_perf_rate_cnt* cnt)
+{
+ BUG_ON(cnt->total < cnt->last_total);
+ cnt->rate = cnt->total - cnt->last_total;
+ cnt->last_total = cnt->total;
+ cnt->av1 = AV_UPDATE(cnt->av1, cnt->rate, AV_EXP_1);
+ cnt->av5 = AV_UPDATE(cnt->av5, cnt->rate, AV_EXP_5);
+ cnt->av15 = AV_UPDATE(cnt->av15, cnt->rate, AV_EXP_15);
+}
+
+static inline u64 pcs_perfcounter_stat_max(struct pcs_perf_stat_cnt *cnt)
+{
+ return max(cnt->maximum, cnt->curr_max);
+}
#endif /* _PCS_PERFCOUNTERS_H_ */
diff --git a/fs/fuse/kio/pcs/pcs_perfcounters_stub.h b/fs/fuse/kio/pcs/pcs_perfcounters_stub.h
deleted file mode 100644
index 17dae73fcd08..000000000000
--- a/fs/fuse/kio/pcs/pcs_perfcounters_stub.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _PCS_PERFCOUNTERS_STUB_H_
-#define _PCS_PERFCOUNTERS_STUB_H_ 1
-
-
-struct pcs_perf_stat_cnt {
- u64 val_total;
- u64 events;
- u64 curr_max;
- u64 events_last;
- u64 avg;
- u64 maximum;
-};
-
-/* Generic event rate counter */
-struct pcs_perf_rate_cnt {
- /* Total number of events */
- u64 total;
- u64 last_total;
- /* The number of events for the last 5 sec interval */
- u64 rate;
- /* The number of events per 5 sec averaged over 1, 5, 15 min and shifted by AV_SHIFT to the left */
- u64 av1;
- u64 av5;
-};
-
-
-static inline void pcs_perfcounter_stat_update(struct pcs_perf_stat_cnt *cnt, u64 val) __attribute__((unused));
-
-static inline void pcs_perfcounter_stat_update(struct pcs_perf_stat_cnt *cnt, u64 val) {}
-#endif //_PCS_PERFCOUNTERS_STUB_H_
--
2.15.1
More information about the Devel
mailing list