Whamcloud - gitweb
LU-9679 modules: Use LIST_HEAD for declaring list_heads
[fs/lustre-release.git] / lnet / klnds / o2iblnd / o2iblnd.c
index 0d7b50a..dde4cfd 100644 (file)
@@ -480,7 +480,7 @@ kiblnd_del_peer_locked(struct kib_peer_ni *peer_ni)
 static int
 kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid)
 {
-       struct list_head        zombies = LIST_HEAD_INIT(zombies);
+       LIST_HEAD(zombies);
        struct list_head        *ptmp;
        struct list_head        *pnxt;
        struct kib_peer_ni              *peer_ni;
@@ -1255,7 +1255,6 @@ kiblnd_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when)
        CDEBUG(D_NET, "peer_ni %s %p, alive %lld secs ago\n",
               libcfs_nid2str(nid), peer_ni,
               last_alive ? now - last_alive : -1);
-       return;
 }
 
 static void
@@ -1789,7 +1788,7 @@ kiblnd_map_tx_pages(struct kib_tx *tx, struct kib_rdma_desc *rd)
 void
 kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status)
 {
-       struct list_head zombies = LIST_HEAD_INIT(zombies);
+       LIST_HEAD(zombies);
        struct kib_fmr_pool *fpo = fmr->fmr_pool;
        struct kib_fmr_poolset *fps;
        time64_t now = ktime_get_seconds();
@@ -2146,7 +2145,7 @@ kiblnd_pool_is_idle(struct kib_pool *pool, time64_t now)
 void
 kiblnd_pool_free_node(struct kib_pool *pool, struct list_head *node)
 {
-       struct list_head zombies = LIST_HEAD_INIT(zombies);
+       LIST_HEAD(zombies);
        struct kib_poolset *ps = pool->po_owner;
        struct kib_pool *tmp;
        time64_t now = ktime_get_seconds();
@@ -2726,9 +2725,9 @@ kiblnd_dev_need_failover(struct kib_dev *dev, struct net *ns)
 int
 kiblnd_dev_failover(struct kib_dev *dev, struct net *ns)
 {
-       struct list_head    zombie_tpo = LIST_HEAD_INIT(zombie_tpo);
-       struct list_head    zombie_ppo = LIST_HEAD_INIT(zombie_ppo);
-       struct list_head    zombie_fpo = LIST_HEAD_INIT(zombie_fpo);
+       LIST_HEAD(zombie_tpo);
+       LIST_HEAD(zombie_ppo);
+       LIST_HEAD(zombie_fpo);
         struct rdma_cm_id  *cmid  = NULL;
        struct kib_hca_dev *hdev  = NULL;
        struct kib_hca_dev *old;
@@ -3027,7 +3026,6 @@ kiblnd_shutdown(struct lnet_ni *ni)
 out:
        if (list_empty(&kiblnd_data.kib_devs))
                 kiblnd_base_shutdown();
-        return;
 }
 
 static int
@@ -3164,7 +3162,8 @@ kiblnd_start_schedulers(struct kib_sched_info *sched)
        return rc;
 }
 
-static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
+static int kiblnd_dev_start_threads(struct kib_dev *dev, bool newdev, u32 *cpts,
+                                   int ncpts)
 {
        int     cpt;
        int     rc;
@@ -3176,7 +3175,7 @@ static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
                cpt = (cpts == NULL) ? i : cpts[i];
                sched = kiblnd_data.kib_scheds[cpt];
 
-               if (sched->ibs_nthreads > 0)
+               if (!newdev && sched->ibs_nthreads > 0)
                        continue;
 
                rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
@@ -3189,29 +3188,65 @@ static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
        return 0;
 }
 
+static struct kib_dev *
+kiblnd_dev_search(char *ifname)
+{
+       struct kib_dev *alias = NULL;
+       struct kib_dev *dev;
+       char            *colon;
+       char            *colon2;
+
+       colon = strchr(ifname, ':');
+       list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
+               if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
+                       return dev;
+
+               if (alias != NULL)
+                       continue;
+
+               colon2 = strchr(dev->ibd_ifname, ':');
+               if (colon != NULL)
+                       *colon = 0;
+               if (colon2 != NULL)
+                       *colon2 = 0;
+
+               if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
+                       alias = dev;
+
+               if (colon != NULL)
+                       *colon = ':';
+               if (colon2 != NULL)
+                       *colon2 = ':';
+       }
+       return alias;
+}
+
 static int
 kiblnd_startup(struct lnet_ni *ni)
 {
-        char                     *ifname;
+       char *ifname = NULL;
        struct lnet_inetdev *ifaces = NULL;
        struct kib_dev *ibdev = NULL;
-       struct kib_net *net;
-        unsigned long             flags;
-        int                       rc;
+       struct kib_net *net = NULL;
+       unsigned long flags;
+       int rc;
        int i;
+       bool newdev;
 
-        LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
+       LASSERT(ni->ni_net->net_lnd == &the_o2iblnd);
 
-        if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) {
+       if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) {
                rc = kiblnd_base_startup(ni->ni_net_ns);
-                if (rc != 0)
-                        return rc;
-        }
+               if (rc != 0)
+                       return rc;
+       }
 
