public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@poochiereds.net>
To: Dave Chinner <david@fromorbit.com>
Cc: bfields@fieldses.org, linux-nfs@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, Al Viro <viro@ZenIV.linux.org.uk>
Subject: Re: [PATCH v5 01/20] list_lru: add list_lru_rotate
Date: Tue, 6 Oct 2015 07:43:41 -0400	[thread overview]
Message-ID: <20151006074341.0e2f796e@tlielax.poochiereds.net> (raw)
In-Reply-To: <20151005214717.GC23350@dastard>

On Tue, 6 Oct 2015 08:47:17 +1100
Dave Chinner <david@fromorbit.com> wrote:

> On Mon, Oct 05, 2015 at 07:02:23AM -0400, Jeff Layton wrote:
> > Add a function that can move an entry to the MRU end of the list.
> > 
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: linux-mm@kvack.org
> > Reviewed-by: Vladimir Davydov <vdavydov@parallels.com>
> > Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
> 
> Having read through patch 10 (nfsd: add a new struct file caching
> facility to nfsd) that uses this function, I think it is unnecessary
> as it's usage is incorrect from the perspective of the list_lru
> shrinker management.
> 
> What you are attempting to do is rotate the object to the tail of
> the LRU when the last reference is dropped, so that it gets a full
> trip through the LRU before being reclaimed by the shrinker. And to
> ensure this "works", the scan from the shrinker checks for reference
> counts and skip the item being isolated (i.e. return LRU_SKIP) and
> so leave it in it's place in the LRU.
> 
> i.e. you're attempting to manage LRU-ness of the list yourself when,
> in fact, the list_lru infrastructure does this and doesn't have the
> subtle bugs your version has. By trying to manage it yourself, the
> list_lru lists are no longer sorted into memory pressure driven
> LRU order.
> 
> e.g. your manual rotation technique means if there are nr_to_walk
> referenced items at the head of the list, the shrinker will skip
> them all and do nothing, even though there are reclaimable objects
> further down the list. i.e. it can't do any reclaim because it
> doesn't sort the list into LRU order any more.
> 
> This comes from using LRU_SKIP improperly. LRU_SKIP is there for
> objects that we can't lock in the isolate callback due to lock
> inversion issues (e.g. see dentry_lru_isolate()), and so we need to
> look at it again on the next scan pass. hence it gets left in place.
> 
> However, if we can lock the item and peer at it's reference counts
> safely and we decide that we cannot reclaim it because it is
> referenced, the isolate callback should be returning LRU_ROTATE
> to move the referenced item to the tail of the list. (Again, see
> dentry_lru_isolate() for an example.) The means that
> the next nr_to_walk scan of the list will not rescan that item and
> skip it again (unless the list is very short), but will instead scan
> items that it hasn't yet reached.
> 
> This avoids the "shrinker does nothing due to skipped items at the
> head of the list" problem, and makes the LRU function as an actual
> LRU. i.e.  referenced items all cluster towards the tail of the LRU
> under memory pressure and the head of the LRU contains the
> reclaimable objects.
> 
> So I think the correct solution is to use LRU_ROTATE correctly
> rather than try to manage the LRU list order externally like this.
> 

Thanks for looking, Dave. Ok, fair enough.

I grafted the LRU list stuff on after I did the original set, and I
think the way I designed the refcounting doesn't really work very well
with it. It has been a while since I added that in, but I do remember
struggling a bit with lock inversion problems trying to do it the more
standard way. It's solvable with a nfsd_file spinlock, but I wanted
to avoid that -- still maybe it's the best way.

What I don't quite get conceptually is how the list_lru stuff really
works...

Looking at the dcache's usage, dentry_lru_add is only called from dput
and only removed from the list when you're shrinking the dcache or from
__dentry_kill. It will rotate entries to the end of the list via
LRU_ROTATE from the shrinker callback if DCACHE_REFERENCED was set, but
I don't see how you end up with stuff at the end of the list otherwise.

