From: jblunck@suse.de
To: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org, akpm@osdl.org,
viro@zeniv.linux.org.uk, dgc@sgi.com, balbir@in.ibm.com,
neilb@suse.de
Subject: [PATCH 4/5] vfs: per superblock dentry stats
Date: Fri, 16 Jun 2006 12:43:25 +0200 [thread overview]
Message-ID: <20060616104322.598112000@hasse.suse.de> (raw)
In-Reply-To: 20060616104321.778718000@hasse.suse.de
[-- Attachment #1: patches.jbl/vfs-per-sb-dentry_stat.diff --]
[-- Type: text/plain, Size: 8278 bytes --]
This patch adds per superblock dentry statistics about unused and absolute
number of dentries.
Signed-off-by: Jan Blunck <jblunck@suse.de>
---
fs/dcache.c | 47 ++++++++++++++++++++++++++---------------------
fs/super.c | 1 +
include/linux/dcache.h | 21 +++++++++++++++++----
include/linux/fs.h | 1 +
kernel/sysctl.c | 2 +-
5 files changed, 46 insertions(+), 26 deletions(-)
Index: work-2.6/fs/dcache.c
===================================================================
--- work-2.6.orig/fs/dcache.c
+++ work-2.6/fs/dcache.c
@@ -64,7 +64,7 @@ static struct hlist_head *dentry_hashtab
static LIST_HEAD(dentry_unused);
/* Statistics gathering. */
-struct dentry_stat_t dentry_stat = {
+struct dentry_stat global_dentry_stat = {
.age_limit = 45,
};
@@ -173,7 +173,7 @@ repeat:
if (list_empty(&dentry->d_lru)) {
dentry->d_flags |= DCACHE_REFERENCED;
list_add(&dentry->d_lru, &dentry_unused);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(dentry->d_sb, nr_unused);
}
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
@@ -190,11 +190,13 @@ kill_it: {
*/
if (!list_empty(&dentry->d_lru)) {
list_del(&dentry->d_lru);
- dentry_stat.nr_unused--;
+ dentry_stat_dec(dentry->d_sb, nr_unused);
}
list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
- /*drops the locks, at that point nobody can reach this dentry */
+ /* For d_free, below */
+ dentry_stat_dec(dentry->d_sb, nr_dentry);
+ /* drops the locks, at that point nobody can reach this
+ * dentry anymore */
dentry_iput(dentry);
parent = dentry->d_parent;
d_free(dentry);
@@ -268,7 +270,7 @@ static inline struct dentry * __dget_loc
{
atomic_inc(&dentry->d_count);
if (!list_empty(&dentry->d_lru)) {
- dentry_stat.nr_unused--;
+ dentry_stat_dec(dentry->d_sb, nr_unused);
list_del_init(&dentry->d_lru);
}
return dentry;
@@ -370,7 +372,7 @@ static inline void prune_one_dentry(stru
__d_drop(dentry);
list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
+ dentry_stat_dec(dentry->d_sb, nr_dentry); /* For d_free, below */
dentry_iput(dentry);
parent = dentry->d_parent;
d_free(dentry);
@@ -403,10 +405,10 @@ static void prune_dcache(int count)
tmp = dentry_unused.prev;
if (tmp == &dentry_unused)
break;
- list_del_init(tmp);
prefetch(dentry_unused.prev);
- dentry_stat.nr_unused--;
dentry = list_entry(tmp, struct dentry, d_lru);
+ dentry_stat_dec(dentry->d_sb, nr_unused);
+ list_del_init(&dentry->d_lru);
spin_lock(&dentry->d_lock);
/*
@@ -422,7 +424,7 @@ static void prune_dcache(int count)
if (dentry->d_flags & DCACHE_REFERENCED) {
dentry->d_flags &= ~DCACHE_REFERENCED;
list_add(&dentry->d_lru, &dentry_unused);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(dentry->d_sb, nr_unused);
spin_unlock(&dentry->d_lock);
continue;
}
@@ -444,7 +446,7 @@ static void select_anon(struct super_blo
spin_lock(&dcache_lock);
hlist_for_each_entry(dentry, lp, &sb->s_anon, d_hash) {
if (!list_empty(&dentry->d_lru)) {
- dentry_stat.nr_unused--;
+ dentry_stat_dec(sb, nr_unused);
list_del_init(&dentry->d_lru);
}
@@ -455,7 +457,7 @@ static void select_anon(struct super_blo
spin_lock(&dentry->d_lock);
if (!atomic_read(&dentry->d_count)) {
list_add(&dentry->d_lru, &dentry_unused);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(sb, nr_unused);
}
spin_unlock(&dentry->d_lock);
}
@@ -519,7 +521,7 @@ repeat:
dentry = list_entry(tmp, struct dentry, d_lru);
if (dentry->d_sb != sb)
continue;
- dentry_stat.nr_unused--;
+ dentry_stat_dec(sb, nr_unused);
list_del_init(tmp);
spin_lock(&dentry->d_lock);
if (atomic_read(&dentry->d_count)) {
@@ -615,7 +617,7 @@ resume:
next = tmp->next;
if (!list_empty(&dentry->d_lru)) {
- dentry_stat.nr_unused--;
+ dentry_stat_dec(dentry->d_sb, nr_unused);
list_del_init(&dentry->d_lru);
}
/*
@@ -624,7 +626,7 @@ resume:
*/
if (!atomic_read(&dentry->d_count)) {
list_add(&dentry->d_lru, dentry_unused.prev);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(dentry->d_sb, nr_unused);
found++;
}
@@ -691,7 +693,7 @@ static int shrink_dcache_memory(int nr,
return -1;
prune_dcache(nr);
}
- return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
+ return (global_dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
/**
@@ -756,7 +758,7 @@ struct dentry *d_alloc(struct dentry * p
spin_lock(&dcache_lock);
if (parent)
list_add(&dentry->d_u.d_child, &parent->d_subdirs);
- dentry_stat.nr_dentry++;
+ dentry_stat_inc(dentry->d_sb, nr_dentry);
spin_unlock(&dcache_lock);
return dentry;
@@ -932,6 +934,9 @@ struct dentry * d_alloc_anon(struct inod
tmp = NULL;
spin_lock(&res->d_lock);
res->d_sb = inode->i_sb;
+ /* Add to the sb dentry_stat here only,
+ * the global data is updated in d_alloc */
+ res->d_sb->s_dentry_stat.nr_dentry++;
res->d_parent = res;
res->d_inode = inode;
res->d_flags |= DCACHE_DISCONNECTED;
@@ -1613,23 +1618,23 @@ resume:
goto repeat;
}
if (!list_empty(&dentry->d_lru)) {
- dentry_stat.nr_unused--;
+ dentry_stat_dec(dentry->d_sb, nr_unused);
list_del_init(&dentry->d_lru);
}
if (atomic_dec_and_test(&dentry->d_count)) {
list_add(&dentry->d_lru, dentry_unused.prev);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(dentry->d_sb, nr_unused);
}
}
if (this_parent != root) {
next = this_parent->d_u.d_child.next;
if (!list_empty(&this_parent->d_lru)) {
- dentry_stat.nr_unused--;
+ dentry_stat_dec(this_parent->d_sb, nr_unused);
list_del_init(&this_parent->d_lru);
}
if (atomic_dec_and_test(&this_parent->d_count)) {
list_add(&this_parent->d_lru, dentry_unused.prev);
- dentry_stat.nr_unused++;
+ dentry_stat_inc(this_parent->d_sb, nr_unused);
}
this_parent = this_parent->d_parent;
goto resume;
Index: work-2.6/fs/super.c
===================================================================
--- work-2.6.orig/fs/super.c
+++ work-2.6/fs/super.c
@@ -71,6 +71,7 @@ static struct super_block *alloc_super(v
INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes);
+ s->s_dentry_stat.age_limit = 45;
init_rwsem(&s->s_umount);
mutex_init(&s->s_lock);
down_write(&s->s_umount);
Index: work-2.6/include/linux/dcache.h
===================================================================
--- work-2.6.orig/include/linux/dcache.h
+++ work-2.6/include/linux/dcache.h
@@ -36,14 +36,27 @@ struct qstr {
const unsigned char *name;
};
-struct dentry_stat_t {
+struct dentry_stat {
int nr_dentry;
int nr_unused;
- int age_limit; /* age in seconds */
- int want_pages; /* pages requested by system */
+ int age_limit; /* age in seconds */
int dummy[2];
};
-extern struct dentry_stat_t dentry_stat;
+extern struct dentry_stat global_dentry_stat;
+
+#define dentry_stat_inc(sb, x) \
+do { \
+ global_dentry_stat.x++; \
+ if (likely(sb)) \
+ (sb)->s_dentry_stat.x++;\
+} while(0)
+
+#define dentry_stat_dec(sb, x) \
+do { \
+ global_dentry_stat.x--; \
+ if (likely(sb)) \
+ (sb)->s_dentry_stat.x--;\
+} while(0)
/* Name hashing routines. Initial hash value */
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
Index: work-2.6/include/linux/fs.h
===================================================================
--- work-2.6.orig/include/linux/fs.h
+++ work-2.6/include/linux/fs.h
@@ -847,6 +847,7 @@ struct super_block {
struct list_head s_io; /* parked for writeback */
struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_files;
+ struct dentry_stat s_dentry_stat;
struct block_device *s_bdev;
struct list_head s_instances;
Index: work-2.6/kernel/sysctl.c
===================================================================
--- work-2.6.orig/kernel/sysctl.c
+++ work-2.6/kernel/sysctl.c
@@ -958,7 +958,7 @@ static ctl_table fs_table[] = {
{
.ctl_name = FS_DENTRY,
.procname = "dentry-state",
- .data = &dentry_stat,
+ .data = &global_dentry_stat,
.maxlen = 6*sizeof(int),
.mode = 0444,
.proc_handler = &proc_dointvec,
next prev parent reply other threads:[~2006-06-16 10:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-06-16 10:43 [PATCH 0/5] vfs: per-superblock unused dentries list (3rd version) jblunck
2006-06-16 10:43 ` [PATCH 1/5] vfs: remove whitespace noise from fs/dcache.c jblunck
2006-06-16 10:43 ` [PATCH 2/5] vfs: d_genocide() doesnt add dentries to unused list jblunck
2006-06-18 19:34 ` Balbir Singh
2006-06-19 9:22 ` Jan Blunck
2006-06-19 10:38 ` Balbir Singh
2006-06-16 10:43 ` [PATCH 3/5] vfs: remove shrink_dcache_anon() jblunck
2006-06-16 10:43 ` jblunck [this message]
2006-06-16 10:43 ` [PATCH 5/5] vfs: per superblock dentry unused list jblunck
-- strict thread matches above, loose matches on Subject: below --
2006-06-01 9:51 [patch 0/5] [PATCH,RFC] vfs: per-superblock unused dentries list (2nd version) jblunck
2006-06-01 9:51 ` [patch 4/5] vfs: per superblock dentry stats jblunck
[not found] <20060526110655.197949000@suse.de>
[not found] ` <20060526110802.852609000@suse.de>
2006-05-29 2:24 ` David Chinner
2006-05-29 9:43 ` Jan Blunck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060616104322.598112000@hasse.suse.de \
--to=jblunck@suse.de \
--cc=akpm@osdl.org \
--cc=balbir@in.ibm.com \
--cc=dgc@sgi.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=neilb@suse.de \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).