-        LIBCFS_ALLOC(net, sizeof(*net));
-        ni->ni_data = net;
-        if (net == NULL)
-                goto failed;
+       LIBCFS_ALLOC(net, sizeof(*net));
+       ni->ni_data = net;
+       if (net == NULL) {
+               rc = -ENOMEM;
+               goto failed;
+       }
 
        net->ibn_incarnation = ktime_get_real_ns() / NSEC_PER_USEC;
 
@@ -3226,6 +3261,7 @@ kiblnd_startup(struct lnet_ni *ni)
                /* Use the IPoIB interface specified in 'networks=' */
                if (ni->ni_interfaces[1] != NULL) {
                        CERROR("ko2iblnd: Multiple interfaces not supported\n");
+                       rc = -EINVAL;
                        goto failed;
                }
 
@@ -3234,10 +3270,11 @@ kiblnd_startup(struct lnet_ni *ni)
                ifname = *kiblnd_tunables.kib_default_ipif;
        }
 
-        if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
-                CERROR("IPoIB interface name too long: %s\n", ifname);
-                goto failed;
-        }
+       if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
+               CERROR("IPoIB interface name too long: %s\n", ifname);
+               rc = -E2BIG;
+               goto failed;
+       }
 
        rc = lnet_inet_enumerate(&ifaces, ni->ni_net_ns);
        if (rc < 0)
@@ -3254,63 +3291,71 @@ kiblnd_startup(struct lnet_ni *ni)
                goto failed;
        }
 
-       LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
-       if (!ibdev) {
-               rc = -ENOMEM;
-               goto failed;
-       }
+       ibdev = kiblnd_dev_search(ifname);
+       newdev = ibdev == NULL;
+       /* hmm...create kib_dev even for alias */
+       if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0) {
+               LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
+               if (!ibdev) {
+                       rc = -ENOMEM;
+                       goto failed;
+               }
 
-       ibdev->ibd_ifip = ifaces[i].li_ipaddr;
-       strlcpy(ibdev->ibd_ifname, ifaces[i].li_name,
-               sizeof(ibdev->ibd_ifname));
-       ibdev->ibd_can_failover = !!(ifaces[i].li_flags & IFF_MASTER);
+               ibdev->ibd_ifip = ifaces[i].li_ipaddr;
+               strlcpy(ibdev->ibd_ifname, ifaces[i].li_name,
+                       sizeof(ibdev->ibd_ifname));
+               ibdev->ibd_can_failover = !!(ifaces[i].li_flags & IFF_MASTER);
 
-       INIT_LIST_HEAD(&ibdev->ibd_nets);
-       INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
-       INIT_LIST_HEAD(&ibdev->ibd_fail_list);
+               INIT_LIST_HEAD(&ibdev->ibd_nets);
+               INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
+               INIT_LIST_HEAD(&ibdev->ibd_fail_list);
 
-       /* initialize the device */
-       rc = kiblnd_dev_failover(ibdev, ni->ni_net_ns);
-       if (rc) {
-               CERROR("ko2iblnd: Can't initialize device: rc = %d\n", rc);
-               goto failed;
-       }
+               /* initialize the device */
+               rc = kiblnd_dev_failover(ibdev, ni->ni_net_ns);
+               if (rc) {
+                       CERROR("ko2iblnd: Can't initialize device: rc = %d\n",
+                              rc);
+                       goto failed;
+               }
 
-       list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
+               list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
+       }
 
        net->ibn_dev = ibdev;
        ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
 
        ni->ni_dev_cpt = ifaces[i].li_cpt;
 
-       rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
+       rc = kiblnd_dev_start_threads(ibdev, newdev, ni->ni_cpts, ni->ni_ncpts);
        if (rc != 0)
                goto failed;
 
        rc = kiblnd_net_init_pools(net, ni, ni->ni_cpts, ni->ni_ncpts);
-        if (rc != 0) {
-                CERROR("Failed to initialize NI pools: %d\n", rc);
-                goto failed;
-        }
+       if (rc != 0) {
+               CERROR("Failed to initialize NI pools: %d\n", rc);
+               goto failed;
+       }
 
        write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
        ibdev->ibd_nnets++;
        list_add_tail(&net->ibn_list, &ibdev->ibd_nets);
        write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
 
-        net->ibn_init = IBLND_INIT_ALL;
+       net->ibn_init = IBLND_INIT_ALL;
 
-        return 0;
+       return 0;
 
 failed:
        if (net != NULL && net->ibn_dev == NULL && ibdev != NULL)
-                kiblnd_destroy_dev(ibdev);
+               kiblnd_destroy_dev(ibdev);
 
        kfree(ifaces);
-        kiblnd_shutdown(ni);
+       kiblnd_shutdown(ni);
 
-        CDEBUG(D_NET, "kiblnd_startup failed\n");
-        return -ENETDOWN;
+       CDEBUG(D_NET, "Configuration of device %s failed: rc = %d\n",
+              ifname ? ifname : "", rc);
+
+       return -ENETDOWN;
 }
 
 static struct lnet_lnd the_o2iblnd = {