1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _FS_CEPH_MDS_METRIC_H |
3 | #define _FS_CEPH_MDS_METRIC_H |
4 | |
5 | #include <linux/ceph/types.h> |
6 | #include <linux/percpu_counter.h> |
7 | #include <linux/ktime.h> |
8 | |
9 | extern bool disable_send_metrics; |
10 | |
11 | enum ceph_metric_type { |
12 | CLIENT_METRIC_TYPE_CAP_INFO, |
13 | CLIENT_METRIC_TYPE_READ_LATENCY, |
14 | CLIENT_METRIC_TYPE_WRITE_LATENCY, |
15 | CLIENT_METRIC_TYPE_METADATA_LATENCY, |
16 | CLIENT_METRIC_TYPE_DENTRY_LEASE, |
17 | CLIENT_METRIC_TYPE_OPENED_FILES, |
18 | CLIENT_METRIC_TYPE_PINNED_ICAPS, |
19 | CLIENT_METRIC_TYPE_OPENED_INODES, |
20 | CLIENT_METRIC_TYPE_READ_IO_SIZES, |
21 | CLIENT_METRIC_TYPE_WRITE_IO_SIZES, |
22 | CLIENT_METRIC_TYPE_AVG_READ_LATENCY, |
23 | CLIENT_METRIC_TYPE_STDEV_READ_LATENCY, |
24 | CLIENT_METRIC_TYPE_AVG_WRITE_LATENCY, |
25 | CLIENT_METRIC_TYPE_STDEV_WRITE_LATENCY, |
26 | CLIENT_METRIC_TYPE_AVG_METADATA_LATENCY, |
27 | CLIENT_METRIC_TYPE_STDEV_METADATA_LATENCY, |
28 | |
29 | CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_STDEV_METADATA_LATENCY, |
30 | }; |
31 | |
32 | /* |
33 | * This will always have the highest metric bit value |
34 | * as the last element of the array. |
35 | */ |
36 | #define CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED { \ |
37 | CLIENT_METRIC_TYPE_CAP_INFO, \ |
38 | CLIENT_METRIC_TYPE_READ_LATENCY, \ |
39 | CLIENT_METRIC_TYPE_WRITE_LATENCY, \ |
40 | CLIENT_METRIC_TYPE_METADATA_LATENCY, \ |
41 | CLIENT_METRIC_TYPE_DENTRY_LEASE, \ |
42 | CLIENT_METRIC_TYPE_OPENED_FILES, \ |
43 | CLIENT_METRIC_TYPE_PINNED_ICAPS, \ |
44 | CLIENT_METRIC_TYPE_OPENED_INODES, \ |
45 | CLIENT_METRIC_TYPE_READ_IO_SIZES, \ |
46 | CLIENT_METRIC_TYPE_WRITE_IO_SIZES, \ |
47 | CLIENT_METRIC_TYPE_AVG_READ_LATENCY, \ |
48 | CLIENT_METRIC_TYPE_STDEV_READ_LATENCY, \ |
49 | CLIENT_METRIC_TYPE_AVG_WRITE_LATENCY, \ |
50 | CLIENT_METRIC_TYPE_STDEV_WRITE_LATENCY, \ |
51 | CLIENT_METRIC_TYPE_AVG_METADATA_LATENCY, \ |
52 | CLIENT_METRIC_TYPE_STDEV_METADATA_LATENCY, \ |
53 | \ |
54 | CLIENT_METRIC_TYPE_MAX, \ |
55 | } |
56 | |
57 | struct { |
58 | __le32 ; /* ceph metric type */ |
59 | __u8 ; |
60 | __u8 ; |
61 | __le32 ; /* length of sizeof(hit + mis + total) */ |
62 | } __packed; |
63 | |
64 | /* metric caps header */ |
65 | struct ceph_metric_cap { |
66 | struct ceph_metric_header ; |
67 | __le64 hit; |
68 | __le64 mis; |
69 | __le64 total; |
70 | } __packed; |
71 | |
72 | /* metric read latency header */ |
73 | struct ceph_metric_read_latency { |
74 | struct ceph_metric_header ; |
75 | struct ceph_timespec lat; |
76 | struct ceph_timespec avg; |
77 | __le64 sq_sum; |
78 | __le64 count; |
79 | } __packed; |
80 | |
81 | /* metric write latency header */ |
82 | struct ceph_metric_write_latency { |
83 | struct ceph_metric_header ; |
84 | struct ceph_timespec lat; |
85 | struct ceph_timespec avg; |
86 | __le64 sq_sum; |
87 | __le64 count; |
88 | } __packed; |
89 | |
90 | /* metric metadata latency header */ |
91 | struct ceph_metric_metadata_latency { |
92 | struct ceph_metric_header ; |
93 | struct ceph_timespec lat; |
94 | struct ceph_timespec avg; |
95 | __le64 sq_sum; |
96 | __le64 count; |
97 | } __packed; |
98 | |
99 | /* metric dentry lease header */ |
100 | struct ceph_metric_dlease { |
101 | struct ceph_metric_header ; |
102 | __le64 hit; |
103 | __le64 mis; |
104 | __le64 total; |
105 | } __packed; |
106 | |
107 | /* metric opened files header */ |
108 | struct ceph_opened_files { |
109 | struct ceph_metric_header ; |
110 | __le64 opened_files; |
111 | __le64 total; |
112 | } __packed; |
113 | |
114 | /* metric pinned i_caps header */ |
115 | struct ceph_pinned_icaps { |
116 | struct ceph_metric_header ; |
117 | __le64 pinned_icaps; |
118 | __le64 total; |
119 | } __packed; |
120 | |
121 | /* metric opened inodes header */ |
122 | struct ceph_opened_inodes { |
123 | struct ceph_metric_header ; |
124 | __le64 opened_inodes; |
125 | __le64 total; |
126 | } __packed; |
127 | |
128 | /* metric read io size header */ |
129 | struct ceph_read_io_size { |
130 | struct ceph_metric_header ; |
131 | __le64 total_ops; |
132 | __le64 total_size; |
133 | } __packed; |
134 | |
135 | /* metric write io size header */ |
136 | struct ceph_write_io_size { |
137 | struct ceph_metric_header ; |
138 | __le64 total_ops; |
139 | __le64 total_size; |
140 | } __packed; |
141 | |
142 | struct ceph_metric_head { |
143 | __le32 num; /* the number of metrics that will be sent */ |
144 | } __packed; |
145 | |
146 | enum metric_type { |
147 | METRIC_READ, |
148 | METRIC_WRITE, |
149 | METRIC_METADATA, |
150 | METRIC_COPYFROM, |
151 | METRIC_MAX |
152 | }; |
153 | |
154 | struct ceph_metric { |
155 | spinlock_t lock; |
156 | u64 total; |
157 | u64 size_sum; |
158 | u64 size_min; |
159 | u64 size_max; |
160 | ktime_t latency_sum; |
161 | ktime_t latency_avg; |
162 | ktime_t latency_sq_sum; |
163 | ktime_t latency_min; |
164 | ktime_t latency_max; |
165 | }; |
166 | |
167 | /* This is the global metrics */ |
168 | struct ceph_client_metric { |
169 | atomic64_t total_dentries; |
170 | struct percpu_counter d_lease_hit; |
171 | struct percpu_counter d_lease_mis; |
172 | |
173 | atomic64_t total_caps; |
174 | struct percpu_counter i_caps_hit; |
175 | struct percpu_counter i_caps_mis; |
176 | |
177 | struct ceph_metric metric[METRIC_MAX]; |
178 | |
179 | /* The total number of directories and files that are opened */ |
180 | atomic64_t opened_files; |
181 | |
182 | /* The total number of inodes that have opened files or directories */ |
183 | struct percpu_counter opened_inodes; |
184 | struct percpu_counter total_inodes; |
185 | |
186 | struct ceph_mds_session *session; |
187 | struct delayed_work delayed_work; /* delayed work */ |
188 | }; |
189 | |
190 | static inline void metric_schedule_delayed(struct ceph_client_metric *m) |
191 | { |
192 | if (disable_send_metrics) |
193 | return; |
194 | |
195 | /* per second */ |
196 | schedule_delayed_work(dwork: &m->delayed_work, delay: round_jiffies_relative(HZ)); |
197 | } |
198 | |
199 | extern int ceph_metric_init(struct ceph_client_metric *m); |
200 | extern void ceph_metric_destroy(struct ceph_client_metric *m); |
201 | |
202 | static inline void ceph_update_cap_hit(struct ceph_client_metric *m) |
203 | { |
204 | percpu_counter_inc(fbc: &m->i_caps_hit); |
205 | } |
206 | |
207 | static inline void ceph_update_cap_mis(struct ceph_client_metric *m) |
208 | { |
209 | percpu_counter_inc(fbc: &m->i_caps_mis); |
210 | } |
211 | |
212 | extern void ceph_update_metrics(struct ceph_metric *m, |
213 | ktime_t r_start, ktime_t r_end, |
214 | unsigned int size, int rc); |
215 | |
216 | static inline void ceph_update_read_metrics(struct ceph_client_metric *m, |
217 | ktime_t r_start, ktime_t r_end, |
218 | unsigned int size, int rc) |
219 | { |
220 | ceph_update_metrics(m: &m->metric[METRIC_READ], |
221 | r_start, r_end, size, rc); |
222 | } |
223 | static inline void ceph_update_write_metrics(struct ceph_client_metric *m, |
224 | ktime_t r_start, ktime_t r_end, |
225 | unsigned int size, int rc) |
226 | { |
227 | ceph_update_metrics(m: &m->metric[METRIC_WRITE], |
228 | r_start, r_end, size, rc); |
229 | } |
230 | static inline void ceph_update_metadata_metrics(struct ceph_client_metric *m, |
231 | ktime_t r_start, ktime_t r_end, |
232 | int rc) |
233 | { |
234 | ceph_update_metrics(m: &m->metric[METRIC_METADATA], |
235 | r_start, r_end, size: 0, rc); |
236 | } |
237 | static inline void ceph_update_copyfrom_metrics(struct ceph_client_metric *m, |
238 | ktime_t r_start, ktime_t r_end, |
239 | unsigned int size, int rc) |
240 | { |
241 | ceph_update_metrics(m: &m->metric[METRIC_COPYFROM], |
242 | r_start, r_end, size, rc); |
243 | } |
244 | #endif /* _FS_CEPH_MDS_METRIC_H */ |
245 | |