LIBCFS_FREE(dev, sizeof(*dev));
}
-static struct kib_dev *
-kiblnd_create_dev(char *ifname)
-{
- struct net_device *netdev;
- struct kib_dev *dev = NULL;
- int flags;
- int rc;
-
- rtnl_lock();
- for_each_netdev(&init_net, netdev) {
- struct in_device *in_dev;
-
- if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */
- continue;
-
- flags = dev_get_flags(netdev);
- if (!(flags & IFF_UP)) {
- CWARN("Can't query IPoIB interface %s: it's down\n",
- netdev->name);
- continue;
- }
-
- in_dev = __in_dev_get_rtnl(netdev);
- if (!in_dev) {
- CWARN("Interface %s has no IPv4 status.\n",
- netdev->name);
- continue;
- }
-
- for_ifa(in_dev)
- if (strcmp(ifname, ifa->ifa_label) == 0) {
- LIBCFS_ALLOC(dev, sizeof(*dev));
- if (!dev)
- goto unlock;
-
- dev->ibd_can_failover = !!(flags & IFF_MASTER);
- dev->ibd_ifip = ntohl(ifa->ifa_local);
-
- INIT_LIST_HEAD(&dev->ibd_nets);
- INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
- INIT_LIST_HEAD(&dev->ibd_fail_list);
- break;
- }
- endfor_ifa(in_dev);
- }
- rtnl_unlock();
-
- if (!dev) {
- CERROR("Can't find any usable interfaces\n");
- return NULL;
- }
-
- if (dev->ibd_ifip == 0) {
- CERROR("Can't initialize device: no IP address\n");
- goto free_dev;
- }
- strcpy(&dev->ibd_ifname[0], ifname);
-
- /* initialize the device */
- rc = kiblnd_dev_failover(dev);
- if (rc != 0) {
- CERROR("Can't initialize device: %d\n", rc);
- goto free_dev;
- }
-
- list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs);
- return dev;
-unlock:
- rtnl_unlock();
-free_dev:
- LIBCFS_FREE(dev, sizeof(*dev));
- return NULL;
-}
-
static void
kiblnd_base_shutdown(void)
{
return rc;
}
-static int
-kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
+static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
{
int cpt;
int rc;
cpt = (cpts == NULL) ? i : cpts[i];
sched = kiblnd_data.kib_scheds[cpt];
- if (!newdev && sched->ibs_nthreads > 0)
+ if (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;
+ struct lnet_inetdev *ifaces = NULL;
struct kib_dev *ibdev = NULL;
struct kib_net *net;
unsigned long flags;
int rc;
- int newdev;
- int node_id;
+ int i;
LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
*/
if (ni->ni_interfaces[0] != NULL) {
/* Use the IPoIB interface specified in 'networks=' */
-
- CLASSERT(LNET_INTERFACES_NUM > 1);
if (ni->ni_interfaces[1] != NULL) {
- CERROR("Multiple interfaces not supported\n");
+ CERROR("ko2iblnd: Multiple interfaces not supported\n");
goto failed;
}
goto failed;
}
- ibdev = kiblnd_dev_search(ifname);
+ rc = lnet_inet_enumerate(&ifaces);
+ if (rc < 0)
+ goto failed;
+
+ for (i = 0; i < rc; i++) {
+ if (strcmp(ifname, ifaces[i].li_name) == 0)
+ break;
+ }
- newdev = ibdev == NULL;
- /* hmm...create kib_dev even for alias */
- if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
- ibdev = kiblnd_create_dev(ifname);
+ if (i == rc) {
+ CERROR("ko2iblnd: No matching interfaces\n");
+ rc = -ENOENT;
+ goto failed;
+ }
- if (ibdev == NULL)
+ 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);
- node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device);
- ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
+ 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);
+ if (rc) {
+ CERROR("ko2iblnd: Can't initialize device: rc = %d\n", rc);
+ goto failed;
+ }
+
+ 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);
- rc = kiblnd_dev_start_threads(ibdev, newdev,
- ni->ni_cpts, ni->ni_ncpts);
+ ni->ni_dev_cpt = ifaces[i].li_cpt;
+
+ rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
if (rc != 0)
goto failed;
if (net != NULL && net->ibn_dev == NULL && ibdev != NULL)
kiblnd_destroy_dev(ibdev);
+ kfree(ifaces);
kiblnd_shutdown(ni);
CDEBUG(D_NET, "kiblnd_startup failed\n");