Message ID | 807020fe6f05364ca793851390252cfdfd8cfb69.1543615225.git.swise@opengridcomputing.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Dynamic rdma link creation | expand |
On 2018/12/1 5:58, 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> > Signed-off-by: Steve Wise <swise@opengridcomputing.com> > --- > drivers/infiniband/sw/rxe/rxe.c | 62 +++++++++++++++++++++++++++++++++-- > drivers/infiniband/sw/rxe/rxe.h | 2 +- > drivers/infiniband/sw/rxe/rxe_net.c | 4 +-- > 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, 70 insertions(+), 12 deletions(-) > > diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c > index 383e65c7bbc0..c09534b513ff 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" > @@ -308,7 +309,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; > > @@ -320,7 +321,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; > > @@ -339,6 +340,59 @@ void rxe_remove(struct rxe_dev *rxe) > rxe_dev_put(rxe); > } > > +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; > + } > + > + if (net_to_rxe(ndev)) { > + pr_err("already configured on %s\n", ndev_name); > + err = -EEXIST; > + 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 = to_rdev(device); > + diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index c09534b513ff..e19d575d276f 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -382,7 +382,7 @@ static int rxe_dellink(struct ib_device *device) { struct rxe_dev *rxe = to_rdev(device); - list_del(&rxe->list); + rxe_net_remove(rxe); rxe_remove(rxe); return 0; } diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index 10a38b76f24b..1b57710008d3 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -573,6 +573,13 @@ struct rxe_dev *rxe_net_add(const char *ibdev_name, struct net_device *ndev) return rxe; } +void rxe_net_remove(struct rxe_dev *rxe) +{ + spin_lock_bh(&dev_list_lock); + list_del(&rxe->list); + spin_unlock_bh(&dev_list_lock); +} + void rxe_remove_all(void) { spin_lock_bh(&dev_list_lock); diff --git a/drivers/infiniband/sw/rxe/rxe_net.h b/drivers/infiniband/sw/rxe/rxe_net.h index f8e00e6d5d38..45bf15fab87f 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.h +++ b/drivers/infiniband/sw/rxe/rxe_net.h @@ -44,6 +44,7 @@ struct rxe_recv_sockets { }; 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); void rxe_net_exit(void); > + list_del(&rxe->list); To avoid race, list_del(&rxe->list); should be replace the above. If I am wrong, please correct me. Zhu Yanjun > + rxe_remove(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; > @@ -354,12 +408,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(); > @@ -369,3 +425,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 8f79bd86d033..e6e91fb14af8 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(struct rxe_dev *rxe); > void rxe_remove_all(void); > > diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c > index b26a8141f3ed..8bb908cae71b 100644 > --- a/drivers/infiniband/sw/rxe/rxe_net.c > +++ b/drivers/infiniband/sw/rxe/rxe_net.c > @@ -550,7 +550,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; > @@ -561,7 +561,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 106c586dbb26..f8e00e6d5d38 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); > > int rxe_net_init(void); > void rxe_net_exit(void); > diff --git a/drivers/infiniband/sw/rxe/rxe_sysfs.c b/drivers/infiniband/sw/rxe/rxe_sysfs.c > index 73a19f808e1b..629f824d8d3e 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 831381b7788d..c5f336d9aaf2 100644 > --- a/drivers/infiniband/sw/rxe/rxe_verbs.h > +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h > @@ -466,7 +466,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);
On 12/3/2018 12:34 AM, Yanjun Zhu wrote: > > On 2018/12/1 5:58, 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> >> Signed-off-by: Steve Wise <swise@opengridcomputing.com> >> --- >> drivers/infiniband/sw/rxe/rxe.c | 62 >> +++++++++++++++++++++++++++++++++-- >> drivers/infiniband/sw/rxe/rxe.h | 2 +- >> drivers/infiniband/sw/rxe/rxe_net.c | 4 +-- >> 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, 70 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/infiniband/sw/rxe/rxe.c >> b/drivers/infiniband/sw/rxe/rxe.c >> index 383e65c7bbc0..c09534b513ff 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" >> @@ -308,7 +309,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; >> @@ -320,7 +321,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; >> @@ -339,6 +340,59 @@ void rxe_remove(struct rxe_dev *rxe) >> rxe_dev_put(rxe); >> } >> +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; >> + } >> + >> + if (net_to_rxe(ndev)) { >> + pr_err("already configured on %s\n", ndev_name); >> + err = -EEXIST; >> + 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 = to_rdev(device); >> + > diff --git a/drivers/infiniband/sw/rxe/rxe.c > b/drivers/infiniband/sw/rxe/rxe.c > index c09534b513ff..e19d575d276f 100644 > --- a/drivers/infiniband/sw/rxe/rxe.c > +++ b/drivers/infiniband/sw/rxe/rxe.c > @@ -382,7 +382,7 @@ static int rxe_dellink(struct ib_device *device) > { > struct rxe_dev *rxe = to_rdev(device); > > - list_del(&rxe->list); > + rxe_net_remove(rxe); > rxe_remove(rxe); > return 0; > } > diff --git a/drivers/infiniband/sw/rxe/rxe_net.c > b/drivers/infiniband/sw/rxe/rxe_net.c > index 10a38b76f24b..1b57710008d3 100644 > --- a/drivers/infiniband/sw/rxe/rxe_net.c > +++ b/drivers/infiniband/sw/rxe/rxe_net.c > @@ -573,6 +573,13 @@ struct rxe_dev *rxe_net_add(const char > *ibdev_name, struct net_device *ndev) > return rxe; > } > > +void rxe_net_remove(struct rxe_dev *rxe) > +{ > + spin_lock_bh(&dev_list_lock); > + list_del(&rxe->list); > + spin_unlock_bh(&dev_list_lock); > +} > + > void rxe_remove_all(void) > { > spin_lock_bh(&dev_list_lock); > diff --git a/drivers/infiniband/sw/rxe/rxe_net.h > b/drivers/infiniband/sw/rxe/rxe_net.h > index f8e00e6d5d38..45bf15fab87f 100644 > --- a/drivers/infiniband/sw/rxe/rxe_net.h > +++ b/drivers/infiniband/sw/rxe/rxe_net.h > @@ -44,6 +44,7 @@ struct rxe_recv_sockets { > }; > > 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); > void rxe_net_exit(void); > >> + list_del(&rxe->list); > > To avoid race, list_del(&rxe->list); should be replace the above. > > If I am wrong, please correct me. > > Zhu Yanjun > Yes, you're correct. This code is not serialized at all for device removal. As Jason requested, I'll address this all in the next version and hopefully get it right. :) Thanks for the review. May I add a reviewed-by tag from you? Steve.
On 2018/12/4 0:26, Steve Wise wrote: > > On 12/3/2018 12:34 AM, Yanjun Zhu wrote: >> On 2018/12/1 5:58, 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> >>> Signed-off-by: Steve Wise <swise@opengridcomputing.com> >>> --- >>> drivers/infiniband/sw/rxe/rxe.c | 62 >>> +++++++++++++++++++++++++++++++++-- >>> drivers/infiniband/sw/rxe/rxe.h | 2 +- >>> drivers/infiniband/sw/rxe/rxe_net.c | 4 +-- >>> 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, 70 insertions(+), 12 deletions(-) >>> >>> diff --git a/drivers/infiniband/sw/rxe/rxe.c >>> b/drivers/infiniband/sw/rxe/rxe.c >>> index 383e65c7bbc0..c09534b513ff 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" >>> @@ -308,7 +309,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; >>> @@ -320,7 +321,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; >>> @@ -339,6 +340,59 @@ void rxe_remove(struct rxe_dev *rxe) >>> rxe_dev_put(rxe); >>> } >>> +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; >>> + } >>> + >>> + if (net_to_rxe(ndev)) { >>> + pr_err("already configured on %s\n", ndev_name); >>> + err = -EEXIST; >>> + 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 = to_rdev(device); >>> + >> diff --git a/drivers/infiniband/sw/rxe/rxe.c >> b/drivers/infiniband/sw/rxe/rxe.c >> index c09534b513ff..e19d575d276f 100644 >> --- a/drivers/infiniband/sw/rxe/rxe.c >> +++ b/drivers/infiniband/sw/rxe/rxe.c >> @@ -382,7 +382,7 @@ static int rxe_dellink(struct ib_device *device) >> { >> struct rxe_dev *rxe = to_rdev(device); >> >> - list_del(&rxe->list); >> + rxe_net_remove(rxe); >> rxe_remove(rxe); >> return 0; >> } >> diff --git a/drivers/infiniband/sw/rxe/rxe_net.c >> b/drivers/infiniband/sw/rxe/rxe_net.c >> index 10a38b76f24b..1b57710008d3 100644 >> --- a/drivers/infiniband/sw/rxe/rxe_net.c >> +++ b/drivers/infiniband/sw/rxe/rxe_net.c >> @@ -573,6 +573,13 @@ struct rxe_dev *rxe_net_add(const char >> *ibdev_name, struct net_device *ndev) >> return rxe; >> } >> >> +void rxe_net_remove(struct rxe_dev *rxe) >> +{ >> + spin_lock_bh(&dev_list_lock); >> + list_del(&rxe->list); >> + spin_unlock_bh(&dev_list_lock); >> +} >> + >> void rxe_remove_all(void) >> { >> spin_lock_bh(&dev_list_lock); >> diff --git a/drivers/infiniband/sw/rxe/rxe_net.h >> b/drivers/infiniband/sw/rxe/rxe_net.h >> index f8e00e6d5d38..45bf15fab87f 100644 >> --- a/drivers/infiniband/sw/rxe/rxe_net.h >> +++ b/drivers/infiniband/sw/rxe/rxe_net.h >> @@ -44,6 +44,7 @@ struct rxe_recv_sockets { >> }; >> >> 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); >> void rxe_net_exit(void); >> >>> + list_del(&rxe->list); >> To avoid race, list_del(&rxe->list); should be replace the above. >> >> If I am wrong, please correct me. >> >> Zhu Yanjun >> > Yes, you're correct. This code is not serialized at all for device > removal. As Jason requested, I'll address this all in the next version > and hopefully get it right. :) > > Thanks for the review. May I add a reviewed-by tag from you? Yes. You can:-). Zhu Yanjun > > Steve.
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 383e65c7bbc0..c09534b513ff 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" @@ -308,7 +309,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; @@ -320,7 +321,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; @@ -339,6 +340,59 @@ void rxe_remove(struct rxe_dev *rxe) rxe_dev_put(rxe); } +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; + } + + if (net_to_rxe(ndev)) { + pr_err("already configured on %s\n", ndev_name); + err = -EEXIST; + 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 = to_rdev(device); + + list_del(&rxe->list); + rxe_remove(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; @@ -354,12 +408,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(); @@ -369,3 +425,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 8f79bd86d033..e6e91fb14af8 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(struct rxe_dev *rxe); void rxe_remove_all(void); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index b26a8141f3ed..8bb908cae71b 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -550,7 +550,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; @@ -561,7 +561,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 106c586dbb26..f8e00e6d5d38 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); int rxe_net_init(void); void rxe_net_exit(void); diff --git a/drivers/infiniband/sw/rxe/rxe_sysfs.c b/drivers/infiniband/sw/rxe/rxe_sysfs.c index 73a19f808e1b..629f824d8d3e 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 831381b7788d..c5f336d9aaf2 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -466,7 +466,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);
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> Signed-off-by: Steve Wise <swise@opengridcomputing.com> --- drivers/infiniband/sw/rxe/rxe.c | 62 +++++++++++++++++++++++++++++++++-- drivers/infiniband/sw/rxe/rxe.h | 2 +- drivers/infiniband/sw/rxe/rxe_net.c | 4 +-- 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, 70 insertions(+), 12 deletions(-)