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 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 239 static inline void ceph_update_cap_hit(struct ceph_client_metric *m) 240 { 241 percpu_counter_inc(&m->i_caps_hit); 242 } 243 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 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 } 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 } 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 } 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