Whamcloud - gitweb
LU-4588 code: replace semaphores with mutexes
[fs/lustre-release.git] / lnet / klnds / gnilnd / gnilnd.c
index 6c00370..84829e5 100644 (file)
 
 /* Primary entry points from LNET.  There are no guarantees against reentrance. */
 lnd_t the_kgnilnd = {
+#ifdef CONFIG_CRAY_XT
        .lnd_type       = GNILND,
+#else
+       .lnd_type       = GNIIPLND,
+#endif
        .lnd_startup    = kgnilnd_startup,
        .lnd_shutdown   = kgnilnd_shutdown,
        .lnd_ctl        = kgnilnd_ctl,
@@ -199,8 +203,7 @@ kgnilnd_create_conn(kgn_conn_t **connp, kgn_device_t *dev)
        LIBCFS_ALLOC(conn->gnc_tx_ref_table, GNILND_MAX_MSG_ID * sizeof(void *));
        if (conn->gnc_tx_ref_table == NULL) {
                CERROR("Can't allocate conn tx_ref_table\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        atomic_set(&conn->gnc_refcount, 1);
@@ -231,8 +234,7 @@ kgnilnd_create_conn(kgn_conn_t **connp, kgn_device_t *dev)
 
        if (conn->gnc_cqid == 0) {
                CERROR("Could not allocate unique CQ ID for conn 0x%p\n", conn);
-               rc = -E2BIG;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -E2BIG);
        }
 
        CDEBUG(D_NET, "alloc cqid %u for conn 0x%p\n",
@@ -251,10 +253,8 @@ kgnilnd_create_conn(kgn_conn_t **connp, kgn_device_t *dev)
        rrc = kgnilnd_ep_create(dev->gnd_handle, dev->gnd_snd_fma_cqh,
                                &conn->gnc_ephandle);
        mutex_unlock(&dev->gnd_cq_mutex);
-       if (rrc != GNI_RC_SUCCESS) {
-               rc = -ENETDOWN;
-               GOTO(failed, rc);
-       }
+       if (rrc != GNI_RC_SUCCESS)
+               GOTO(failed, rc = -ENETDOWN);
 
        CDEBUG(D_NET, "created conn 0x%p ep_hndl 0x%p\n",
               conn, conn->gnc_ephandle);
@@ -914,7 +914,10 @@ return_out:
  * kgn_peer_conn_lock is held, we guarantee that nobody calls
  * kgnilnd_add_peer_locked without checking gnn_shutdown */
 int
-kgnilnd_create_peer_safe(kgn_peer_t **peerp, lnet_nid_t nid, kgn_net_t *net)
+kgnilnd_create_peer_safe(kgn_peer_t **peerp,
+                        lnet_nid_t nid,
+                        kgn_net_t *net,
+                        int node_state)
 {
        kgn_peer_t      *peer;
        int             rc;
@@ -946,7 +949,7 @@ kgnilnd_create_peer_safe(kgn_peer_t **peerp, lnet_nid_t nid, kgn_net_t *net)
                return -ENOMEM;
        }
        peer->gnp_nid = nid;
-       peer->gnp_down = GNILND_RCA_NODE_UP;
+       peer->gnp_down = node_state;
 
        /* translate from nid to nic addr & store */
        rc = kgnilnd_nid_to_nicaddrs(LNET_NIDADDR(nid), 1, &peer->gnp_host_id);
@@ -1053,6 +1056,8 @@ kgnilnd_add_purgatory_locked(kgn_conn_t *conn, kgn_peer_t *peer)
        CDEBUG(D_NET, "conn %p peer %p dev %p\n", conn, peer,
                conn->gnc_device);
 
+       LASSERTF(conn->gnc_in_purgatory == 0,
+               "Conn already in purgatory\n");
        conn->gnc_in_purgatory = 1;
 
        mbox = &conn->gnc_fma_blk->gnm_mbox_info[conn->gnc_mbox_id];
@@ -1334,11 +1339,14 @@ kgnilnd_add_peer(kgn_net_t *net, lnet_nid_t nid, kgn_peer_t **peerp)
 {
        kgn_peer_t        *peer;
        int                rc;
+       int                node_state;
        ENTRY;
 
        if (nid == LNET_NID_ANY)
                return -EINVAL;
 
+       node_state = kgnilnd_get_node_state(LNET_NIDADDR(nid));
+
        /* NB - this will not block during normal operations -
         * the only writer of this is in the startup/shutdown path. */
        rc = down_read_trylock(&kgnilnd_data.kgn_net_rw_sem);
@@ -1346,7 +1354,7 @@ kgnilnd_add_peer(kgn_net_t *net, lnet_nid_t nid, kgn_peer_t **peerp)
                rc = -ESHUTDOWN;
                RETURN(rc);
        }
-       rc = kgnilnd_create_peer_safe(&peer, nid, net);
+       rc = kgnilnd_create_peer_safe(&peer, nid, net, node_state);
        if (rc != 0) {
                up_read(&kgnilnd_data.kgn_net_rw_sem);
                RETURN(rc);
@@ -1513,9 +1521,6 @@ kgnilnd_del_conn_or_peer(kgn_net_t *net, lnet_nid_t nid, int command,
 
        write_unlock(&kgnilnd_data.kgn_peer_conn_lock);
 
-       /* release all of the souls found held in purgatory */
-       kgnilnd_release_purgatory_list(&souls);
-
        /* nuke peer TX */
        kgnilnd_txlist_done(&zombies, error);
 
@@ -1650,7 +1655,7 @@ kgnilnd_report_node_state(lnet_nid_t nid, int down)
 {
        int         rc;
        kgn_peer_t  *peer, *new_peer;
-       CFS_LIST_HEAD(zombies);
+       LIST_HEAD(zombies);
 
        write_lock(&kgnilnd_data.kgn_peer_conn_lock);
        peer = kgnilnd_find_peer_locked(nid);
@@ -1949,8 +1954,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
                                 &dev->gnd_domain);
        if (rrc != GNI_RC_SUCCESS) {
                CERROR("Can't create CDM %d (%d)\n", dev->gnd_id, rrc);
-               rc = -ENODEV;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENODEV);
        }
 
        rrc = kgnilnd_cdm_attach(dev->gnd_domain, dev->gnd_id,
@@ -1958,17 +1962,14 @@ kgnilnd_dev_init(kgn_device_t *dev)
        if (rrc != GNI_RC_SUCCESS) {
                CERROR("Can't attach CDM to device %d (%d)\n",
                        dev->gnd_id, rrc);
-               rc = -ENODEV;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENODEV);
        }
 
        /* a bit gross, but not much we can do - Aries Sim doesn't have
         * hardcoded NIC/NID that we can use */
        rc = kgnilnd_setup_nic_translation(dev->gnd_host_id);
-       if (rc != 0) {
-               rc = -ENODEV;
-               GOTO(failed, rc);
-       }
+       if (rc != 0)
+               GOTO(failed, rc = -ENODEV);
 
        /* only dev 0 gets the errors - no need to reset the stack twice
         * - this works because we have a single PTAG, if we had more
@@ -1982,8 +1983,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
                if (rrc != GNI_RC_SUCCESS) {
                        CERROR("Can't subscribe for errors on device %d: rc %d\n",
                                dev->gnd_id, rrc);
-                       rc = -ENODEV;
-                       GOTO(failed, rc);
+                       GOTO(failed, rc = -ENODEV);
                }
 
                rc = kgnilnd_set_quiesce_callback(dev->gnd_handle,
@@ -1991,11 +1991,16 @@ kgnilnd_dev_init(kgn_device_t *dev)
                if (rc != GNI_RC_SUCCESS) {
                        CERROR("Can't subscribe for quiesce callback on device %d: rc %d\n",
                                dev->gnd_id, rrc);
-                       rc = -ENODEV;
-                       GOTO(failed, rc);
+                       GOTO(failed, rc = -ENODEV);
                }
        }
 
+       rrc = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_IP, &kgnilnd_data.kgn_sock);
+       if (rrc < 0) {
+               CERROR("sock_create returned %d\n", rrc);
+               GOTO(failed, rrc);
+       }
+
        rc = kgnilnd_nicaddr_to_nid(dev->gnd_host_id, &dev->gnd_nid);
        if (rc < 0) {
                /* log messages during startup */
@@ -2003,8 +2008,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
                        CERROR("couldn't translate host_id 0x%x to nid. rc %d\n",
                                dev->gnd_host_id, rc);
                }
-               rc = -ESRCH;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ESRCH);
        }
        CDEBUG(D_NET, "NIC %x -> NID %d\n", dev->gnd_host_id, dev->gnd_nid);
 
@@ -2014,8 +2018,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
        if (rrc != GNI_RC_SUCCESS) {
                CERROR("Can't create rdma send cq size %u for device "
                       "%d (%d)\n", cq_size, dev->gnd_id, rrc);
-               rc = -EINVAL;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -EINVAL);
        }
 
        rrc = kgnilnd_cq_create(dev->gnd_handle, cq_size,
@@ -2024,8 +2027,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
        if (rrc != GNI_RC_SUCCESS) {
                CERROR("Can't create fma send cq size %u for device %d (%d)\n",
                       cq_size, dev->gnd_id, rrc);
-               rc = -EINVAL;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -EINVAL);
        }
 
        /* This one we size differently - overflows are possible and it needs to be
@@ -2037,8 +2039,7 @@ kgnilnd_dev_init(kgn_device_t *dev)
        if (rrc != GNI_RC_SUCCESS) {
                CERROR("Can't create fma cq size %d for device %d (%d)\n",
                       *kgnilnd_tunables.kgn_fma_cq_size, dev->gnd_id, rrc);
-               rc = -EINVAL;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -EINVAL);
        }
 
        RETURN(0);
@@ -2126,6 +2127,8 @@ kgnilnd_dev_fini(kgn_device_t *dev)
                dev->gnd_domain = NULL;
        }
 
+       sock_release(kgnilnd_data.kgn_sock);
+
        EXIT;
 }
 
@@ -2167,7 +2170,7 @@ int kgnilnd_base_startup(void)
                INIT_LIST_HEAD(&dev->gnd_map_tx);
                INIT_LIST_HEAD(&dev->gnd_fma_buffs);
                mutex_init(&dev->gnd_cq_mutex);
-               sema_init(&dev->gnd_fmablk_sem, 1);
+               mutex_init(&dev->gnd_fmablk_mutex);
                spin_lock_init(&dev->gnd_fmablk_lock);
                init_waitqueue_head(&dev->gnd_waitq);
                init_waitqueue_head(&dev->gnd_dgram_waitq);
@@ -2190,10 +2193,8 @@ int kgnilnd_base_startup(void)
                LIBCFS_ALLOC(dev->gnd_dgrams,
                            sizeof(struct list_head) * *kgnilnd_tunables.kgn_peer_hash_size);
 
-               if (dev->gnd_dgrams == NULL) {
-                       rc = -ENOMEM;
-                       GOTO(failed, rc);
-               }
+               if (dev->gnd_dgrams == NULL)
+                       GOTO(failed, rc = -ENOMEM);
 
                for (i = 0; i < *kgnilnd_tunables.kgn_peer_hash_size; i++) {
                        INIT_LIST_HEAD(&dev->gnd_dgrams[i]);
@@ -2217,7 +2218,7 @@ int kgnilnd_base_startup(void)
        init_waitqueue_head(&kgnilnd_data.kgn_ruhroh_waitq);
        spin_lock_init(&kgnilnd_data.kgn_reaper_lock);
 
-       sema_init(&kgnilnd_data.kgn_quiesce_sem, 1);
+       mutex_init(&kgnilnd_data.kgn_quiesce_mutex);
        atomic_set(&kgnilnd_data.kgn_nquiesce, 0);
        atomic_set(&kgnilnd_data.kgn_npending_conns, 0);
        atomic_set(&kgnilnd_data.kgn_npending_unlink, 0);
@@ -2228,17 +2229,15 @@ int kgnilnd_base_startup(void)
 
        /* OK to call kgnilnd_api_shutdown() to cleanup now */
        kgnilnd_data.kgn_init = GNILND_INIT_DATA;
