Slightly reorganise the CPU-intensive hash chain probing to check for more commonly varying entry keys first, and to reduce arithmetic operations by hoisting out an invariant. This slightly reduces the CPU time spent in nfsd_cache_lookup() under heavy nonidempotent loads. This code predates the IPv6 support in the NFS server but should be harmless with IPv6 clients. Signed-off-by: Greg Banks <gnb@xxxxxxx> --- fs/nfsd/nfscache.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) Index: bfields/fs/nfsd/nfscache.c =================================================================== --- bfields.orig/fs/nfsd/nfscache.c +++ bfields/fs/nfsd/nfscache.c @@ -108,6 +108,23 @@ static inline u32 request_hash(u32 xid, return h; } + +/* + * Fast compare of two sockaddr_in's. Ignore the zero padding at + * the end of a sockaddr_in; compares sin_family and sin_port in + * one comparison. Returns 1 if identical, 0 otherwise. + * + * Alignment issues prevent us from comparing all the relevant + * fields in a single 64b comparison on 64b platforms: the most + * we can assume is that sin_addr is 32b-aligned. + */ +static inline int +compare_sockaddr_in(const struct sockaddr_in *sina, const struct sockaddr_in *sinb) +{ + return ((*(u32 *)&sina->sin_family == *(u32 *)&sinb->sin_family) && + (sina->sin_addr.s_addr == sinb->sin_addr.s_addr)); +} + static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); /* @@ -263,12 +280,14 @@ nfsd_cache_lookup(struct svc_rqst *rqstp rtn = RC_DOIT; rh = &b->hash[h]; + age = jiffies - 120*HZ; hlist_for_each_entry(rp, hn, rh, c_hash) { if (rp->c_state != RC_UNUSED && - xid == rp->c_xid && proc == rp->c_proc && + xid == rp->c_xid && + compare_sockaddr_in(svc_addr_in(rqstp), &rp->c_addr) && + proc == rp->c_proc && proto == rp->c_prot && vers == rp->c_vers && - time_before(jiffies, rp->c_timestamp + 120*HZ) && - memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, sizeof(rp->c_addr))==0) { + time_after(rp->c_timestamp, age)) { nfsdstats.rchits++; goto found_entry; } -- Greg -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html