Le vendredi 05 août 2011 à 04:35 +0400, Glauber Costa a écrit : > Now that we have per-sb shrinkers, it makes sense to have nr_dentries > stored per sb as well. We turn them into per-cpu counters so we can > keep acessing them without locking. > > Signed-off-by: Glauber Costa <glommer@xxxxxxxxxxxxx> > CC: Dave Chinner <david@xxxxxxxxxxxxx> > --- > fs/dcache.c | 12 +++++++++++- > fs/super.c | 15 ++++++++++++++- > include/linux/fs.h | 2 ++ > 3 files changed, 27 insertions(+), 2 deletions(-) > > diff --git a/fs/dcache.c b/fs/dcache.c > index b05aac3..ac19d24 100644 > --- a/fs/dcache.c > +++ b/fs/dcache.c > @@ -151,7 +151,13 @@ static void __d_free(struct rcu_head *head) > static void d_free(struct dentry *dentry) > { > BUG_ON(dentry->d_count); > + /* > + * It is cheaper to keep a global counter separate > + * then to scan through all superblocks when needed "then to scan" or "than scanning" ? > + */ > this_cpu_dec(nr_dentry); > + this_cpu_dec(*dentry->d_sb->s_nr_dentry); > + > if (dentry->d_op && dentry->d_op->d_release) > dentry->d_op->d_release(dentry); > > @@ -1224,7 +1230,11 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) > INIT_LIST_HEAD(&dentry->d_alias); > INIT_LIST_HEAD(&dentry->d_u.d_child); > d_set_d_op(dentry, dentry->d_sb->s_d_op); > - > + /* > + * It is cheaper to keep a global counter separate > + * then to scan through all superblocks when needed > + */ > + this_cpu_inc(*dentry->d_sb->s_nr_dentry); > this_cpu_inc(nr_dentry); > > return dentry; > diff --git a/fs/super.c b/fs/super.c > index 3f56a26..9345385 100644 > --- a/fs/super.c > +++ b/fs/super.c > @@ -112,6 +112,7 @@ static struct super_block *alloc_super(struct file_system_type *type) > { > struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); > static const struct super_operations default_op; > + int i; > > if (s) { > if (security_sb_alloc(s)) { > @@ -119,15 +120,26 @@ static struct super_block *alloc_super(struct file_system_type *type) > s = NULL; > goto out; > } > + > + s->s_nr_dentry = alloc_percpu(int); > + if (!s->s_nr_dentry) { > + security_sb_free(s); > + kfree(s); > + s = NULL; > + goto out; > + } > + for_each_possible_cpu(i) > + *per_cpu_ptr(s->s_nr_dentry, i) = 0; This loop is not needed, alloc_percpu() gives zeroed data Why dont you use a percpu_counter ? -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html