From 8a444c89182bd0b87c194c2f7eead8ba5f068313 Mon Sep 17 00:00:00 2001
From: Gordon Ross <gwr@nexenta.com>
Date: Wed, 22 Jan 2020 19:46:47 -0500
Subject: [PATCH] Use TSD to reduce zone_getspecific calls

---
 usr/src/uts/common/fs/nfs/nfs3_srv.c   |  2 +-
 usr/src/uts/common/fs/nfs/nfs4_srv.c   |  2 +-
 usr/src/uts/common/fs/nfs/nfs_auth.c   |  2 +-
 usr/src/uts/common/fs/nfs/nfs_export.c |  2 +-
 usr/src/uts/common/fs/nfs/nfs_server.c | 19 ++++++++++++++++---
 usr/src/uts/common/fs/nfs/nfs_srv.c    |  2 +-
 6 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/usr/src/uts/common/fs/nfs/nfs3_srv.c b/usr/src/uts/common/fs/nfs/nfs3_srv.c
index d976300b58..89d65a4d0f 100644
--- a/usr/src/uts/common/fs/nfs/nfs3_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs3_srv.c
@@ -95,7 +95,7 @@ u_longlong_t nfs3_srv_caller_id;
 static nfs3_srv_t *
 nfs3_get_srv(void)
 {
-	nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
+	nfs_globals_t *ng = nfs_srv_getzg();
 	nfs3_srv_t *srv = ng->nfs3_srv;
 	ASSERT(srv != NULL);
 	return (srv);
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv.c b/usr/src/uts/common/fs/nfs/nfs4_srv.c
index 689e167a49..850fe1bbdf 100644
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c
@@ -503,7 +503,7 @@ static const fs_operation_def_t nfs4_wr_deleg_tmpl[] = {
 nfs4_srv_t *
 nfs4_get_srv(void)
 {
-	nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
+	nfs_globals_t *ng = nfs_srv_getzg();
 	nfs4_srv_t *srv = ng->nfs4_srv;
 	ASSERT(srv != NULL);
 	return (srv);
diff --git a/usr/src/uts/common/fs/nfs/nfs_auth.c b/usr/src/uts/common/fs/nfs/nfs_auth.c
index 217808c351..255eb9e5c4 100644
--- a/usr/src/uts/common/fs/nfs/nfs_auth.c
+++ b/usr/src/uts/common/fs/nfs/nfs_auth.c
@@ -178,7 +178,7 @@ static int nfsauth_cache_compar(const void *, const void *);
 static nfsauth_globals_t *
 nfsauth_get_zg(void)
 {
-	nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
+	nfs_globals_t *ng = nfs_srv_getzg();
 	nfsauth_globals_t *nag = ng->nfs_auth;
 	ASSERT(nag != NULL);
 	return (nag);
diff --git a/usr/src/uts/common/fs/nfs/nfs_export.c b/usr/src/uts/common/fs/nfs/nfs_export.c
index 71a111b383..f8744f0ceb 100644
--- a/usr/src/uts/common/fs/nfs/nfs_export.c
+++ b/usr/src/uts/common/fs/nfs/nfs_export.c
@@ -120,7 +120,7 @@ fhandle_t nullfh2;	/* for comparing V2 filehandles */
 extern nfs_export_t *
 nfs_get_export(void)
 {
-	nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
+	nfs_globals_t *ng = nfs_srv_getzg();
 	nfs_export_t *ne = ng->nfs_export;
 	ASSERT(ne != NULL);
 	return (ne);
diff --git a/usr/src/uts/common/fs/nfs/nfs_server.c b/usr/src/uts/common/fs/nfs/nfs_server.c
index 2a59bb4ddc..e4d2269cd2 100644
--- a/usr/src/uts/common/fs/nfs/nfs_server.c
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c
@@ -257,12 +257,23 @@ nvlist_t *rfs4_dss_paths, *rfs4_dss_oldpaths;
 int rfs4_dispatch(struct rpcdisp *, struct svc_req *, SVCXPRT *, char *);
 bool_t rfs4_minorvers_mismatch(struct svc_req *, SVCXPRT *, void *);
 
+/*
+ * Stash NFS zone globals in TSD to avoid some lock contention
+ * from frequent zone_getspecific calls.
+ */
+static uint_t nfs_server_tsd_key;
+
 nfs_globals_t *
 nfs_srv_getzg(void)
 {
 	nfs_globals_t *ng;
 
-	ng = zone_getspecific(nfssrv_zone_key, curzone);
+	ng = tsd_get(nfs_server_tsd_key);
+	if (ng == NULL) {
+		ng = zone_getspecific(nfssrv_zone_key, curzone);
+		(void) tsd_set(nfs_server_tsd_key, ng);
+	}
+
 	return (ng);
 }
 
@@ -1487,8 +1498,8 @@ common_dispatch(struct svc_req *req, SVCXPRT *xprt, rpcvers_t min_vers,
 	char **procnames;
 	char cbuf[INET6_ADDRSTRLEN];	/* to hold both IPv4 and IPv6 addr */
 	bool_t ro = FALSE;
-	nfs_export_t *ne = nfs_get_export();
-	nfs_globals_t *ng = ne->ne_globals;
+	nfs_globals_t *ng = nfs_srv_getzg();
+	nfs_export_t *ne = ng->nfs_export;
 	kstat_named_t *svstat, *procstat;
 
 	ASSERT(req->rq_prog == NFS_PROGRAM || req->rq_prog == NFS_ACL_PROGRAM);
@@ -2565,6 +2576,7 @@ nfs_srvinit(void)
 	rw_init(&nfssrv_globals_rwl, NULL, RW_DEFAULT, NULL);
 	list_create(&nfssrv_globals_list, sizeof (nfs_globals_t),
 	    offsetof (nfs_globals_t, nfs_g_link));
+	tsd_create(&nfs_server_tsd_key, NULL);
 
 	/* The order here is important */
 	nfs_exportinit();
@@ -2604,6 +2616,7 @@ nfs_srvfini(void)
 	nfs_exportfini();
 
 	/* Truly global stuff in this module (not per zone) */
+	tsd_destroy(&nfs_server_tsd_key);
 	list_destroy(&nfssrv_globals_list);
 	rw_destroy(&nfssrv_globals_rwl);
 }
diff --git a/usr/src/uts/common/fs/nfs/nfs_srv.c b/usr/src/uts/common/fs/nfs/nfs_srv.c
index ae51f4ab53..b320f599df 100644
--- a/usr/src/uts/common/fs/nfs/nfs_srv.c
+++ b/usr/src/uts/common/fs/nfs/nfs_srv.c
@@ -115,7 +115,7 @@ u_longlong_t nfs2_srv_caller_id;
 static nfs_srv_t *
 nfs_get_srv(void)
 {
-	nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone);
+	nfs_globals_t *ng = nfs_srv_getzg();
 	nfs_srv_t *srv = ng->nfs_srv;
 	ASSERT(srv != NULL);
 	return (srv);
-- 
2.21.0 (Apple Git-122)

