nfsd: don't halt scanning the DRC LRU list when there's an RC_INPROG entry
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / nfsd / nfscache.c
index b6af150..6040da8 100644 (file)
@@ -132,13 +132,6 @@ nfsd_reply_cache_alloc(void)
 }
 
 static void
-nfsd_reply_cache_unhash(struct svc_cacherep *rp)
-{
-       hlist_del_init(&rp->c_hash);
-       list_del_init(&rp->c_lru);
-}
-
-static void
 nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
 {
        if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) {
@@ -231,13 +224,6 @@ hash_refile(struct svc_cacherep *rp)
        hlist_add_head(&rp->c_hash, cache_hash + hash_32(rp->c_xid, maskbits));
 }
 
-static inline bool
-nfsd_cache_entry_expired(struct svc_cacherep *rp)
-{
-       return rp->c_state != RC_INPROG &&
-              time_after(jiffies, rp->c_timestamp + RC_EXPIRE);
-}
-
 /*
  * Walk the LRU list and prune off entries that are older than RC_EXPIRE.
  * Also prune the oldest ones when the total exceeds the max number of entries.
@@ -249,8 +235,14 @@ prune_cache_entries(void)
        long freed = 0;
 
        list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) {
-               if (!nfsd_cache_entry_expired(rp) &&
-                   num_drc_entries <= max_drc_entries)
+               /*
+                * Don't free entries attached to calls that are still
+                * in-progress, but do keep scanning the list.
+                */
+               if (rp->c_state == RC_INPROG)
+                       continue;
+               if (num_drc_entries <= max_drc_entries &&
+                   time_before(jiffies, rp->c_timestamp + RC_EXPIRE))
                        break;
                nfsd_reply_cache_free_locked(rp);
                freed++;
@@ -416,22 +408,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
 
        /*
         * Since the common case is a cache miss followed by an insert,
-        * preallocate an entry. First, try to reuse the first entry on the LRU
-        * if it works, then go ahead and prune the LRU list.
+        * preallocate an entry.
         */
-       spin_lock(&cache_lock);
-       if (!list_empty(&lru_head)) {
-               rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
-               if (nfsd_cache_entry_expired(rp) ||
-                   num_drc_entries >= max_drc_entries) {
-                       nfsd_reply_cache_unhash(rp);
-                       prune_cache_entries();
-                       goto search_cache;
-               }
-       }
-
-       /* No expired ones available, allocate a new one. */
-       spin_unlock(&cache_lock);
        rp = nfsd_reply_cache_alloc();
        spin_lock(&cache_lock);
        if (likely(rp)) {
@@ -439,7 +417,9 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
                drc_mem_usage += sizeof(*rp);
        }
 
-search_cache:
+       /* go ahead and prune the cache */
+       prune_cache_entries();
+
        found = nfsd_cache_search(rqstp, csum);
        if (found) {
                if (likely(rp))
@@ -453,15 +433,6 @@ search_cache:
                goto out;
        }
 
-       /*
-        * We're keeping the one we just allocated. Are we now over the
-        * limit? Prune one off the tip of the LRU in trade for the one we
-        * just allocated if so.
-        */
-       if (num_drc_entries >= max_drc_entries)
-               nfsd_reply_cache_free_locked(list_first_entry(&lru_head,
-                                               struct svc_cacherep, c_lru));
-
        nfsdstats.rcmisses++;
        rqstp->rq_cacherep = rp;
        rp->c_state = RC_INPROG;