OSDN Git Service

knfsd: Further simplify the cache lookup
authorTrond Myklebust <trondmy@gmail.com>
Wed, 3 Oct 2018 17:11:51 +0000 (13:11 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 29 Oct 2018 20:58:04 +0000 (16:58 -0400)
Order the structure so that the key can be compared using memcmp().

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/cache.h
fs/nfsd/nfscache.c

index b7559c6..745c861 100644 (file)
  * is much larger than a sockaddr_in6.
  */
 struct svc_cacherep {
-       struct list_head        c_lru;
+       struct {
+               /* Keep often-read xid, csum in the same cache line: */
+               __be32                  k_xid;
+               __wsum                  k_csum;
+               u32                     k_proc;
+               u32                     k_prot;
+               u32                     k_vers;
+               unsigned int            k_len;
+               struct sockaddr_in6     k_addr;
+       } c_key;
 
+       struct list_head        c_lru;
        unsigned char           c_state,        /* unused, inprog, done */
                                c_type,         /* status, buffer */
                                c_secure : 1;   /* req came from port < 1024 */
-       struct sockaddr_in6     c_addr;
-       __be32                  c_xid;
-       u32                     c_prot;
-       u32                     c_proc;
-       u32                     c_vers;
-       unsigned int            c_len;
-       __wsum                  c_csum;
        unsigned long           c_timestamp;
        union {
                struct kvec     u_vec;
index 527ce4c..230cc83 100644 (file)
@@ -131,15 +131,15 @@ nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum)
                rp->c_type = RC_NOCACHE;
                INIT_LIST_HEAD(&rp->c_lru);
 
-               rp->c_xid = rqstp->rq_xid;
-               rp->c_proc = rqstp->rq_proc;
-               memset(&rp->c_addr, 0, sizeof(rp->c_addr));
-               rpc_copy_addr((struct sockaddr *)&rp->c_addr, svc_addr(rqstp));
-               rpc_set_port((struct sockaddr *)&rp->c_addr, rpc_get_port(svc_addr(rqstp)));
-               rp->c_prot = rqstp->rq_prot;
-               rp->c_vers = rqstp->rq_vers;
-               rp->c_len = rqstp->rq_arg.len;
-               rp->c_csum = csum;
+               memset(&rp->c_key, 0, sizeof(rp->c_key));
+               rp->c_key.k_xid = rqstp->rq_xid;
+               rp->c_key.k_proc = rqstp->rq_proc;
+               rpc_copy_addr((struct sockaddr *)&rp->c_key.k_addr, svc_addr(rqstp));
+               rpc_set_port((struct sockaddr *)&rp->c_key.k_addr, rpc_get_port(svc_addr(rqstp)));
+               rp->c_key.k_prot = rqstp->rq_prot;
+               rp->c_key.k_vers = rqstp->rq_vers;
+               rp->c_key.k_len = rqstp->rq_arg.len;
+               rp->c_key.k_csum = csum;
        }
        return rp;
 }
@@ -330,27 +330,14 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
        return csum;
 }
 
-static bool
-nfsd_cache_match(const struct svc_cacherep *key, const struct svc_cacherep *rp)
+static int
+nfsd_cache_key_cmp(const struct svc_cacherep *key, const struct svc_cacherep *rp)
 {
-       /* Check RPC XID first */
-       if (key->c_xid != rp->c_xid)
-               return false;
-       /* compare checksum of NFS data */
-       if (key->c_csum != rp->c_csum) {
+       if (key->c_key.k_xid == rp->c_key.k_xid &&
+           key->c_key.k_csum != rp->c_key.k_csum)
                ++payload_misses;
-               return false;
-       }
-
-       /* Other discriminators */
-       if (key->c_proc != rp->c_proc ||
-           key->c_prot != rp->c_prot ||
-           key->c_vers != rp->c_vers ||
-           key->c_len != rp->c_len ||
-           memcmp(&key->c_addr, &rp->c_addr, sizeof(key->c_addr)) != 0)
-               return false;
 
-       return true;
+       return memcmp(&key->c_key, &rp->c_key, sizeof(key->c_key));
 }
 
 /*
@@ -367,7 +354,7 @@ nfsd_cache_insert(struct nfsd_drc_bucket *b, struct svc_cacherep *key)
 
        list_for_each_entry(rp, rh, c_lru) {
                ++entries;
-               if (nfsd_cache_match(key, rp)) {
+               if (nfsd_cache_key_cmp(key, rp) == 0) {
                        ret = rp;
                        break;
                }
@@ -510,7 +497,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
        if (!rp)
                return;
 
-       hash = nfsd_cache_hash(rp->c_xid);
+       hash = nfsd_cache_hash(rp->c_key.k_xid);
        b = &drc_hashtbl[hash];
 
        len = resv->iov_len - ((char*)statp - (char*)resv->iov_base);