@@ -189,6 +189,15 @@ static int metric_show(struct seq_file *s, void *p)
sq = percpu_counter_sum(&m->write_latency_sq_sum);
CEPH_METRIC_SHOW("write", total, avg, min, max, sq);
+ avg = get_avg(&m->total_metadatas,
+ &m->metadata_latency_sum,
+ &m->metadata_latency_lock,
+ &total);
+ min = atomic64_read(&m->metadata_latency_min);
+ max = atomic64_read(&m->metadata_latency_max);
+ sq = percpu_counter_sum(&m->metadata_latency_sq_sum);
+ 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");
@@ -2547,6 +2547,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
static void complete_request(struct ceph_mds_client *mdsc,
struct ceph_mds_request *req)
{
+ req->r_ended = jiffies;
+
if (req->r_callback)
req->r_callback(mdsc, req);
complete_all(&req->r_completion);
@@ -3155,6 +3157,9 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
/* kick calling process */
complete_request(mdsc, req);
+
+ ceph_update_metadata_latency(&mdsc->metric, req->r_started,
+ req->r_ended, err);
out:
ceph_mdsc_put_request(req);
return;
@@ -298,7 +298,8 @@ struct ceph_mds_request {
u32 r_readdir_offset;
unsigned long r_timeout; /* optional. jiffies, 0 is "wait forever" */
- unsigned long r_started; /* start time to measure timeout against */
+ unsigned long r_started; /* start time to measure timeout against and latency */
+ unsigned long r_ended; /* finish time to measure latency */
unsigned long r_request_started; /* start time for mds request only,
used to measure lease durations */
@@ -50,8 +50,20 @@ int ceph_metric_init(struct ceph_client_metric *m)
atomic64_set(&m->write_latency_min, S64_MAX);
atomic64_set(&m->write_latency_max, 0);
+ ret = percpu_counter_init(&m->metadata_latency_sq_sum, 0, GFP_KERNEL);
+ if (ret)
+ goto err_metadata_latency_sq_sum;
+
+ spin_lock_init(&m->metadata_latency_lock);
+ atomic64_set(&m->total_metadatas, 0);
+ atomic64_set(&m->metadata_latency_sum, 0);
+ atomic64_set(&m->metadata_latency_min, S64_MAX);
+ atomic64_set(&m->metadata_latency_max, 0);
+
return 0;
+err_metadata_latency_sq_sum:
+ percpu_counter_destroy(&m->write_latency_sq_sum);
err_write_latency_sq_sum:
percpu_counter_destroy(&m->read_latency_sq_sum);
err_read_latency_sq_sum:
@@ -71,6 +83,7 @@ void ceph_metric_destroy(struct ceph_client_metric *m)
if (!m)
return;
+ percpu_counter_destroy(&m->metadata_latency_sq_sum);
percpu_counter_destroy(&m->write_latency_sq_sum);
percpu_counter_destroy(&m->read_latency_sq_sum);
percpu_counter_destroy(&m->i_caps_mis);
@@ -160,3 +173,21 @@ void ceph_update_write_latency(struct ceph_client_metric *m,
&m->write_latency_lock,
lat);
}
+
+void ceph_update_metadata_latency(struct ceph_client_metric *m,
+ unsigned long r_start,
+ unsigned long r_end,
+ int rc)
+{
+ unsigned long lat = r_end - r_start;
+
+ if (unlikely(rc && rc != -ENOENT))
+ return;
+
+ __update_min_latency(&m->metadata_latency_min, lat);
+ __update_max_latency(&m->metadata_latency_max, lat);
+ __update_avg_and_sq(&m->total_metadatas, &m->metadata_latency_sum,
+ &m->metadata_latency_sq_sum,
+ &m->metadata_latency_lock,
+ lat);
+}
@@ -27,6 +27,13 @@ struct ceph_client_metric {
atomic64_t write_latency_sum;
atomic64_t write_latency_min;
atomic64_t write_latency_max;
+
+ struct percpu_counter metadata_latency_sq_sum;
+ spinlock_t metadata_latency_lock;
+ atomic64_t total_metadatas;
+ atomic64_t metadata_latency_sum;
+ atomic64_t metadata_latency_min;
+ atomic64_t metadata_latency_max;
};
extern int ceph_metric_init(struct ceph_client_metric *m);
@@ -50,4 +57,8 @@ extern void ceph_update_write_latency(struct ceph_client_metric *m,
unsigned long r_start,
unsigned long r_end,
int rc);
+extern void ceph_update_metadata_latency(struct ceph_client_metric *m,
+ unsigned long r_start,
+ unsigned long r_end,
+ int rc);
#endif /* _FS_CEPH_MDS_METRIC_H */