Message ID | e63cec57a13b40731730778d71b66cc9f1ca513a.1544033819.git.swise@opengridcomputing.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Dynamic rdma link creation | expand |
On Wed, Dec 05, 2018 at 07:14:20AM -0800, Steve Wise wrote: > Add support for the RDMA_NLDEV_CMD_NEWLINK/DELLINK messages which allow > dynamically adding new RXE links. Deprecate the old module options > for now. > > Cc: Moni Shoua <monis@mellanox.com> > Reviewed-by: Yanjun Zhu <yanjun.zhu@oracle.com> > Signed-off-by: Steve Wise <swise@opengridcomputing.com> > --- > drivers/infiniband/sw/rxe/rxe.c | 66 +++++++++++++++++++++++++++++++++-- > drivers/infiniband/sw/rxe/rxe.h | 3 +- > drivers/infiniband/sw/rxe/rxe_net.c | 21 +++++++++-- > drivers/infiniband/sw/rxe/rxe_net.h | 2 +- > drivers/infiniband/sw/rxe/rxe_sysfs.c | 6 ++-- > drivers/infiniband/sw/rxe/rxe_verbs.c | 4 +-- > drivers/infiniband/sw/rxe/rxe_verbs.h | 2 +- > 7 files changed, 92 insertions(+), 12 deletions(-) > > diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c > index 19d8e522b72b..b98141442cb2 100644 > --- a/drivers/infiniband/sw/rxe/rxe.c > +++ b/drivers/infiniband/sw/rxe/rxe.c > @@ -31,6 +31,7 @@ > * SOFTWARE. > */ > > +#include <rdma/rdma_netlink.h> > #include <net/addrconf.h> > #include "rxe.h" > #include "rxe_loc.h" > @@ -309,7 +310,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) > /* called by ifc layer to create new rxe device. > * The caller should allocate memory for rxe by calling ib_alloc_device. > */ > -int rxe_add(struct rxe_dev *rxe, unsigned int mtu) > +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name) > { > int err; > > @@ -321,7 +322,7 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) > > rxe_set_mtu(rxe, mtu); > > - err = rxe_register_device(rxe); > + err = rxe_register_device(rxe, ibdev_name); > if (err) > goto err1; > > @@ -332,6 +333,63 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) > return err; > } > > +static struct ib_device *rxe_newlink(const char *ibdev_name, > + const char *ndev_name) > +{ > + struct net_device *ndev = NULL; > + struct rxe_dev *rxe; > + int err = 0; > + > + ndev = dev_get_by_name(&init_net, ndev_name); > + if (!ndev) { > + pr_err("interface %s not found\n", ndev_name); > + err = -ENODEV; > + goto err; > + } > + > + rxe = net_to_rxe(ndev); > + if (rxe) { > + pr_err("already configured on %s\n", ndev_name); > + err = -EEXIST; > + rxe_dev_put(rxe); > + goto err; > + } Shouldn't the code above be part of core logic instead of being in driver? Thanks
On 12/6/2018 1:02 AM, Leon Romanovsky wrote: > On Wed, Dec 05, 2018 at 07:14:20AM -0800, Steve Wise wrote: >> Add support for the RDMA_NLDEV_CMD_NEWLINK/DELLINK messages which allow >> dynamically adding new RXE links. Deprecate the old module options >> for now. >> >> Cc: Moni Shoua <monis@mellanox.com> >> Reviewed-by: Yanjun Zhu <yanjun.zhu@oracle.com> >> Signed-off-by: Steve Wise <swise@opengridcomputing.com> >> --- >> drivers/infiniband/sw/rxe/rxe.c | 66 +++++++++++++++++++++++++++++++++-- >> drivers/infiniband/sw/rxe/rxe.h | 3 +- >> drivers/infiniband/sw/rxe/rxe_net.c | 21 +++++++++-- >> drivers/infiniband/sw/rxe/rxe_net.h | 2 +- >> drivers/infiniband/sw/rxe/rxe_sysfs.c | 6 ++-- >> drivers/infiniband/sw/rxe/rxe_verbs.c | 4 +-- >> drivers/infiniband/sw/rxe/rxe_verbs.h | 2 +- >> 7 files changed, 92 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c >> index 19d8e522b72b..b98141442cb2 100644 >> --- a/drivers/infiniband/sw/rxe/rxe.c >> +++ b/drivers/infiniband/sw/rxe/rxe.c >> @@ -31,6 +31,7 @@ >> * SOFTWARE. >> */ >> >> +#include <rdma/rdma_netlink.h> >> #include <net/addrconf.h> >> #include "rxe.h" >> #include "rxe_loc.h" >> @@ -309,7 +310,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) >> /* called by ifc layer to create new rxe device. >> * The caller should allocate memory for rxe by calling ib_alloc_device. >> */ >> -int rxe_add(struct rxe_dev *rxe, unsigned int mtu) >> +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name) >> { >> int err; >> >> @@ -321,7 +322,7 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) >> >> rxe_set_mtu(rxe, mtu); >> >> - err = rxe_register_device(rxe); >> + err = rxe_register_device(rxe, ibdev_name); >> if (err) >> goto err1; >> >> @@ -332,6 +333,63 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) >> return err; >> } >> >> +static struct ib_device *rxe_newlink(const char *ibdev_name, >> + const char *ndev_name) >> +{ >> + struct net_device *ndev = NULL; >> + struct rxe_dev *rxe; >> + int err = 0; >> + >> + ndev = dev_get_by_name(&init_net, ndev_name); >> + if (!ndev) { >> + pr_err("interface %s not found\n", ndev_name); >> + err = -ENODEV; >> + goto err; >> + } >> + >> + rxe = net_to_rxe(ndev); >> + if (rxe) { >> + pr_err("already configured on %s\n", ndev_name); >> + err = -EEXIST; >> + rxe_dev_put(rxe); >> + goto err; >> + } > Shouldn't the code above be part of core logic instead of being in driver? > > Thanks So nldev_newlink() would find the net device and pass it to the ops->newlink function instead of passing the net device name? That sounds good. Thanks!
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 19d8e522b72b..b98141442cb2 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -31,6 +31,7 @@ * SOFTWARE. */ +#include <rdma/rdma_netlink.h> #include <net/addrconf.h> #include "rxe.h" #include "rxe_loc.h" @@ -309,7 +310,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) /* called by ifc layer to create new rxe device. * The caller should allocate memory for rxe by calling ib_alloc_device. */ -int rxe_add(struct rxe_dev *rxe, unsigned int mtu) +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name) { int err; @@ -321,7 +322,7 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) rxe_set_mtu(rxe, mtu); - err = rxe_register_device(rxe); + err = rxe_register_device(rxe, ibdev_name); if (err) goto err1; @@ -332,6 +333,63 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu) return err; } +static struct ib_device *rxe_newlink(const char *ibdev_name, + const char *ndev_name) +{ + struct net_device *ndev = NULL; + struct rxe_dev *rxe; + int err = 0; + + ndev = dev_get_by_name(&init_net, ndev_name); + if (!ndev) { + pr_err("interface %s not found\n", ndev_name); + err = -ENODEV; + goto err; + } + + rxe = net_to_rxe(ndev); + if (rxe) { + pr_err("already configured on %s\n", ndev_name); + err = -EEXIST; + rxe_dev_put(rxe); + goto err; + } + + rxe = rxe_net_add(ibdev_name, ndev); + if (!rxe) { + pr_err("failed to add %s\n", ndev_name); + err = -EINVAL; + goto err; + } + + if (netif_running(ndev) && netif_carrier_ok(ndev)) + rxe_port_up(rxe); + else + rxe_port_down(rxe); + pr_info("added %s to %s\n", rxe->ib_dev.name, ndev->name); +err: + if (ndev) + dev_put(ndev); + return err ? ERR_PTR(err) : &rxe->ib_dev; +} + +static int rxe_dellink(struct ib_device *device) +{ + struct rxe_dev *rxe = ibdev_to_rxe(device); + + if (!rxe) + return -ENODEV; + rxe_net_remove(rxe); + rxe_dev_put(rxe); + return 0; +} + +static struct rdma_link_ops rxe_link_ops = { + .type = "rxe", + .newlink = rxe_newlink, + .dellink = rxe_dellink, +}; + static int __init rxe_module_init(void) { int err; @@ -347,12 +405,14 @@ static int __init rxe_module_init(void) if (err) return err; + rdma_link_register(&rxe_link_ops); pr_info("loaded\n"); return 0; } static void __exit rxe_module_exit(void) { + rdma_link_unregister(&rxe_link_ops); rxe_remove_all(); rxe_net_exit(); rxe_cache_exit(); @@ -362,3 +422,5 @@ static void __exit rxe_module_exit(void) late_initcall(rxe_module_init); module_exit(rxe_module_exit); + +MODULE_ALIAS_RDMA_LINK("rxe"); diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h index e0c0dce80bbf..b8e754af6310 100644 --- a/drivers/infiniband/sw/rxe/rxe.h +++ b/drivers/infiniband/sw/rxe/rxe.h @@ -95,7 +95,7 @@ static inline u32 rxe_crc32(struct rxe_dev *rxe, void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); -int rxe_add(struct rxe_dev *rxe, unsigned int mtu); +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); void rxe_remove_all(void); void rxe_rcv(struct sk_buff *skb); @@ -106,6 +106,7 @@ static inline void rxe_dev_put(struct rxe_dev *rxe) } struct rxe_dev *net_to_rxe(struct net_device *ndev); struct rxe_dev *get_rxe_by_name(const char *name); +struct rxe_dev *ibdev_to_rxe(struct ib_device *device); void rxe_port_up(struct rxe_dev *rxe); void rxe_port_down(struct rxe_dev *rxe); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index f1b559d728b6..7897bcb61394 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -83,6 +83,23 @@ struct rxe_dev *get_rxe_by_name(const char *name) return found; } +struct rxe_dev *ibdev_to_rxe(struct ib_device *device) +{ + struct rxe_dev *rxe; + struct rxe_dev *found = NULL; + + spin_lock_bh(&dev_list_lock); + list_for_each_entry(rxe, &rxe_dev_list, list) { + if (&rxe->ib_dev == device) { + found = rxe; + kref_get(&rxe->ref_cnt); + break; + } + } + spin_unlock_bh(&dev_list_lock); + + return found; +} static struct rxe_recv_sockets recv_sockets; @@ -552,7 +569,7 @@ enum rdma_link_layer rxe_link_layer(struct rxe_dev *rxe, unsigned int port_num) return IB_LINK_LAYER_ETHERNET; } -struct rxe_dev *rxe_net_add(struct net_device *ndev) +struct rxe_dev *rxe_net_add(const char *ibdev_name, struct net_device *ndev) { int err; struct rxe_dev *rxe = NULL; @@ -563,7 +580,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev) rxe->ndev = ndev; - err = rxe_add(rxe, ndev->mtu); + err = rxe_add(rxe, ndev->mtu, ibdev_name); if (err) { ib_dealloc_device(&rxe->ib_dev); return NULL; diff --git a/drivers/infiniband/sw/rxe/rxe_net.h b/drivers/infiniband/sw/rxe/rxe_net.h index feb1d715468c..ced836f346ee 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.h +++ b/drivers/infiniband/sw/rxe/rxe_net.h @@ -43,7 +43,7 @@ struct rxe_recv_sockets { struct socket *sk6; }; -struct rxe_dev *rxe_net_add(struct net_device *ndev); +struct rxe_dev *rxe_net_add(const char *ibdev_name, struct net_device *ndev); void rxe_net_remove(struct rxe_dev *rxe); int rxe_net_init(void); diff --git a/drivers/infiniband/sw/rxe/rxe_sysfs.c b/drivers/infiniband/sw/rxe/rxe_sysfs.c index fc52eb3d1856..1a3410647854 100644 --- a/drivers/infiniband/sw/rxe/rxe_sysfs.c +++ b/drivers/infiniband/sw/rxe/rxe_sysfs.c @@ -97,7 +97,7 @@ static int rxe_param_set_add(const char *val, const struct kernel_param *kp) goto err; } - rxe = rxe_net_add(ndev); + rxe = rxe_net_add("rxe%d", ndev); if (!rxe) { pr_err("failed to add %s\n", intf); err = -EINVAL; @@ -152,6 +152,6 @@ static int rxe_param_set_remove(const char *val, const struct kernel_param *kp) }; module_param_cb(add, &rxe_add_ops, NULL, 0200); -MODULE_PARM_DESC(add, "Create RXE device over network interface"); +MODULE_PARM_DESC(add, "DEPRECATED. Create RXE device over network interface"); module_param_cb(remove, &rxe_remove_ops, NULL, 0200); -MODULE_PARM_DESC(remove, "Remove RXE device over network interface"); +MODULE_PARM_DESC(remove, "DEPRECATED. Remove RXE device over network interface"); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index 30817c79ba96..3536ca4627cd 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -1165,7 +1165,7 @@ static ssize_t parent_show(struct device *device, .attrs = rxe_dev_attributes, }; -int rxe_register_device(struct rxe_dev *rxe) +int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) { int err; struct ib_device *dev = &rxe->ib_dev; @@ -1273,7 +1273,7 @@ int rxe_register_device(struct rxe_dev *rxe) rdma_set_device_sysfs_group(dev, &rxe_attr_group); dev->driver_id = RDMA_DRIVER_RXE; - err = ib_register_device(dev, "rxe%d", NULL); + err = ib_register_device(dev, ibdev_name, NULL); if (err) { pr_warn("%s failed with error %d\n", __func__, err); goto err1; diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index 32c8ecb707d1..01e2e5604137 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -467,7 +467,7 @@ static inline struct rxe_mem *to_rmw(struct ib_mw *mw) return mw ? container_of(mw, struct rxe_mem, ibmw) : NULL; } -int rxe_register_device(struct rxe_dev *rxe); +int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name); void rxe_unregister_device(struct rxe_dev *rxe); void rxe_mc_cleanup(struct rxe_pool_entry *arg);