diff -r 78d64822f8bb -r 115e6d42744b usr/src/uts/common/fs/nfs/nfs_server.c --- 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 #include #include +#include #include #include @@ -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);