.. | .. |
---|
7 | 7 | #include <linux/ctype.h> |
---|
8 | 8 | #include <linux/debugfs.h> |
---|
9 | 9 | #include <linux/seq_file.h> |
---|
| 10 | +#include <linux/math64.h> |
---|
| 11 | +#include <linux/ktime.h> |
---|
10 | 12 | |
---|
11 | 13 | #include <linux/ceph/libceph.h> |
---|
12 | 14 | #include <linux/ceph/mon_client.h> |
---|
.. | .. |
---|
18 | 20 | #ifdef CONFIG_DEBUG_FS |
---|
19 | 21 | |
---|
20 | 22 | #include "mds_client.h" |
---|
| 23 | +#include "metric.h" |
---|
21 | 24 | |
---|
22 | 25 | static int mdsmap_show(struct seq_file *s, void *p) |
---|
23 | 26 | { |
---|
.. | .. |
---|
33 | 36 | seq_printf(s, "max_mds %d\n", mdsmap->m_max_mds); |
---|
34 | 37 | seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout); |
---|
35 | 38 | seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose); |
---|
36 | | - for (i = 0; i < mdsmap->m_num_mds; i++) { |
---|
| 39 | + for (i = 0; i < mdsmap->possible_max_rank; i++) { |
---|
37 | 40 | struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr; |
---|
38 | 41 | int state = mdsmap->m_info[i].state; |
---|
39 | 42 | seq_printf(s, "\tmds%d\t%s\t(%s)\n", i, |
---|
40 | | - ceph_pr_addr(&addr->in_addr), |
---|
| 43 | + ceph_pr_addr(addr), |
---|
41 | 44 | ceph_mds_state_name(state)); |
---|
42 | 45 | } |
---|
43 | 46 | return 0; |
---|
.. | .. |
---|
52 | 55 | struct ceph_mds_client *mdsc = fsc->mdsc; |
---|
53 | 56 | struct ceph_mds_request *req; |
---|
54 | 57 | struct rb_node *rp; |
---|
55 | | - int pathlen; |
---|
| 58 | + int pathlen = 0; |
---|
56 | 59 | u64 pathbase; |
---|
57 | 60 | char *path; |
---|
58 | 61 | |
---|
.. | .. |
---|
88 | 91 | req->r_dentry, |
---|
89 | 92 | path ? path : ""); |
---|
90 | 93 | spin_unlock(&req->r_dentry->d_lock); |
---|
91 | | - kfree(path); |
---|
| 94 | + ceph_mdsc_free_path(path, pathlen); |
---|
92 | 95 | } else if (req->r_path1) { |
---|
93 | 96 | seq_printf(s, " #%llx/%s", req->r_ino1.ino, |
---|
94 | 97 | req->r_path1); |
---|
.. | .. |
---|
108 | 111 | req->r_old_dentry, |
---|
109 | 112 | path ? path : ""); |
---|
110 | 113 | spin_unlock(&req->r_old_dentry->d_lock); |
---|
111 | | - kfree(path); |
---|
| 114 | + ceph_mdsc_free_path(path, pathlen); |
---|
112 | 115 | } else if (req->r_path2 && req->r_op != CEPH_MDS_OP_SYMLINK) { |
---|
113 | 116 | if (req->r_ino2.ino) |
---|
114 | 117 | seq_printf(s, " #%llx/%s", req->r_ino2.ino, |
---|
.. | .. |
---|
124 | 127 | return 0; |
---|
125 | 128 | } |
---|
126 | 129 | |
---|
| 130 | +#define CEPH_METRIC_SHOW(name, total, avg, min, max, sq) { \ |
---|
| 131 | + s64 _total, _avg, _min, _max, _sq, _st; \ |
---|
| 132 | + _avg = ktime_to_us(avg); \ |
---|
| 133 | + _min = ktime_to_us(min == KTIME_MAX ? 0 : min); \ |
---|
| 134 | + _max = ktime_to_us(max); \ |
---|
| 135 | + _total = total - 1; \ |
---|
| 136 | + _sq = _total > 0 ? DIV64_U64_ROUND_CLOSEST(sq, _total) : 0; \ |
---|
| 137 | + _st = int_sqrt64(_sq); \ |
---|
| 138 | + _st = ktime_to_us(_st); \ |
---|
| 139 | + seq_printf(s, "%-14s%-12lld%-16lld%-16lld%-16lld%lld\n", \ |
---|
| 140 | + name, total, _avg, _min, _max, _st); \ |
---|
| 141 | +} |
---|
| 142 | + |
---|
| 143 | +static int metric_show(struct seq_file *s, void *p) |
---|
| 144 | +{ |
---|
| 145 | + struct ceph_fs_client *fsc = s->private; |
---|
| 146 | + struct ceph_mds_client *mdsc = fsc->mdsc; |
---|
| 147 | + struct ceph_client_metric *m = &mdsc->metric; |
---|
| 148 | + int nr_caps = 0; |
---|
| 149 | + s64 total, sum, avg, min, max, sq; |
---|
| 150 | + |
---|
| 151 | + sum = percpu_counter_sum(&m->total_inodes); |
---|
| 152 | + seq_printf(s, "item total\n"); |
---|
| 153 | + seq_printf(s, "------------------------------------------\n"); |
---|
| 154 | + seq_printf(s, "%-35s%lld / %lld\n", "opened files / total inodes", |
---|
| 155 | + atomic64_read(&m->opened_files), sum); |
---|
| 156 | + seq_printf(s, "%-35s%lld / %lld\n", "pinned i_caps / total inodes", |
---|
| 157 | + atomic64_read(&m->total_caps), sum); |
---|
| 158 | + seq_printf(s, "%-35s%lld / %lld\n", "opened inodes / total inodes", |
---|
| 159 | + percpu_counter_sum(&m->opened_inodes), sum); |
---|
| 160 | + |
---|
| 161 | + seq_printf(s, "\n"); |
---|
| 162 | + seq_printf(s, "item total avg_lat(us) min_lat(us) max_lat(us) stdev(us)\n"); |
---|
| 163 | + seq_printf(s, "-----------------------------------------------------------------------------------\n"); |
---|
| 164 | + |
---|
| 165 | + spin_lock(&m->read_latency_lock); |
---|
| 166 | + total = m->total_reads; |
---|
| 167 | + sum = m->read_latency_sum; |
---|
| 168 | + avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0; |
---|
| 169 | + min = m->read_latency_min; |
---|
| 170 | + max = m->read_latency_max; |
---|
| 171 | + sq = m->read_latency_sq_sum; |
---|
| 172 | + spin_unlock(&m->read_latency_lock); |
---|
| 173 | + CEPH_METRIC_SHOW("read", total, avg, min, max, sq); |
---|
| 174 | + |
---|
| 175 | + spin_lock(&m->write_latency_lock); |
---|
| 176 | + total = m->total_writes; |
---|
| 177 | + sum = m->write_latency_sum; |
---|
| 178 | + avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0; |
---|
| 179 | + min = m->write_latency_min; |
---|
| 180 | + max = m->write_latency_max; |
---|
| 181 | + sq = m->write_latency_sq_sum; |
---|
| 182 | + spin_unlock(&m->write_latency_lock); |
---|
| 183 | + CEPH_METRIC_SHOW("write", total, avg, min, max, sq); |
---|
| 184 | + |
---|
| 185 | + spin_lock(&m->metadata_latency_lock); |
---|
| 186 | + total = m->total_metadatas; |
---|
| 187 | + sum = m->metadata_latency_sum; |
---|
| 188 | + avg = total > 0 ? DIV64_U64_ROUND_CLOSEST(sum, total) : 0; |
---|
| 189 | + min = m->metadata_latency_min; |
---|
| 190 | + max = m->metadata_latency_max; |
---|
| 191 | + sq = m->metadata_latency_sq_sum; |
---|
| 192 | + spin_unlock(&m->metadata_latency_lock); |
---|
| 193 | + CEPH_METRIC_SHOW("metadata", total, avg, min, max, sq); |
---|
| 194 | + |
---|
| 195 | + seq_printf(s, "\n"); |
---|
| 196 | + seq_printf(s, "item total miss hit\n"); |
---|
| 197 | + seq_printf(s, "-------------------------------------------------\n"); |
---|
| 198 | + |
---|
| 199 | + seq_printf(s, "%-14s%-16lld%-16lld%lld\n", "d_lease", |
---|
| 200 | + atomic64_read(&m->total_dentries), |
---|
| 201 | + percpu_counter_sum(&m->d_lease_mis), |
---|
| 202 | + percpu_counter_sum(&m->d_lease_hit)); |
---|
| 203 | + |
---|
| 204 | + nr_caps = atomic64_read(&m->total_caps); |
---|
| 205 | + seq_printf(s, "%-14s%-16d%-16lld%lld\n", "caps", nr_caps, |
---|
| 206 | + percpu_counter_sum(&m->i_caps_mis), |
---|
| 207 | + percpu_counter_sum(&m->i_caps_hit)); |
---|
| 208 | + |
---|
| 209 | + return 0; |
---|
| 210 | +} |
---|
| 211 | + |
---|
| 212 | +static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p) |
---|
| 213 | +{ |
---|
| 214 | + struct seq_file *s = p; |
---|
| 215 | + |
---|
| 216 | + seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode), |
---|
| 217 | + cap->session->s_mds, |
---|
| 218 | + ceph_cap_string(cap->issued), |
---|
| 219 | + ceph_cap_string(cap->implemented)); |
---|
| 220 | + return 0; |
---|
| 221 | +} |
---|
| 222 | + |
---|
127 | 223 | static int caps_show(struct seq_file *s, void *p) |
---|
128 | 224 | { |
---|
129 | 225 | struct ceph_fs_client *fsc = s->private; |
---|
130 | | - int total, avail, used, reserved, min; |
---|
| 226 | + struct ceph_mds_client *mdsc = fsc->mdsc; |
---|
| 227 | + int total, avail, used, reserved, min, i; |
---|
| 228 | + struct cap_wait *cw; |
---|
131 | 229 | |
---|
132 | 230 | ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min); |
---|
133 | 231 | seq_printf(s, "total\t\t%d\n" |
---|
134 | 232 | "avail\t\t%d\n" |
---|
135 | 233 | "used\t\t%d\n" |
---|
136 | 234 | "reserved\t%d\n" |
---|
137 | | - "min\t%d\n", |
---|
| 235 | + "min\t\t%d\n\n", |
---|
138 | 236 | total, avail, used, reserved, min); |
---|
139 | | - return 0; |
---|
140 | | -} |
---|
| 237 | + seq_printf(s, "ino mds issued implemented\n"); |
---|
| 238 | + seq_printf(s, "--------------------------------------------------\n"); |
---|
141 | 239 | |
---|
142 | | -static int dentry_lru_show(struct seq_file *s, void *ptr) |
---|
143 | | -{ |
---|
144 | | - struct ceph_fs_client *fsc = s->private; |
---|
145 | | - struct ceph_mds_client *mdsc = fsc->mdsc; |
---|
146 | | - struct ceph_dentry_info *di; |
---|
| 240 | + mutex_lock(&mdsc->mutex); |
---|
| 241 | + for (i = 0; i < mdsc->max_sessions; i++) { |
---|
| 242 | + struct ceph_mds_session *session; |
---|
147 | 243 | |
---|
148 | | - spin_lock(&mdsc->dentry_lru_lock); |
---|
149 | | - list_for_each_entry(di, &mdsc->dentry_lru, lru) { |
---|
150 | | - struct dentry *dentry = di->dentry; |
---|
151 | | - seq_printf(s, "%p %p\t%pd\n", |
---|
152 | | - di, dentry, dentry); |
---|
| 244 | + session = __ceph_lookup_mds_session(mdsc, i); |
---|
| 245 | + if (!session) |
---|
| 246 | + continue; |
---|
| 247 | + mutex_unlock(&mdsc->mutex); |
---|
| 248 | + mutex_lock(&session->s_mutex); |
---|
| 249 | + ceph_iterate_session_caps(session, caps_show_cb, s); |
---|
| 250 | + mutex_unlock(&session->s_mutex); |
---|
| 251 | + ceph_put_mds_session(session); |
---|
| 252 | + mutex_lock(&mdsc->mutex); |
---|
153 | 253 | } |
---|
154 | | - spin_unlock(&mdsc->dentry_lru_lock); |
---|
| 254 | + mutex_unlock(&mdsc->mutex); |
---|
| 255 | + |
---|
| 256 | + seq_printf(s, "\n\nWaiters:\n--------\n"); |
---|
| 257 | + seq_printf(s, "tgid ino need want\n"); |
---|
| 258 | + seq_printf(s, "-----------------------------------------------------\n"); |
---|
| 259 | + |
---|
| 260 | + spin_lock(&mdsc->caps_list_lock); |
---|
| 261 | + list_for_each_entry(cw, &mdsc->cap_wait_list, list) { |
---|
| 262 | + seq_printf(s, "%-13d0x%-17llx%-17s%-17s\n", cw->tgid, cw->ino, |
---|
| 263 | + ceph_cap_string(cw->need), |
---|
| 264 | + ceph_cap_string(cw->want)); |
---|
| 265 | + } |
---|
| 266 | + spin_unlock(&mdsc->caps_list_lock); |
---|
155 | 267 | |
---|
156 | 268 | return 0; |
---|
157 | 269 | } |
---|
.. | .. |
---|
162 | 274 | struct ceph_mds_client *mdsc = fsc->mdsc; |
---|
163 | 275 | struct ceph_auth_client *ac = fsc->client->monc.auth; |
---|
164 | 276 | struct ceph_options *opt = fsc->client->options; |
---|
165 | | - int mds = -1; |
---|
| 277 | + int mds; |
---|
166 | 278 | |
---|
167 | 279 | mutex_lock(&mdsc->mutex); |
---|
168 | 280 | |
---|
.. | .. |
---|
192 | 304 | return 0; |
---|
193 | 305 | } |
---|
194 | 306 | |
---|
195 | | -CEPH_DEFINE_SHOW_FUNC(mdsmap_show) |
---|
196 | | -CEPH_DEFINE_SHOW_FUNC(mdsc_show) |
---|
197 | | -CEPH_DEFINE_SHOW_FUNC(caps_show) |
---|
198 | | -CEPH_DEFINE_SHOW_FUNC(dentry_lru_show) |
---|
199 | | -CEPH_DEFINE_SHOW_FUNC(mds_sessions_show) |
---|
| 307 | +DEFINE_SHOW_ATTRIBUTE(mdsmap); |
---|
| 308 | +DEFINE_SHOW_ATTRIBUTE(mdsc); |
---|
| 309 | +DEFINE_SHOW_ATTRIBUTE(caps); |
---|
| 310 | +DEFINE_SHOW_ATTRIBUTE(mds_sessions); |
---|
| 311 | +DEFINE_SHOW_ATTRIBUTE(metric); |
---|
200 | 312 | |
---|
201 | 313 | |
---|
202 | 314 | /* |
---|
.. | .. |
---|
230 | 342 | debugfs_remove(fsc->debugfs_mdsmap); |
---|
231 | 343 | debugfs_remove(fsc->debugfs_mds_sessions); |
---|
232 | 344 | debugfs_remove(fsc->debugfs_caps); |
---|
| 345 | + debugfs_remove(fsc->debugfs_metric); |
---|
233 | 346 | debugfs_remove(fsc->debugfs_mdsc); |
---|
234 | | - debugfs_remove(fsc->debugfs_dentry_lru); |
---|
235 | 347 | } |
---|
236 | 348 | |
---|
237 | | -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) |
---|
| 349 | +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) |
---|
238 | 350 | { |
---|
239 | 351 | char name[100]; |
---|
240 | | - int err = -ENOMEM; |
---|
241 | 352 | |
---|
242 | 353 | dout("ceph_fs_debugfs_init\n"); |
---|
243 | | - BUG_ON(!fsc->client->debugfs_dir); |
---|
244 | 354 | fsc->debugfs_congestion_kb = |
---|
245 | 355 | debugfs_create_file("writeback_congestion_kb", |
---|
246 | 356 | 0600, |
---|
247 | 357 | fsc->client->debugfs_dir, |
---|
248 | 358 | fsc, |
---|
249 | 359 | &congestion_kb_fops); |
---|
250 | | - if (!fsc->debugfs_congestion_kb) |
---|
251 | | - goto out; |
---|
252 | 360 | |
---|
253 | 361 | snprintf(name, sizeof(name), "../../bdi/%s", |
---|
254 | 362 | bdi_dev_name(fsc->sb->s_bdi)); |
---|
.. | .. |
---|
256 | 364 | debugfs_create_symlink("bdi", |
---|
257 | 365 | fsc->client->debugfs_dir, |
---|
258 | 366 | name); |
---|
259 | | - if (!fsc->debugfs_bdi) |
---|
260 | | - goto out; |
---|
261 | 367 | |
---|
262 | 368 | fsc->debugfs_mdsmap = debugfs_create_file("mdsmap", |
---|
263 | 369 | 0400, |
---|
264 | 370 | fsc->client->debugfs_dir, |
---|
265 | 371 | fsc, |
---|
266 | | - &mdsmap_show_fops); |
---|
267 | | - if (!fsc->debugfs_mdsmap) |
---|
268 | | - goto out; |
---|
| 372 | + &mdsmap_fops); |
---|
269 | 373 | |
---|
270 | 374 | fsc->debugfs_mds_sessions = debugfs_create_file("mds_sessions", |
---|
271 | 375 | 0400, |
---|
272 | 376 | fsc->client->debugfs_dir, |
---|
273 | 377 | fsc, |
---|
274 | | - &mds_sessions_show_fops); |
---|
275 | | - if (!fsc->debugfs_mds_sessions) |
---|
276 | | - goto out; |
---|
| 378 | + &mds_sessions_fops); |
---|
277 | 379 | |
---|
278 | 380 | fsc->debugfs_mdsc = debugfs_create_file("mdsc", |
---|
279 | 381 | 0400, |
---|
280 | 382 | fsc->client->debugfs_dir, |
---|
281 | 383 | fsc, |
---|
282 | | - &mdsc_show_fops); |
---|
283 | | - if (!fsc->debugfs_mdsc) |
---|
284 | | - goto out; |
---|
| 384 | + &mdsc_fops); |
---|
| 385 | + |
---|
| 386 | + fsc->debugfs_metric = debugfs_create_file("metrics", |
---|
| 387 | + 0400, |
---|
| 388 | + fsc->client->debugfs_dir, |
---|
| 389 | + fsc, |
---|
| 390 | + &metric_fops); |
---|
285 | 391 | |
---|
286 | 392 | fsc->debugfs_caps = debugfs_create_file("caps", |
---|
287 | | - 0400, |
---|
288 | | - fsc->client->debugfs_dir, |
---|
289 | | - fsc, |
---|
290 | | - &caps_show_fops); |
---|
291 | | - if (!fsc->debugfs_caps) |
---|
292 | | - goto out; |
---|
293 | | - |
---|
294 | | - fsc->debugfs_dentry_lru = debugfs_create_file("dentry_lru", |
---|
295 | | - 0400, |
---|
296 | | - fsc->client->debugfs_dir, |
---|
297 | | - fsc, |
---|
298 | | - &dentry_lru_show_fops); |
---|
299 | | - if (!fsc->debugfs_dentry_lru) |
---|
300 | | - goto out; |
---|
301 | | - |
---|
302 | | - return 0; |
---|
303 | | - |
---|
304 | | -out: |
---|
305 | | - ceph_fs_debugfs_cleanup(fsc); |
---|
306 | | - return err; |
---|
| 393 | + 0400, |
---|
| 394 | + fsc->client->debugfs_dir, |
---|
| 395 | + fsc, |
---|
| 396 | + &caps_fops); |
---|
307 | 397 | } |
---|
308 | 398 | |
---|
309 | 399 | |
---|
310 | 400 | #else /* CONFIG_DEBUG_FS */ |
---|
311 | 401 | |
---|
312 | | -int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) |
---|
| 402 | +void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) |
---|
313 | 403 | { |
---|
314 | | - return 0; |
---|
315 | 404 | } |
---|
316 | 405 | |
---|
317 | 406 | void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc) |
---|