ceph: add metadata perf metric support
[linux-block.git] / fs / ceph / debugfs.c
index dcaed75de9e6a095fb72b53c04c9567feb3c9545..070ed8481340647da1e79d716a719cf2072d6a18 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/math64.h>
+#include <linux/ktime.h>
 
 #include <linux/ceph/libceph.h>
 #include <linux/ceph/mon_client.h>
@@ -18,6 +20,7 @@
 #ifdef CONFIG_DEBUG_FS
 
 #include "mds_client.h"
+#include "metric.h"
 
 static int mdsmap_show(struct seq_file *s, void *p)
 {
@@ -124,6 +127,87 @@ static int mdsc_show(struct seq_file *s, void *p)
        return 0;
 }
 
+#define CEPH_METRIC_SHOW(name, total, avg, min, max, sq) {             \
+       s64 _total, _avg, _min, _max, _sq, _st;                         \
+       _avg = ktime_to_us(avg);                                        \
+       _min = ktime_to_us(min == KTIME_MAX ? 0 : min);                 \
+       _max = ktime_to_us(max);                                        \
+       _total = total - 1;                                             \
+       _sq = _total > 0 ? DIV64_U64_ROUND_CLOSEST(sq, _total) : 0;     \
+       _st = int_sqrt64(_sq);                                          \
+       _st = ktime_to_us(_st);                                         \
+       seq_printf(s, "%-14s%-12lld%-16lld%-16lld%-16lld%lld\n",        \
+                  name, total, _avg, _min, _max, _st);                 \
+}
+
+static int metric_show(struct seq_file *s, void *p)
+{
+       struct ceph_fs_client *fsc = s->private;
+       struct ceph_mds_client *mdsc = fsc->mdsc;
+       struct ceph_client_metric *m = &mdsc->metric;
+       int i, nr_caps = 0;
+       s64 total, sum, avg, min, max, sq;
+
+       seq_printf(s, "item          total       avg_lat(us)     min_lat(us)     max_lat(us)     stdev(us)\n");
+       seq_printf(s, "-----------------------------------------------------------------------------------\n");
+
+       spin_lock(&m->read_latency_lock);
+       total = m->total_reads;
+       sum = m->read_latency_sum;
+       avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0;
+       min = m->read_latency_min;
+       max = m->read_latency_max;
+       sq = m->read_latency_sq_sum;
+       spin_unlock(&m->read_latency_lock);
+       CEPH_METRIC_SHOW("read", total, avg, min, max, sq);
+
+       spin_lock(&m->write_latency_lock);
+       total = m->total_writes;
+       sum = m->write_latency_sum;
+       avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0;
+       min = m->write_latency_min;
+       max = m->write_latency_max;
+       sq = m->write_latency_sq_sum;
+       spin_unlock(&m->write_latency_lock);
+       CEPH_METRIC_SHOW("write", total, avg, min, max, sq);
+
+       spin_lock(&m->metadata_latency_lock);
+       total = m->total_metadatas;
+       sum = m->metadata_latency_sum;
+       avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0;
+       min = m->metadata_latency_min;
+       max = m->metadata_latency_max;
+       sq = m->metadata_latency_sq_sum;
+       spin_unlock(&m->metadata_latency_lock);
+       CEPH_METRIC_SHOW("metadata", total, avg, min, max, sq);
+
+       seq_printf(s, "\n");
+       seq_printf(s, "item          total           miss            hit\n");
+       seq_printf(s, "-------------------------------------------------\n");
+
+       seq_printf(s, "%-14s%-16lld%-16lld%lld\n", "d_lease",
+                  atomic64_read(&m->total_dentries),
+                  percpu_counter_sum(&m->d_lease_mis),
+                  percpu_counter_sum(&m->d_lease_hit));
+
+       mutex_lock(&mdsc->mutex);
+       for (i = 0; i < mdsc->max_sessions; i++) {
+               struct ceph_mds_session *s;
+
+               s = __ceph_lookup_mds_session(mdsc, i);
+               if (!s)
+                       continue;
+               nr_caps += s->s_nr_caps;
+               ceph_put_mds_session(s);
+       }
+       mutex_unlock(&mdsc->mutex);
+       seq_printf(s, "%-14s%-16d%-16lld%lld\n", "caps", nr_caps,
+                  percpu_counter_sum(&m->i_caps_mis),
+                  percpu_counter_sum(&m->i_caps_hit));
+
+       return 0;
+}
+
 static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
 {
        struct seq_file *s = p;
@@ -222,6 +306,7 @@ DEFINE_SHOW_ATTRIBUTE(mdsmap);
 DEFINE_SHOW_ATTRIBUTE(mdsc);
 DEFINE_SHOW_ATTRIBUTE(caps);
 DEFINE_SHOW_ATTRIBUTE(mds_sessions);
+DEFINE_SHOW_ATTRIBUTE(metric);
 
 
 /*
@@ -255,6 +340,7 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
        debugfs_remove(fsc->debugfs_mdsmap);
        debugfs_remove(fsc->debugfs_mds_sessions);
        debugfs_remove(fsc->debugfs_caps);
+       debugfs_remove(fsc->debugfs_metric);
        debugfs_remove(fsc->debugfs_mdsc);
 }
 
@@ -295,11 +381,17 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
                                                fsc,
                                                &mdsc_fops);
 
+       fsc->debugfs_metric = debugfs_create_file("metrics",
+                                                 0400,
+                                                 fsc->client->debugfs_dir,
+                                                 fsc,
+                                                 &metric_fops);
+
        fsc->debugfs_caps = debugfs_create_file("caps",
-                                                  0400,
-                                                  fsc->client->debugfs_dir,
-                                                  fsc,
-                                                  &caps_fops);
+                                               0400,
+                                               fsc->client->debugfs_dir,
+                                               fsc,
+                                               &caps_fops);
 }