So, the dcache's LRU list doesn't really seem to keep the entries in LRU
order at all. It just prunes a number of entries that haven't been used
since the last time the shrinker callback was called, and the rest end
up staying on the list in whatever order they were originally added.

So...

dentry1			dentry2
allocated
dput
			allocated
			dput

found
dput again
(maybe many more times)

Now, the shrinker runs once and skips both because DCACHE_REFERENCED is
set. It then runs again later and prunes dentry1 before dentry2 even
though it has been used many more times since dentry2 has.

Am I missing something in how this works?
-- 
Jeff Layton <jlayton@poochiereds.net>

  reply	other threads:[~2015-10-06 11:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-05 11:02 [PATCH v5 00/20] nfsd: open file caching Jeff Layton
2015-10-05 11:02 ` [PATCH v5 01/20] list_lru: add list_lru_rotate Jeff Layton
2015-10-05 21:47   ` Dave Chinner
2015-10-06 11:43     ` Jeff Layton [this message]
2015-10-07  1:09       ` Dave Chinner
2015-10-05 11:02 ` [PATCH v5 02/20] fs: have flush_delayed_fput flush the workqueue job Jeff Layton
2015-10-05 11:02 ` [PATCH v5 03/20] fs: add a kerneldoc header to fput Jeff Layton
2015-10-05 11:02 ` [PATCH v5 04/20] fs: add fput_queue Jeff Layton
2015-10-05 11:02 ` [PATCH v5 05/20] fs: export flush_delayed_fput Jeff Layton
2015-10-05 11:02 ` [PATCH v5 06/20] fsnotify: export several symbols Jeff Layton
2015-10-05 11:02 ` [PATCH v5 07/20] locks: create a new notifier chain for lease attempts Jeff Layton
2015-10-05 11:02 ` [PATCH v5 08/20] nfsd: move include of state.h from trace.c to trace.h Jeff Layton
2015-10-05 11:02 ` [PATCH v5 09/20] sunrpc: add a new cache_detail operation for when a cache is flushed Jeff Layton
2015-10-05 11:02 ` [PATCH v5 10/20] nfsd: add a new struct file caching facility to nfsd Jeff Layton
2015-10-05 11:02 ` [PATCH v5 11/20] nfsd: keep some rudimentary stats on nfsd_file cache Jeff Layton
2015-10-05 11:02 ` [PATCH v5 12/20] nfsd: allow filecache open to skip fh_verify check Jeff Layton
2015-10-05 11:02 ` [PATCH v5 13/20] nfsd: hook up nfsd_write to the new nfsd_file cache Jeff Layton
2015-10-05 11:02 ` [PATCH v5 14/20] nfsd: hook up nfsd_read to the " Jeff Layton
2015-10-05 11:02 ` [PATCH v5 15/20] nfsd: hook nfsd_commit up " Jeff Layton
2015-10-05 11:02 ` [PATCH v5 16/20] nfsd: convert nfs4_file->fi_fds array to use nfsd_files Jeff Layton
2015-10-05 11:02 ` [PATCH v5 17/20] nfsd: have nfsd_test_lock use the nfsd_file cache Jeff Layton
2015-10-05 11:02 ` [PATCH v5 18/20] nfsd: convert fi_deleg_file and ls_file fields to nfsd_file Jeff Layton
2015-10-05 11:02 ` [PATCH v5 19/20] nfsd: hook up nfs4_preprocess_stateid_op to the nfsd_file cache Jeff Layton
2015-10-05 11:02 ` [PATCH v5 20/20] nfsd: rip out the raparms cache Jeff Layton
2015-10-08 16:42 ` [PATCH v5 00/20] nfsd: open file caching J. Bruce Fields
2015-10-08 16:55   ` Jeff Layton
2015-10-08 18:04     ` J. Bruce Fields
2015-10-10 11:19       ` Jeff Layton
2015-10-10 13:48         ` J. Bruce Fields

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=20151006074341.0e2f796e@tlielax.poochiereds.net \
    --to=jlayton@poochiereds.net \
    --cc=bfields@fieldses.org \
    --cc=david@fromorbit.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --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