@@ -453,6 +453,7 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose)
*
* Return values:
* %LRU_REMOVED: @item was removed from the LRU
+ * %LRU_ROTATED: @item is to be moved to the LRU tail
* %LRU_SKIP: @item cannot be evicted
*/
static enum lru_status
@@ -491,7 +492,7 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru,
if (test_and_clear_bit(NFSD_FILE_REFERENCED, &nf->nf_flags)) {
trace_nfsd_file_gc_referenced(nf);
- return LRU_SKIP;
+ return LRU_ROTATE;
}
if (!test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
@@ -528,13 +529,14 @@ static void nfsd_file_gc_dispose_list(struct list_head *dispose)
static void
nfsd_file_gc(void)
{
+ unsigned long max = list_lru_count(&nfsd_file_lru);
LIST_HEAD(dispose);
unsigned long ret;
ret = list_lru_walk(&nfsd_file_lru, nfsd_file_lru_cb,
- &dispose, LONG_MAX);
+ &dispose, max);
this_cpu_add(nfsd_file_evictions, ret);
- trace_nfsd_file_gc_evicted(ret, list_lru_count(&nfsd_file_lru));
+ trace_nfsd_file_gc_evicted(ret, max);
nfsd_file_gc_dispose_list(&dispose);
}
Without LRU item rotation, the shrinker visits only a few items on the end of the LRU list, and those would always be long-term OPEN files for NFSv4 workloads. That makes the filecache shrinker completely ineffective. Adopt the same strategy as the inode LRU by using LRU_ROTATE. Suggested-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/filecache.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)