Commit f9009efa authored by Xiubo Li's avatar Xiubo Li Committed by Ilya Dryomov

ceph: add dentry lease metric support

For dentry leases, only count the hit/miss info triggered from the vfs
calls. For the cases like request reply handling and ceph_trim_dentries,
ignore them.

For now, these are only viewable using debugfs. Future patches will
allow the client to send the stats to the MDS.

The output looks like:

item          total           miss            hit
-------------------------------------------------
d_lease       11              7               141

URL: https://tracker.ceph.com/issues/43215Signed-off-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 3d77e6a8
...@@ -8,7 +8,7 @@ obj-$(CONFIG_CEPH_FS) += ceph.o ...@@ -8,7 +8,7 @@ obj-$(CONFIG_CEPH_FS) += ceph.o
ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
export.o caps.o snap.o xattr.o quota.o io.o \ export.o caps.o snap.o xattr.o quota.o io.o \
mds_client.o mdsmap.o strings.o ceph_frag.o \ mds_client.o mdsmap.o strings.o ceph_frag.o \
debugfs.o util.o debugfs.o util.o metric.o
ceph-$(CONFIG_CEPH_FSCACHE) += cache.o ceph-$(CONFIG_CEPH_FSCACHE) += cache.o
ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o
...@@ -124,6 +124,23 @@ static int mdsc_show(struct seq_file *s, void *p) ...@@ -124,6 +124,23 @@ static int mdsc_show(struct seq_file *s, void *p)
return 0; return 0;
} }
static int metric_show(struct seq_file *s, void *p)
{
struct ceph_fs_client *fsc = s->private;
struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_client_metric *m = &mdsc->metric;
seq_printf(s, "item total miss hit\n");
seq_printf(s, "-------------------------------------------------\n");
seq_printf(s, "%-14s%-16lld%-16lld%lld\n", "d_lease",
atomic64_read(&m->total_dentries),
percpu_counter_sum(&m->d_lease_mis),
percpu_counter_sum(&m->d_lease_hit));
return 0;
}
static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p) static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
{ {
struct seq_file *s = p; struct seq_file *s = p;
...@@ -222,6 +239,7 @@ DEFINE_SHOW_ATTRIBUTE(mdsmap); ...@@ -222,6 +239,7 @@ DEFINE_SHOW_ATTRIBUTE(mdsmap);
DEFINE_SHOW_ATTRIBUTE(mdsc); DEFINE_SHOW_ATTRIBUTE(mdsc);
DEFINE_SHOW_ATTRIBUTE(caps); DEFINE_SHOW_ATTRIBUTE(caps);
DEFINE_SHOW_ATTRIBUTE(mds_sessions); DEFINE_SHOW_ATTRIBUTE(mds_sessions);
DEFINE_SHOW_ATTRIBUTE(metric);
/* /*
...@@ -255,6 +273,7 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc) ...@@ -255,6 +273,7 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
debugfs_remove(fsc->debugfs_mdsmap); debugfs_remove(fsc->debugfs_mdsmap);
debugfs_remove(fsc->debugfs_mds_sessions); debugfs_remove(fsc->debugfs_mds_sessions);
debugfs_remove(fsc->debugfs_caps); debugfs_remove(fsc->debugfs_caps);
debugfs_remove(fsc->debugfs_metric);
debugfs_remove(fsc->debugfs_mdsc); debugfs_remove(fsc->debugfs_mdsc);
} }
...@@ -295,11 +314,17 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) ...@@ -295,11 +314,17 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
fsc, fsc,
&mdsc_fops); &mdsc_fops);
fsc->debugfs_metric = debugfs_create_file("metrics",
0400,
fsc->client->debugfs_dir,
fsc,
&metric_fops);
fsc->debugfs_caps = debugfs_create_file("caps", fsc->debugfs_caps = debugfs_create_file("caps",
0400, 0400,
fsc->client->debugfs_dir, fsc->client->debugfs_dir,
fsc, fsc,
&caps_fops); &caps_fops);
} }
......
...@@ -38,6 +38,8 @@ static int __dir_lease_try_check(const struct dentry *dentry); ...@@ -38,6 +38,8 @@ static int __dir_lease_try_check(const struct dentry *dentry);
static int ceph_d_init(struct dentry *dentry) static int ceph_d_init(struct dentry *dentry)
{ {
struct ceph_dentry_info *di; struct ceph_dentry_info *di;
struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
struct ceph_mds_client *mdsc = fsc->mdsc;
di = kmem_cache_zalloc(ceph_dentry_cachep, GFP_KERNEL); di = kmem_cache_zalloc(ceph_dentry_cachep, GFP_KERNEL);
if (!di) if (!di)
...@@ -48,6 +50,9 @@ static int ceph_d_init(struct dentry *dentry) ...@@ -48,6 +50,9 @@ static int ceph_d_init(struct dentry *dentry)
di->time = jiffies; di->time = jiffies;
dentry->d_fsdata = di; dentry->d_fsdata = di;
INIT_LIST_HEAD(&di->lease_list); INIT_LIST_HEAD(&di->lease_list);
atomic64_inc(&mdsc->metric.total_dentries);
return 0; return 0;
} }
...@@ -1709,6 +1714,8 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -1709,6 +1714,8 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
if (flags & LOOKUP_RCU) if (flags & LOOKUP_RCU)
return -ECHILD; return -ECHILD;
percpu_counter_inc(&mdsc->metric.d_lease_mis);
op = ceph_snap(dir) == CEPH_SNAPDIR ? op = ceph_snap(dir) == CEPH_SNAPDIR ?
CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
...@@ -1740,6 +1747,8 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -1740,6 +1747,8 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
dout("d_revalidate %p lookup result=%d\n", dout("d_revalidate %p lookup result=%d\n",
dentry, err); dentry, err);
} }
} else {
percpu_counter_inc(&mdsc->metric.d_lease_hit);
} }
dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid"); dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid");
...@@ -1782,9 +1791,12 @@ static int ceph_d_delete(const struct dentry *dentry) ...@@ -1782,9 +1791,12 @@ static int ceph_d_delete(const struct dentry *dentry)
static void ceph_d_release(struct dentry *dentry) static void ceph_d_release(struct dentry *dentry)
{ {
struct ceph_dentry_info *di = ceph_dentry(dentry); struct ceph_dentry_info *di = ceph_dentry(dentry);
struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
dout("d_release %p\n", dentry); dout("d_release %p\n", dentry);
atomic64_dec(&fsc->mdsc->metric.total_dentries);
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
__dentry_lease_unlist(di); __dentry_lease_unlist(di);
dentry->d_fsdata = NULL; dentry->d_fsdata = NULL;
......
...@@ -4323,6 +4323,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) ...@@ -4323,6 +4323,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
{ {
struct ceph_mds_client *mdsc; struct ceph_mds_client *mdsc;
int err;
mdsc = kzalloc(sizeof(struct ceph_mds_client), GFP_NOFS); mdsc = kzalloc(sizeof(struct ceph_mds_client), GFP_NOFS);
if (!mdsc) if (!mdsc)
...@@ -4331,8 +4332,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) ...@@ -4331,8 +4332,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
mutex_init(&mdsc->mutex); mutex_init(&mdsc->mutex);
mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
if (!mdsc->mdsmap) { if (!mdsc->mdsmap) {
kfree(mdsc); err = -ENOMEM;
return -ENOMEM; goto err_mdsc;
} }
fsc->mdsc = mdsc; fsc->mdsc = mdsc;
...@@ -4371,6 +4372,9 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) ...@@ -4371,6 +4372,9 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
init_waitqueue_head(&mdsc->cap_flushing_wq); init_waitqueue_head(&mdsc->cap_flushing_wq);
INIT_WORK(&mdsc->cap_reclaim_work, ceph_cap_reclaim_work); INIT_WORK(&mdsc->cap_reclaim_work, ceph_cap_reclaim_work);
atomic_set(&mdsc->cap_reclaim_pending, 0); atomic_set(&mdsc->cap_reclaim_pending, 0);
err = ceph_metric_init(&mdsc->metric);
if (err)
goto err_mdsmap;
spin_lock_init(&mdsc->dentry_list_lock); spin_lock_init(&mdsc->dentry_list_lock);
INIT_LIST_HEAD(&mdsc->dentry_leases); INIT_LIST_HEAD(&mdsc->dentry_leases);
...@@ -4389,6 +4393,12 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) ...@@ -4389,6 +4393,12 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
strscpy(mdsc->nodename, utsname()->nodename, strscpy(mdsc->nodename, utsname()->nodename,
sizeof(mdsc->nodename)); sizeof(mdsc->nodename));
return 0; return 0;
err_mdsmap:
kfree(mdsc->mdsmap);
err_mdsc:
kfree(mdsc);
return err;
} }
/* /*
...@@ -4646,6 +4656,8 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc) ...@@ -4646,6 +4656,8 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
ceph_mdsc_stop(mdsc); ceph_mdsc_stop(mdsc);
ceph_metric_destroy(&mdsc->metric);
fsc->mdsc = NULL; fsc->mdsc = NULL;
kfree(mdsc); kfree(mdsc);
dout("mdsc_destroy %p done\n", mdsc); dout("mdsc_destroy %p done\n", mdsc);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/ceph/mdsmap.h> #include <linux/ceph/mdsmap.h>
#include <linux/ceph/auth.h> #include <linux/ceph/auth.h>
#include "metric.h"
/* The first 8 bits are reserved for old ceph releases */ /* The first 8 bits are reserved for old ceph releases */
enum ceph_feature_type { enum ceph_feature_type {
CEPHFS_FEATURE_MIMIC = 8, CEPHFS_FEATURE_MIMIC = 8,
...@@ -454,6 +456,8 @@ struct ceph_mds_client { ...@@ -454,6 +456,8 @@ struct ceph_mds_client {
struct list_head dentry_leases; /* fifo list */ struct list_head dentry_leases; /* fifo list */
struct list_head dentry_dir_leases; /* lru list */ struct list_head dentry_dir_leases; /* lru list */
struct ceph_client_metric metric;
spinlock_t snapid_map_lock; spinlock_t snapid_map_lock;
struct rb_root snapid_map_tree; struct rb_root snapid_map_tree;
struct list_head snapid_map_lru; struct list_head snapid_map_lru;
......
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/types.h>
#include <linux/percpu_counter.h>
#include "metric.h"
int ceph_metric_init(struct ceph_client_metric *m)
{
int ret;
if (!m)
return -EINVAL;
atomic64_set(&m->total_dentries, 0);
ret = percpu_counter_init(&m->d_lease_hit, 0, GFP_KERNEL);
if (ret)
return ret;
ret = percpu_counter_init(&m->d_lease_mis, 0, GFP_KERNEL);
if (ret) {
percpu_counter_destroy(&m->d_lease_hit);
return ret;
}
return 0;
}
void ceph_metric_destroy(struct ceph_client_metric *m)
{
if (!m)
return;
percpu_counter_destroy(&m->d_lease_mis);
percpu_counter_destroy(&m->d_lease_hit);
}
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _FS_CEPH_MDS_METRIC_H
#define _FS_CEPH_MDS_METRIC_H
#include <linux/types.h>
#include <linux/percpu_counter.h>
/* This is the global metrics */
struct ceph_client_metric {
atomic64_t total_dentries;
struct percpu_counter d_lease_hit;
struct percpu_counter d_lease_mis;
};
extern int ceph_metric_init(struct ceph_client_metric *m);
extern void ceph_metric_destroy(struct ceph_client_metric *m);
#endif /* _FS_CEPH_MDS_METRIC_H */
...@@ -128,6 +128,7 @@ struct ceph_fs_client { ...@@ -128,6 +128,7 @@ struct ceph_fs_client {
struct dentry *debugfs_congestion_kb; struct dentry *debugfs_congestion_kb;
struct dentry *debugfs_bdi; struct dentry *debugfs_bdi;
struct dentry *debugfs_mdsc, *debugfs_mdsmap; struct dentry *debugfs_mdsc, *debugfs_mdsmap;
struct dentry *debugfs_metric;
struct dentry *debugfs_mds_sessions; struct dentry *debugfs_mds_sessions;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment