[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20070626011845.bfd4efe0.akpm@linux-foundation.org>
Date: Tue, 26 Jun 2007 01:18:45 -0700
From: Andrew Morton <akpm@...ux-foundation.org>
To: clameter@....com
Cc: linux-kernel@...r.kernel.org, linux-mm@...ck.org,
Pekka Enberg <penberg@...helsinki.fi>,
suresh.b.siddha@...el.com
Subject: Re: [patch 21/26] Slab defragmentation: support dentry
defragmentation
On Mon, 18 Jun 2007 02:58:59 -0700 clameter@....com wrote:
> get() uses the dcache lock and then works with dget_locked to obtain a
> reference to the dentry. An additional complication is that the dentry
> may be in process of being freed or it may just have been allocated.
> We add an additional flag to d_flags to be able to determined the
> status of an object.
>
> kick() is called after get() has been used and after the slab has dropped
> all of its own locks. The dentry pruning for unused entries works in a
> straighforward way.
>
> ...
>
> +/*
> + * Slab has dropped all the locks. Get rid of the
> + * refcount we obtained earlier and also rid of the
> + * object.
> + */
> +static void kick_dentries(struct kmem_cache *s, int nr, void **v, void *private)
> +{
> + struct dentry *dentry;
> + int abort = 0;
> + int i;
> +
> + /*
> + * First invalidate the dentries without holding the dcache lock
> + */
> + for (i = 0; i < nr; i++) {
> + dentry = v[i];
> +
> + if (dentry)
> + d_invalidate(dentry);
> + }
> +
> + /*
> + * If we are the last one holding a reference then the dentries can
> + * be freed. We need the dcache_lock.
> + */
> + spin_lock(&dcache_lock);
> + for (i = 0; i < nr; i++) {
> + dentry = v[i];
> + if (!dentry)
> + continue;
> +
> + if (abort)
> + goto put_dentry;
> +
> + spin_lock(&dentry->d_lock);
> + if (atomic_read(&dentry->d_count) > 1) {
> + /*
> + * Reference count was increased.
> + * We need to abandon the freeing of
> + * objects.
> + */
> + abort = 1;
It's unobvious why the entire shrink effort is abandoned if one busy dentry
is encountered. Please flesh the comment out explaining this.
> + spin_unlock(&dentry->d_lock);
> +put_dentry:
> + spin_unlock(&dcache_lock);
> + dput(dentry);
> + spin_lock(&dcache_lock);
> + continue;
> + }
> +
> + /* Remove from LRU */
> + if (!list_empty(&dentry->d_lru)) {
> + dentry_stat.nr_unused--;
> + list_del_init(&dentry->d_lru);
> + }
> + /* Drop the entry */
> + prune_one_dentry(dentry, 1);
> + }
> + spin_unlock(&dcache_lock);
> +
> + /*
> + * dentries are freed using RCU so we need to wait until RCU
> + * operations arei complete
> + */
> + if (!abort)
> + synchronize_rcu();
> +}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists