lkml.org 
[lkml]   [2006]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] Per-superblock unused dentry LRU lists V3
    > David Chinner <dgc@sgi.com> wrote:
    >
    > +/*
    > + * Shrink the dentry LRU on a given superblock.
    > + *
    > + * If flags is non-zero, we need to do special processing based on
    > + * which flags are set. This means we don't need to maintain multiple
    > + * similar copies of this loop.
    > + */
    > +static void __shrink_dcache_sb(struct super_block *sb, int *count, int
    > flags)
    > +{
    > + struct dentry *dentry;
    > + int cnt = *count;
    > +
    > + spin_lock(&dcache_lock);
    > + while (!list_empty(&sb->s_dentry_lru) && cnt--) {
    > + dentry = list_entry(sb->s_dentry_lru.prev,
    > + struct dentry, d_lru);
    > + dentry_lru_del_init(dentry);
    > + BUG_ON(dentry->d_sb != sb);
    > + prefetch(sb->s_dentry_lru.prev);
    > +
    > + spin_lock(&dentry->d_lock);
    > + /*
    > + * We found an inuse dentry which was not removed from
    > + * the LRU because of laziness during lookup. Do not free
    > + * it - just keep it off the LRU list.
    > + */
    > + if (atomic_read(&dentry->d_count)) {
    > + spin_unlock(&dentry->d_lock);
    > + continue;
    > + }
    > + /*
    > + * If we are honouring the DCACHE_REFERENCED flag and the
    > + * dentry has this flag set, don't free it. Clear the flag
    > + * and put it back on the LRU
    > + */
    > + if ((flags & DCACHE_REFERENCED) &&
    > + (dentry->d_flags & DCACHE_REFERENCED)) {
    > + dentry->d_flags &= ~DCACHE_REFERENCED;
    > + dentry_lru_add(dentry);
    > + spin_unlock(&dentry->d_lock);
    > + continue;
    > + }
    > + prune_one_dentry(dentry);
    > + }
    > + spin_unlock(&dcache_lock);
    > + *count = cnt;
    > +}
    > +
    > /**
    > * shrink_dcache_sb - shrink dcache for a superblock
    > * @sb: superblock
    > @@ -507,44 +529,9 @@ static void prune_dcache(int count, stru
    > * is used to free the dcache before unmounting a file
    > * system
    > */
    > -
    > void shrink_dcache_sb(struct super_block * sb)
    > {
    > - struct list_head *tmp, *next;
    > - struct dentry *dentry;
    > -
    > - /*
    > - * Pass one ... move the dentries for the specified
    > - * superblock to the most recent end of the unused list.
    > - */
    > - spin_lock(&dcache_lock);
    > - list_for_each_safe(tmp, next, &dentry_unused) {
    > - dentry = list_entry(tmp, struct dentry, d_lru);
    > - if (dentry->d_sb != sb)
    > - continue;
    > - list_move(tmp, &dentry_unused);
    > - }
    > -
    > - /*
    > - * Pass two ... free the dentries for this superblock.
    > - */
    > -repeat:
    > - list_for_each_safe(tmp, next, &dentry_unused) {
    > - dentry = list_entry(tmp, struct dentry, d_lru);
    > - if (dentry->d_sb != sb)
    > - continue;
    > - dentry_stat.nr_unused--;
    > - list_del_init(tmp);
    > - spin_lock(&dentry->d_lock);
    > - if (atomic_read(&dentry->d_count)) {
    > - spin_unlock(&dentry->d_lock);
    > - continue;
    > - }
    > - prune_one_dentry(dentry);
    > - cond_resched_lock(&dcache_lock);
    > - goto repeat;
    > - }
    > - spin_unlock(&dcache_lock);
    > + __shrink_dcache_sb(sb, &sb->s_dentry_lru_nr, 0);
    > }

    This doesn't prune all the dentries on the unused list. The parents of the
    pruned dentries are added to the unused list. Therefore just shrinking
    sb->s_dentry_lru_nr dentries isn't enough.

    Jan
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-05-30 17:07    [W:0.027 / U:62.228 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site