summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfs
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-01-03 15:09:59 +0000
committermav <mav@FreeBSD.org>2014-01-03 15:09:59 +0000
commitd75fe782e9f66e5daa9ee5ad39eecc2be925db47 (patch)
tree41fae690ab667a8b53a31423d51d2ff36ca697a6 /sys/fs/nfs
parent4d725b0decffd3025cc73d299156cafb82885d99 (diff)
downloadFreeBSD-src-d75fe782e9f66e5daa9ee5ad39eecc2be925db47.zip
FreeBSD-src-d75fe782e9f66e5daa9ee5ad39eecc2be925db47.tar.gz
Rework NFS Duplicate Request Cache cleanup logic.
- Introduce additional hash to group requests by hash of sockref. This allows to process TCP acknowledgements without looping though all the cache, and as result allows to do it every time. - Indroduce additional callbacks to notify application layer about sockets disconnection. Without this last few requests processed just before socket disconnection never processed their ACKs and stuck in cache for many hours. - Implement transport-specific method for tracking reply acknowledgements. New implementation does not cross multiple stack layers to get the data and does not have race conditions that previously made some requests stuck in cache. This could be done more efficiently at sockbuf layer, but that would broke some KBIs, while I don't know other consumers for it aside NFS. - Instead of traversing all DRC twice per request, run cleaning only once per request, and except in some conditions traverse only single hash slot at a time. Together this limits NFS DRC growth only to situations of real connectivity problems. If network is working well, and so all replies are acknowledged, cache remains almost empty even after hours of heavy load. Without this change on the same test cache was growing to many thousand requests even with perfectly working local network. As another result this reduces CPU time spent on the DRC handling during SPEC NFS benchmark from about 10% to 0.5%. Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r--sys/fs/nfs/nfs_var.h11
-rw-r--r--sys/fs/nfs/nfsrvcache.h10
2 files changed, 13 insertions, 8 deletions
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 7fbabaa..71daeaf 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -218,14 +218,14 @@ void nfsrvd_dorpc(struct nfsrv_descript *, int, NFSPROC_T *);
/* nfs_nfsdcache.c */
void nfsrvd_initcache(void);
-int nfsrvd_getcache(struct nfsrv_descript *, struct socket *);
-struct nfsrvcache *nfsrvd_updatecache(struct nfsrv_descript *,
- struct socket *);
-void nfsrvd_sentcache(struct nfsrvcache *, struct socket *, int);
+int nfsrvd_getcache(struct nfsrv_descript *);
+struct nfsrvcache *nfsrvd_updatecache(struct nfsrv_descript *);
+void nfsrvd_sentcache(struct nfsrvcache *, uint32_t);
void nfsrvd_cleancache(void);
void nfsrvd_refcache(struct nfsrvcache *);
void nfsrvd_derefcache(struct nfsrvcache *);
void nfsrvd_delcache(struct nfsrvcache *);
+void nfsrc_trimcache(uint64_t, uint32_t, int);
/* nfs_commonsubs.c */
void newnfs_init(void);
@@ -327,9 +327,6 @@ int nfsd_checkrootexp(struct nfsrv_descript *);
void nfscl_retopts(struct nfsmount *, char *, size_t);
/* nfs_commonport.c */
-int nfsrv_checksockseqnum(struct socket *, tcp_seq);
-int nfsrv_getsockseqnum(struct socket *, tcp_seq *);
-int nfsrv_getsocksndseq(struct socket *, tcp_seq *, tcp_seq *);
int nfsrv_lookupfilename(struct nameidata *, char *, NFSPROC_T *);
void nfsrv_object_create(vnode_t, NFSPROC_T *);
int nfsrv_mallocmget_limit(void);
diff --git a/sys/fs/nfs/nfsrvcache.h b/sys/fs/nfs/nfsrvcache.h
index 5c9dc57..7db3035 100644
--- a/sys/fs/nfs/nfsrvcache.h
+++ b/sys/fs/nfs/nfsrvcache.h
@@ -46,6 +46,7 @@
/* Cache table entry. */
struct nfsrvcache {
LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */
+ LIST_ENTRY(nfsrvcache) rc_ahash; /* ACK hash chain */
TAILQ_ENTRY(nfsrvcache) rc_lru; /* UDP lru chain */
u_int32_t rc_xid; /* rpc id number */
time_t rc_timestamp; /* Time done */
@@ -64,6 +65,7 @@ struct nfsrvcache {
int16_t refcnt;
u_int16_t cksum;
time_t cachetime;
+ int acked;
} ot;
} rc_un2;
u_int16_t rc_proc; /* rpc proc number */
@@ -81,6 +83,13 @@ struct nfsrvcache {
#define rc_reqlen rc_un2.ot.len
#define rc_cksum rc_un2.ot.cksum
#define rc_cachetime rc_un2.ot.cachetime
+#define rc_acked rc_un2.ot.acked
+
+/* TCP ACK values */
+#define RC_NO_SEQ 0
+#define RC_NO_ACK 1
+#define RC_ACK 2
+#define RC_NACK 3
/* Return values */
#define RC_DROPIT 0
@@ -95,7 +104,6 @@ struct nfsrvcache {
#define RC_UDP 0x0010
#define RC_INETIPV6 0x0020
#define RC_INPROG 0x0040
-#define RC_TCPSEQ 0x0080
#define RC_NFSV2 0x0100
#define RC_NFSV3 0x0200
#define RC_NFSV4 0x0400
OpenPOWER on IntegriCloud