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@xxxxxxxxxxxx>
Signed-off-by: Steve Wise <swise@xxxxxxxxxxxxxxxxxxxxx>
---
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);