ceph: add metadata perf metric support
[linux-block.git] / fs / ceph / mds_client.c
index 7c63abf5bea91f5bded40475e2460f240f08ca2c..20fab5c72d39a3eb25be7917e865d0747c47a7ca 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
 #include <linux/bits.h>
+#include <linux/ktime.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -2201,6 +2202,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        mutex_init(&req->r_fill_mutex);
        req->r_mdsc = mdsc;
        req->r_started = jiffies;
+       req->r_start_latency = ktime_get();
        req->r_resend_mds = -1;
        INIT_LIST_HEAD(&req->r_unsafe_dir_item);
        INIT_LIST_HEAD(&req->r_unsafe_target_item);
@@ -2547,6 +2549,8 @@ out:
 static void complete_request(struct ceph_mds_client *mdsc,
                             struct ceph_mds_request *req)
 {
+       req->r_end_latency = ktime_get();
+
        if (req->r_callback)
                req->r_callback(mdsc, req);
        complete_all(&req->r_completion);
@@ -3155,6 +3159,9 @@ out_err:
 
        /* kick calling process */
        complete_request(mdsc, req);
+
+       ceph_update_metadata_latency(&mdsc->metric, req->r_start_latency,
+                                    req->r_end_latency, err);
 out:
        ceph_mdsc_put_request(req);
        return;
@@ -4323,6 +4330,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
 
 {
        struct ceph_mds_client *mdsc;
+       int err;
 
        mdsc = kzalloc(sizeof(struct ceph_mds_client), GFP_NOFS);
        if (!mdsc)
@@ -4331,8 +4339,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        mutex_init(&mdsc->mutex);
        mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
        if (!mdsc->mdsmap) {
-               kfree(mdsc);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_mdsc;
        }
 
        fsc->mdsc = mdsc;
@@ -4371,6 +4379,9 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        init_waitqueue_head(&mdsc->cap_flushing_wq);
        INIT_WORK(&mdsc->cap_reclaim_work, ceph_cap_reclaim_work);
        atomic_set(&mdsc->cap_reclaim_pending, 0);
+       err = ceph_metric_init(&mdsc->metric);
+       if (err)
+               goto err_mdsmap;
 
        spin_lock_init(&mdsc->dentry_list_lock);
        INIT_LIST_HEAD(&mdsc->dentry_leases);
@@ -4389,6 +4400,12 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        strscpy(mdsc->nodename, utsname()->nodename,
                sizeof(mdsc->nodename));
        return 0;
+
+err_mdsmap:
+       kfree(mdsc->mdsmap);
+err_mdsc:
+       kfree(mdsc);
+       return err;
 }
 
 /*
@@ -4646,6 +4663,8 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
 
        ceph_mdsc_stop(mdsc);
 
+       ceph_metric_destroy(&mdsc->metric);
+
        fsc->mdsc = NULL;
        kfree(mdsc);
        dout("mdsc_destroy %p done\n", mdsc);