xref: /linux/fs/ceph/metric.h (revision ac2dc6d57425ffa9629941d7c9d7c0e51082cb5a)
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 	CLIENT_METRIC_TYPE_SUBVOLUME_METRICS,
29 
30 	CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_SUBVOLUME_METRICS,
31 };
32 
33 /*
34  * This will always have the highest metric bit value
35  * as the last element of the array.
36  */
37 #define CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED {	   \
38 	CLIENT_METRIC_TYPE_CAP_INFO,		   \
39 	CLIENT_METRIC_TYPE_READ_LATENCY,	   \
40 	CLIENT_METRIC_TYPE_WRITE_LATENCY,	   \
41 	CLIENT_METRIC_TYPE_METADATA_LATENCY,	   \
42 	CLIENT_METRIC_TYPE_DENTRY_LEASE,	   \
43 	CLIENT_METRIC_TYPE_OPENED_FILES,	   \
44 	CLIENT_METRIC_TYPE_PINNED_ICAPS,	   \
45 	CLIENT_METRIC_TYPE_OPENED_INODES,	   \
46 	CLIENT_METRIC_TYPE_READ_IO_SIZES,	   \
47 	CLIENT_METRIC_TYPE_WRITE_IO_SIZES,	   \
48 	CLIENT_METRIC_TYPE_AVG_READ_LATENCY,	   \
49 	CLIENT_METRIC_TYPE_STDEV_READ_LATENCY,	   \
50 	CLIENT_METRIC_TYPE_AVG_WRITE_LATENCY,	   \
51 	CLIENT_METRIC_TYPE_STDEV_WRITE_LATENCY,	   \
52 	CLIENT_METRIC_TYPE_AVG_METADATA_LATENCY,   \
53 	CLIENT_METRIC_TYPE_STDEV_METADATA_LATENCY, \
54 	CLIENT_METRIC_TYPE_SUBVOLUME_METRICS,	   \
55 						   \
56 	CLIENT_METRIC_TYPE_MAX,			   \
57 }
58 
59 struct ceph_metric_header {
60 	__le32 type;     /* ceph metric type */
61 	__u8  ver;
62 	__u8  compat;
63 	__le32 data_len; /* length of sizeof(hit + mis + total) */
64 } __packed;
65 
66 /* metric caps header */
67 struct ceph_metric_cap {
68 	struct ceph_metric_header header;
69 	__le64 hit;
70 	__le64 mis;
71 	__le64 total;
72 } __packed;
73 
74 /* metric read latency header */
75 struct ceph_metric_read_latency {
76 	struct ceph_metric_header header;
77 	struct ceph_timespec lat;
78 	struct ceph_timespec avg;
79 	__le64 sq_sum;
80 	__le64 count;
81 } __packed;
82 
83 /* metric write latency header */
84 struct ceph_metric_write_latency {
85 	struct ceph_metric_header header;
86 	struct ceph_timespec lat;
87 	struct ceph_timespec avg;
88 	__le64 sq_sum;
89 	__le64 count;
90 } __packed;
91 
92 /* metric metadata latency header */
93 struct ceph_metric_metadata_latency {
94 	struct ceph_metric_header header;
95 	struct ceph_timespec lat;
96 	struct ceph_timespec avg;
97 	__le64 sq_sum;
98 	__le64 count;
99 } __packed;
100 
101 /* metric dentry lease header */
102 struct ceph_metric_dlease {
103 	struct ceph_metric_header header;
104 	__le64 hit;
105 	__le64 mis;
106 	__le64 total;
107 } __packed;
108 
109 /* metric opened files header */
110 struct ceph_opened_files {
111 	struct ceph_metric_header header;
112 	__le64 opened_files;
113 	__le64 total;
114 } __packed;
115 
116 /* metric pinned i_caps header */
117 struct ceph_pinned_icaps {
118 	struct ceph_metric_header header;
119 	__le64 pinned_icaps;
120 	__le64 total;
121 } __packed;
122 
123 /* metric opened inodes header */
124 struct ceph_opened_inodes {
125 	struct ceph_metric_header header;
126 	__le64 opened_inodes;
127 	__le64 total;
128 } __packed;
129 
130 /* metric read io size header */
131 struct ceph_read_io_size {
132 	struct ceph_metric_header header;
133 	__le64 total_ops;
134 	__le64 total_size;
135 } __packed;
136 
137 /* metric write io size header */
138 struct ceph_write_io_size {
139 	struct ceph_metric_header header;
140 	__le64 total_ops;
141 	__le64 total_size;
142 } __packed;
143 
144 /**
145  * struct ceph_subvolume_metric_entry_wire - On-wire format sent to MDS
146  * @subvolume_id: Subvolume identifier
147  * @read_ops: Read operation count (32-bit, clamped from 64-bit internal)
148  * @write_ops: Write operation count (32-bit, clamped from 64-bit internal)
149  * @read_bytes: Total bytes read
150  * @write_bytes: Total bytes written
151  * @read_latency_us: Cumulative read latency in microseconds
152  * @write_latency_us: Cumulative write latency in microseconds
153  * @time_stamp: Collection timestamp (currently unused, set to 0)
154  *
155  * Wire format must match C++ AggregatedIOMetrics struct in MDS.
156  */
157 struct ceph_subvolume_metric_entry_wire {
158 	__le64 subvolume_id;
159 	__le32 read_ops;
160 	__le32 write_ops;
161 	__le64 read_bytes;
162 	__le64 write_bytes;
163 	__le64 read_latency_us;
164 	__le64 write_latency_us;
165 	__le64 time_stamp;
166 } __packed;
167 
168 /* Old struct kept for internal tracking, not used on wire */
169 struct ceph_subvolume_metric_entry {
170 	__le64 subvolume_id;
171 	__le64 read_ops;
172 	__le64 write_ops;
173 	__le64 read_bytes;
174 	__le64 write_bytes;
175 	__le64 read_latency_us;
176 	__le64 write_latency_us;
177 } __packed;
178 
179 struct ceph_metric_head {
180 	__le32 num;	/* the number of metrics that will be sent */
181 } __packed;
182 
183 enum metric_type {
184 	METRIC_READ,
185 	METRIC_WRITE,
186 	METRIC_METADATA,
187 	METRIC_COPYFROM,
188 	METRIC_MAX
189 };
190 
191 struct ceph_metric {
192 	spinlock_t lock;
193 	u64 total;
194 	u64 size_sum;
195 	u64 size_min;
196 	u64 size_max;
197 	ktime_t latency_sum;
198 	ktime_t latency_avg;
199 	ktime_t latency_sq_sum;
200 	ktime_t latency_min;
201 	ktime_t latency_max;
202 };
203 
204 /* This is the global metrics */
205 struct ceph_client_metric {
206 	atomic64_t            total_dentries;
207 	struct percpu_counter d_lease_hit;
208 	struct percpu_counter d_lease_mis;
209 
210 	atomic64_t            total_caps;
211 	struct percpu_counter i_caps_hit;
212 	struct percpu_counter i_caps_mis;
213 
214 	struct ceph_metric metric[METRIC_MAX];
215 
216 	/* The total number of directories and files that are opened */
217 	atomic64_t opened_files;
218 
219 	/* The total number of inodes that have opened files or directories */
220 	struct percpu_counter opened_inodes;
221 	struct percpu_counter total_inodes;
222 
223 	struct ceph_mds_session *session;
224 	struct delayed_work delayed_work;  /* delayed work */
225 };
226 
metric_schedule_delayed(struct ceph_client_metric * m)227 static inline void metric_schedule_delayed(struct ceph_client_metric *m)
228 {
229 	if (disable_send_metrics)
230 		return;
231 
232 	/* per second */
233 	schedule_delayed_work(&m->delayed_work, round_jiffies_relative(HZ));
234 }
235 
236 extern int ceph_metric_init(struct ceph_client_metric *m);
237 extern void ceph_metric_destroy(struct ceph_client_metric *m);
238 
ceph_update_cap_hit(struct ceph_client_metric * m)239 static inline void ceph_update_cap_hit(struct ceph_client_metric *m)
240 {
241 	percpu_counter_inc(&m->i_caps_hit);
242 }
243 
ceph_update_cap_mis(struct ceph_client_metric * m)244 static inline void ceph_update_cap_mis(struct ceph_client_metric *m)
245 {
246 	percpu_counter_inc(&m->i_caps_mis);
247 }
248 
249 extern void ceph_update_metrics(struct ceph_metric *m,
250 				ktime_t r_start, ktime_t r_end,
251 				unsigned int size, int rc);
252 
ceph_update_read_metrics(struct ceph_client_metric * m,ktime_t r_start,ktime_t r_end,unsigned int size,int rc)253 static inline void ceph_update_read_metrics(struct ceph_client_metric *m,
254 					    ktime_t r_start, ktime_t r_end,
255 					    unsigned int size, int rc)
256 {
257 	ceph_update_metrics(&m->metric[METRIC_READ],
258 			    r_start, r_end, size, rc);
259 }
ceph_update_write_metrics(struct ceph_client_metric * m,ktime_t r_start,ktime_t r_end,unsigned int size,int rc)260 static inline void ceph_update_write_metrics(struct ceph_client_metric *m,
261 					     ktime_t r_start, ktime_t r_end,
262 					     unsigned int size, int rc)
263 {
264 	ceph_update_metrics(&m->metric[METRIC_WRITE],
265 			    r_start, r_end, size, rc);
266 }
ceph_update_metadata_metrics(struct ceph_client_metric * m,ktime_t r_start,ktime_t r_end,int rc)267 static inline void ceph_update_metadata_metrics(struct ceph_client_metric *m,
268 						ktime_t r_start, ktime_t r_end,
269 						int rc)
270 {
271 	ceph_update_metrics(&m->metric[METRIC_METADATA],
272 			    r_start, r_end, 0, rc);
273 }
ceph_update_copyfrom_metrics(struct ceph_client_metric * m,ktime_t r_start,ktime_t r_end,unsigned int size,int rc)274 static inline void ceph_update_copyfrom_metrics(struct ceph_client_metric *m,
275 						ktime_t r_start, ktime_t r_end,
276 						unsigned int size, int rc)
277 {
278 	ceph_update_metrics(&m->metric[METRIC_COPYFROM],
279 			    r_start, r_end, size, rc);
280 }
281 #endif /* _FS_CEPH_MDS_METRIC_H */
282