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;
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
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();
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();
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;
out:
if (list_empty(&kiblnd_data.kib_devs))
kiblnd_base_shutdown();
- return;
}
static int
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;
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]);
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;
/* Use the IPoIB interface specified in 'networks=' */
if (ni->ni_interfaces[1] != NULL) {
CERROR("ko2iblnd: Multiple interfaces not supported\n");
+ rc = -EINVAL;
goto failed;
}
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)
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 = {