usr/src/uts/common/fs/nfs/nfs_server.c
changeset 8695 115e6d42744b
parent 8395 62c9dba0f531
child 9871 6f02df7ca581
--- a/usr/src/uts/common/fs/nfs/nfs_server.c	Thu Feb 05 11:59:59 2009 -0500
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c	Thu Feb 05 10:03:55 2009 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -70,6 +70,7 @@
 #include <rpc/auth_des.h>
 #include <rpc/svc.h>
 #include <rpc/xdr.h>
+#include <rpc/rpc_rdma.h>
 
 #include <nfs/nfs.h>
 #include <nfs/export.h>
@@ -552,6 +553,8 @@
 {
 	int error;
 	rdma_xprt_group_t started_rdma_xprts;
+	rdma_stat stat;
+	int svc_state = 0;
 
 	/* Double check the vers min/max ranges */
 	if ((rsa->nfs_versmin > rsa->nfs_versmax) ||
@@ -580,15 +583,52 @@
 	started_rdma_xprts.rtg_count = 0;
 	started_rdma_xprts.rtg_listhead = NULL;
 	started_rdma_xprts.rtg_poolid = rsa->poolid;
+
+restart:
 	error = svc_rdma_kcreate(rsa->netid, &nfs_sct_rdma, rsa->poolid,
 	    &started_rdma_xprts);
 
-	if (error == 0) {
-		mutex_enter(&rdma_wait_mutex);
-		if (!cv_wait_sig(&rdma_wait_cv, &rdma_wait_mutex)) {
-			rdma_stop(started_rdma_xprts);
+	svc_state = !error;
+
+	while (!error) {
+
+		/*
+		 * wait till either interrupted by a signal on
+		 * nfs service stop/restart or signalled by a
+		 * rdma plugin attach/detatch.
+		 */
+
+		stat = rdma_kwait();
+
+		/*
+		 * stop services if running -- either on a HCA detach event
+		 * or if the nfs service is stopped/restarted.
+		 */
+
+		if ((stat == RDMA_HCA_DETACH || stat == RDMA_INTR) &&
+		    svc_state) {
+			rdma_stop(&started_rdma_xprts);
+			svc_state = 0;
 		}
-		mutex_exit(&rdma_wait_mutex);
+
+		/*
+		 * nfs service stop/restart, break out of the
+		 * wait loop and return;
+		 */
+		if (stat == RDMA_INTR)
+			return (0);
+
+		/*
+		 * restart stopped services on a HCA attach event
+		 * (if not already running)
+		 */
+
+		if ((stat == RDMA_HCA_ATTACH) && (svc_state == 0))
+			goto restart;
+
+		/*
+		 * loop until a nfs service stop/restart
+		 */
 	}
 
 	return (error);