c6x: switch to ->regset_get()
[linux-2.6-microblaze.git] / fs / ceph / metric.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #include <linux/types.h>
4 #include <linux/percpu_counter.h>
5 #include <linux/math64.h>
6
7 #include "metric.h"
8
9 int ceph_metric_init(struct ceph_client_metric *m)
10 {
11         int ret;
12
13         if (!m)
14                 return -EINVAL;
15
16         atomic64_set(&m->total_dentries, 0);
17         ret = percpu_counter_init(&m->d_lease_hit, 0, GFP_KERNEL);
18         if (ret)
19                 return ret;
20
21         ret = percpu_counter_init(&m->d_lease_mis, 0, GFP_KERNEL);
22         if (ret)
23                 goto err_d_lease_mis;
24
25         ret = percpu_counter_init(&m->i_caps_hit, 0, GFP_KERNEL);
26         if (ret)
27                 goto err_i_caps_hit;
28
29         ret = percpu_counter_init(&m->i_caps_mis, 0, GFP_KERNEL);
30         if (ret)
31                 goto err_i_caps_mis;
32
33         spin_lock_init(&m->read_latency_lock);
34         m->read_latency_sq_sum = 0;
35         m->read_latency_min = KTIME_MAX;
36         m->read_latency_max = 0;
37         m->total_reads = 0;
38         m->read_latency_sum = 0;
39
40         spin_lock_init(&m->write_latency_lock);
41         m->write_latency_sq_sum = 0;
42         m->write_latency_min = KTIME_MAX;
43         m->write_latency_max = 0;
44         m->total_writes = 0;
45         m->write_latency_sum = 0;
46
47         spin_lock_init(&m->metadata_latency_lock);
48         m->metadata_latency_sq_sum = 0;
49         m->metadata_latency_min = KTIME_MAX;
50         m->metadata_latency_max = 0;
51         m->total_metadatas = 0;
52         m->metadata_latency_sum = 0;
53
54         return 0;
55
56 err_i_caps_mis:
57         percpu_counter_destroy(&m->i_caps_hit);
58 err_i_caps_hit:
59         percpu_counter_destroy(&m->d_lease_mis);
60 err_d_lease_mis:
61         percpu_counter_destroy(&m->d_lease_hit);
62
63         return ret;
64 }
65
66 void ceph_metric_destroy(struct ceph_client_metric *m)
67 {
68         if (!m)
69                 return;
70
71         percpu_counter_destroy(&m->i_caps_mis);
72         percpu_counter_destroy(&m->i_caps_hit);
73         percpu_counter_destroy(&m->d_lease_mis);
74         percpu_counter_destroy(&m->d_lease_hit);
75 }
76
77 static inline void __update_latency(ktime_t *totalp, ktime_t *lsump,
78                                     ktime_t *min, ktime_t *max,
79                                     ktime_t *sq_sump, ktime_t lat)
80 {
81         ktime_t total, avg, sq, lsum;
82
83         total = ++(*totalp);
84         lsum = (*lsump += lat);
85
86         if (unlikely(lat < *min))
87                 *min = lat;
88         if (unlikely(lat > *max))
89                 *max = lat;
90
91         if (unlikely(total == 1))
92                 return;
93
94         /* the sq is (lat - old_avg) * (lat - new_avg) */
95         avg = DIV64_U64_ROUND_CLOSEST((lsum - lat), (total - 1));
96         sq = lat - avg;
97         avg = DIV64_U64_ROUND_CLOSEST(lsum, total);
98         sq = sq * (lat - avg);
99         *sq_sump += sq;
100 }
101
102 void ceph_update_read_latency(struct ceph_client_metric *m,
103                               ktime_t r_start, ktime_t r_end,
104                               int rc)
105 {
106         ktime_t lat = ktime_sub(r_end, r_start);
107
108         if (unlikely(rc < 0 && rc != -ENOENT && rc != -ETIMEDOUT))
109                 return;
110
111         spin_lock(&m->read_latency_lock);
112         __update_latency(&m->total_reads, &m->read_latency_sum,
113                          &m->read_latency_min, &m->read_latency_max,
114                          &m->read_latency_sq_sum, lat);
115         spin_unlock(&m->read_latency_lock);
116 }
117
118 void ceph_update_write_latency(struct ceph_client_metric *m,
119                                ktime_t r_start, ktime_t r_end,
120                                int rc)
121 {
122         ktime_t lat = ktime_sub(r_end, r_start);
123
124         if (unlikely(rc && rc != -ETIMEDOUT))
125                 return;
126
127         spin_lock(&m->write_latency_lock);
128         __update_latency(&m->total_writes, &m->write_latency_sum,
129                          &m->write_latency_min, &m->write_latency_max,
130                          &m->write_latency_sq_sum, lat);
131         spin_unlock(&m->write_latency_lock);
132 }
133
134 void ceph_update_metadata_latency(struct ceph_client_metric *m,
135                                   ktime_t r_start, ktime_t r_end,
136                                   int rc)
137 {
138         ktime_t lat = ktime_sub(r_end, r_start);
139
140         if (unlikely(rc && rc != -ENOENT))
141                 return;
142
143         spin_lock(&m->metadata_latency_lock);
144         __update_latency(&m->total_metadatas, &m->metadata_latency_sum,
145                          &m->metadata_latency_min, &m->metadata_latency_max,
146                          &m->metadata_latency_sq_sum, lat);
147         spin_unlock(&m->metadata_latency_lock);
148 }