-       PORTAL_MODULE_USE;
+       try_module_get(THIS_MODULE);
 
        rwlock_init(&kgnilnd_data.kgn_peer_conn_lock);
 
        LIBCFS_ALLOC(kgnilnd_data.kgn_peers,
                    sizeof(struct list_head) * *kgnilnd_tunables.kgn_peer_hash_size);
 
-       if (kgnilnd_data.kgn_peers == NULL) {
-               rc = -ENOMEM;
-               GOTO(failed, rc);
-       }
+       if (kgnilnd_data.kgn_peers == NULL)
+               GOTO(failed, rc = -ENOMEM);
 
        for (i = 0; i < *kgnilnd_tunables.kgn_peer_hash_size; i++) {
                INIT_LIST_HEAD(&kgnilnd_data.kgn_peers[i]);
@@ -2247,10 +2246,8 @@ int kgnilnd_base_startup(void)
        LIBCFS_ALLOC(kgnilnd_data.kgn_conns,
                    sizeof(struct list_head) * *kgnilnd_tunables.kgn_peer_hash_size);
 
-       if (kgnilnd_data.kgn_conns == NULL) {
-               rc = -ENOMEM;
-               GOTO(failed, rc);
-       }
+       if (kgnilnd_data.kgn_conns == NULL)
+               GOTO(failed, rc = -ENOMEM);
 
        for (i = 0; i < *kgnilnd_tunables.kgn_peer_hash_size; i++) {
                INIT_LIST_HEAD(&kgnilnd_data.kgn_conns[i]);
@@ -2259,68 +2256,49 @@ int kgnilnd_base_startup(void)
        LIBCFS_ALLOC(kgnilnd_data.kgn_nets,
                    sizeof(struct list_head) * *kgnilnd_tunables.kgn_net_hash_size);
 
-       if (kgnilnd_data.kgn_nets == NULL) {
-               rc = -ENOMEM;
-               GOTO(failed, rc);
-       }
+       if (kgnilnd_data.kgn_nets == NULL)
+               GOTO(failed, rc = -ENOMEM);
 
        for (i = 0; i < *kgnilnd_tunables.kgn_net_hash_size; i++) {
                INIT_LIST_HEAD(&kgnilnd_data.kgn_nets[i]);
        }
 
        kgnilnd_data.kgn_mbox_cache =
-               cfs_mem_cache_create("kgn_mbox_block",
-                                    KMALLOC_MAX_SIZE,
-                                    0,    /* offset */
-                                    SLAB_HWCACHE_ALIGN);   /* flags */
+               kmem_cache_create("kgn_mbox_block", KMALLOC_MAX_SIZE, 0,
+                                 SLAB_HWCACHE_ALIGN, NULL);
        if (kgnilnd_data.kgn_mbox_cache == NULL) {
                CERROR("Can't create slab for physical mbox blocks\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        kgnilnd_data.kgn_rx_cache =
-               cfs_mem_cache_create("kgn_rx_t",
-                                    sizeof(kgn_rx_t),
-                                    0,    /* offset */
-                                    0);   /* flags */
+               kmem_cache_create("kgn_rx_t", sizeof(kgn_rx_t), 0, 0, NULL);
        if (kgnilnd_data.kgn_rx_cache == NULL) {
                CERROR("Can't create slab for kgn_rx_t descriptors\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        kgnilnd_data.kgn_tx_cache =
-               cfs_mem_cache_create("kgn_tx_t",
-                                    sizeof(kgn_tx_t),
-                                    0,    /* offset */
-                                    0);   /* flags */
+               kmem_cache_create("kgn_tx_t", sizeof(kgn_tx_t), 0, 0, NULL);
        if (kgnilnd_data.kgn_tx_cache == NULL) {
                CERROR("Can't create slab for kgn_tx_t\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        kgnilnd_data.kgn_tx_phys_cache =
-               cfs_mem_cache_create("kgn_tx_phys",
-                                    LNET_MAX_IOV * sizeof(gni_mem_segment_t),
-                                    0,    /* offset */
-                                    0);   /* flags */
+               kmem_cache_create("kgn_tx_phys",
+                                  LNET_MAX_IOV * sizeof(gni_mem_segment_t),
+                                  0, 0, NULL);
        if (kgnilnd_data.kgn_tx_phys_cache == NULL) {
                CERROR("Can't create slab for kgn_tx_phys\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        kgnilnd_data.kgn_dgram_cache =
-               cfs_mem_cache_create("kgn_dgram_t",
-                                    sizeof(kgn_dgram_t),
-                                    0,    /* offset */
-                                    0);   /* flags */
+               kmem_cache_create("kgn_dgram_t", sizeof(kgn_dgram_t), 0, 0, NULL);
        if (kgnilnd_data.kgn_dgram_cache == NULL) {
                CERROR("Can't create slab for outgoing datagrams\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
 
        /* allocate a MAX_IOV array of page pointers for each cpu */
@@ -2328,8 +2306,7 @@ int kgnilnd_base_startup(void)
                                                   GFP_KERNEL);
        if (kgnilnd_data.kgn_cksum_map_pages == NULL) {
                CERROR("Can't allocate vmap cksum pages\n");
-               rc = -ENOMEM;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
        kgnilnd_data.kgn_cksum_npages = num_possible_cpus();
        memset(kgnilnd_data.kgn_cksum_map_pages, 0,
@@ -2340,8 +2317,7 @@ int kgnilnd_base_startup(void)
                                                              GFP_KERNEL);
                if (kgnilnd_data.kgn_cksum_map_pages[i] == NULL) {
                        CERROR("Can't allocate vmap cksum pages for cpu %d\n", i);
-                       rc = -ENOMEM;
-                       GOTO(failed, rc);
+                       GOTO(failed, rc = -ENOMEM);
                }
        }
 
@@ -2357,16 +2333,14 @@ int kgnilnd_base_startup(void)
                        kgnilnd_data.kgn_ndevs++;
 
                        rc = kgnilnd_allocate_phys_fmablk(dev);
-                       if (rc) {
+                       if (rc)
                                GOTO(failed, rc);
-                       }
                }
        }
 
        if (kgnilnd_data.kgn_ndevs == 0) {
                CERROR("Can't initialise any GNI devices\n");
-               rc = -ENODEV;
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENODEV);
        }
 
        rc = kgnilnd_thread_start(kgnilnd_reaper, NULL, "kgnilnd_rpr", 0);
@@ -2450,7 +2424,7 @@ failed:
 void
 kgnilnd_base_shutdown(void)
 {
-       int                     i;
+       int                     i, j;
        ENTRY;
 
        while (CFS_FAIL_TIMEOUT(CFS_FAIL_GNI_PAUSE_SHUTDOWN, 1)) {};
@@ -2460,10 +2434,29 @@ kgnilnd_base_shutdown(void)
        for (i = 0; i < kgnilnd_data.kgn_ndevs; i++) {
                kgn_device_t *dev = &kgnilnd_data.kgn_devices[i];
                kgnilnd_cancel_wc_dgrams(dev);
+               kgnilnd_cancel_dgrams(dev);
                kgnilnd_del_conn_or_peer(NULL, LNET_NID_ANY, GNILND_DEL_PEER, -ESHUTDOWN);
                kgnilnd_wait_for_canceled_dgrams(dev);
        }
 
+       /* We need to verify there are no conns left before we let the threads
+        * shut down otherwise we could clean up the peers but still have
+        * some outstanding conns due to orphaned datagram conns that are
+        * being cleaned up.
+        */
+       i = 2;
+       while (atomic_read(&kgnilnd_data.kgn_nconns) != 0) {
+               i++;
+
+               for(j = 0; j < kgnilnd_data.kgn_ndevs; ++j) {
+                       kgn_device_t *dev = &kgnilnd_data.kgn_devices[j];
+                       kgnilnd_schedule_device(dev);
+               }
+
+               CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET,
+                       "Waiting for conns to be cleaned up %d\n",atomic_read(&kgnilnd_data.kgn_nconns));
+               cfs_pause(cfs_time_seconds(1));
+       }
        /* Peer state all cleaned up BEFORE setting shutdown, so threads don't
         * have to worry about shutdown races.  NB connections may be created
         * while there are still active connds, but these will be temporary
@@ -2491,7 +2484,7 @@ kgnilnd_base_shutdown(void)
                kgn_device_t *dev = &kgnilnd_data.kgn_devices[i];
 
                /* should clear all the MDDs */
-               kgnilnd_unmap_phys_fmablk(dev);
+               kgnilnd_unmap_fma_blocks(dev);
 
                kgnilnd_schedule_device(dev);
                wake_up_all(&dev->gnd_dgram_waitq);
@@ -2569,30 +2562,20 @@ kgnilnd_base_shutdown(void)
                kgnilnd_free_phys_fmablk(dev);
        }
 
-       if (kgnilnd_data.kgn_mbox_cache != NULL) {
-               i = cfs_mem_cache_destroy(kgnilnd_data.kgn_mbox_cache);
-               LASSERTF(i == 0, "rc %d destroying kgn_mbox_cache\n", i);
-       }
+       if (kgnilnd_data.kgn_mbox_cache != NULL)
+               kmem_cache_destroy(kgnilnd_data.kgn_mbox_cache);
 
-       if (kgnilnd_data.kgn_rx_cache != NULL) {
-               i = cfs_mem_cache_destroy(kgnilnd_data.kgn_rx_cache);
-               LASSERTF(i == 0, "rc %d destroying kgn_rx_cache\n", i);
-       }
+       if (kgnilnd_data.kgn_rx_cache != NULL)
+               kmem_cache_destroy(kgnilnd_data.kgn_rx_cache);
 
-       if (kgnilnd_data.kgn_tx_cache != NULL) {
-               i = cfs_mem_cache_destroy(kgnilnd_data.kgn_tx_cache);
-               LASSERTF(i == 0, "rc %d destroying kgn_tx_cache\n", i);
-       }
+       if (kgnilnd_data.kgn_tx_cache != NULL)
+               kmem_cache_destroy(kgnilnd_data.kgn_tx_cache);
 
-       if (kgnilnd_data.kgn_tx_phys_cache != NULL) {
-               i = cfs_mem_cache_destroy(kgnilnd_data.kgn_tx_phys_cache);
-               LASSERTF(i == 0, "rc %d destroying kgn_tx_phys_cache\n", i);
-       }
+       if (kgnilnd_data.kgn_tx_phys_cache != NULL)
+               kmem_cache_destroy(kgnilnd_data.kgn_tx_phys_cache);
 
-       if (kgnilnd_data.kgn_dgram_cache != NULL) {
-               i = cfs_mem_cache_destroy(kgnilnd_data.kgn_dgram_cache);
-               LASSERTF(i == 0, "rc %d destroying kgn_dgram_cache\n", i);
-       }
+       if (kgnilnd_data.kgn_dgram_cache != NULL)
+               kmem_cache_destroy(kgnilnd_data.kgn_dgram_cache);
 
        if (kgnilnd_data.kgn_cksum_map_pages != NULL) {
                for (i = 0; i < kgnilnd_data.kgn_cksum_npages; i++) {
@@ -2607,7 +2590,7 @@ kgnilnd_base_shutdown(void)
               atomic_read(&libcfs_kmemory));
 
        kgnilnd_data.kgn_init = GNILND_INIT_NOTHING;
-       PORTAL_MODULE_UNUSE;
+       module_put(THIS_MODULE);
 
        EXIT;
 }
@@ -2630,14 +2613,13 @@ kgnilnd_startup(lnet_ni_t *ni)
        }
 
        /* Serialize with shutdown. */
-       down(&kgnilnd_data.kgn_quiesce_sem);
+       mutex_lock(&kgnilnd_data.kgn_quiesce_mutex);
 
        LIBCFS_ALLOC(net, sizeof(*net));
        if (net == NULL) {
                CERROR("could not allocate net for new interface instance\n");
-               rc = -ENOMEM;
                /* no need to cleanup the CDM... */
-               GOTO(failed, rc);
+               GOTO(failed, rc = -ENOMEM);
        }
        INIT_LIST_HEAD(&net->gnn_list);
        ni->ni_data = net;
@@ -2661,8 +2643,7 @@ kgnilnd_startup(lnet_ni_t *ni)
                                        timeout);
                        ni->ni_data = NULL;
                        LIBCFS_FREE(net, sizeof(*net));
-                       rc = -EINVAL;
-                       GOTO(failed, rc);
+                       GOTO(failed, rc = -EINVAL);
                } else
                        ni->ni_peertimeout = timeout;
 
@@ -2699,10 +2680,10 @@ kgnilnd_startup(lnet_ni_t *ni)
 
        /* we need a separate thread to call probe_wait_by_id until
         * we get a function callback notifier from kgni */
-       up(&kgnilnd_data.kgn_quiesce_sem);
+       mutex_unlock(&kgnilnd_data.kgn_quiesce_mutex);
        RETURN(0);
  failed:
-       up(&kgnilnd_data.kgn_quiesce_sem);
+       mutex_unlock(&kgnilnd_data.kgn_quiesce_mutex);
        kgnilnd_shutdown(ni);
        RETURN(rc);
 }
@@ -2721,14 +2702,13 @@ kgnilnd_shutdown(lnet_ni_t *ni)
                "init %d\n", kgnilnd_data.kgn_init);
 
        /* Serialize with startup. */
-       down(&kgnilnd_data.kgn_quiesce_sem);
+       mutex_lock(&kgnilnd_data.kgn_quiesce_mutex);
        CDEBUG(D_MALLOC, "before NAL cleanup: kmem %d\n",
               atomic_read(&libcfs_kmemory));
 
        if (net == NULL) {
                CERROR("got NULL net for ni %p\n", ni);
-               rc = -EINVAL;
-               GOTO(out, rc);
+               GOTO(out, rc = -EINVAL);
        }
 
        LASSERTF(ni == net->gnn_ni,
@@ -2805,9 +2785,8 @@ out:
        CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
               atomic_read(&libcfs_kmemory));
 
-       up(&kgnilnd_data.kgn_quiesce_sem);
+       mutex_unlock(&kgnilnd_data.kgn_quiesce_mutex);
        EXIT;
-       return;
 }
 
 void __exit