rdma_rxe: Use netlink messages to add/delete links
authorSteve Wise <swise@opengridcomputing.com>
Fri, 15 Feb 2019 19:03:57 +0000 (11:03 -0800)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 20 Feb 2019 03:52:19 +0000 (20:52 -0700)
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>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/sw/rxe/rxe.c
drivers/infiniband/sw/rxe/rxe.h
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_net.h
drivers/infiniband/sw/rxe/rxe_param.h
drivers/infiniband/sw/rxe/rxe_sysfs.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/sw/rxe/rxe_verbs.h

index 08a45ce9cab5510e9a0426b703dee57d15dc9f68..a8c11b5e1e943068cb798a753addcfb32d4bdca1 100644 (file)
@@ -31,6 +31,7 @@
  * SOFTWARE.
  */
 
+#include <rdma/rdma_netlink.h>
 #include <net/addrconf.h>
 #include "rxe.h"
 #include "rxe_loc.h"
@@ -301,7 +302,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;
 
@@ -311,9 +312,36 @@ int rxe_add(struct rxe_dev *rxe, unsigned int mtu)
 
        rxe_set_mtu(rxe, mtu);
 
-       return rxe_register_device(rxe);
+       return rxe_register_device(rxe, ibdev_name);
 }
 
+static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)
+{
+       struct rxe_dev *exists;
+       int err = 0;
+
+       exists = rxe_get_dev_from_net(ndev);
+       if (exists) {
+               ib_device_put(&exists->ib_dev);
+               pr_err("already configured on %s\n", ndev->name);
+               err = -EEXIST;
+               goto err;
+       }
+
+       err = rxe_net_add(ibdev_name, ndev);
+       if (err) {
+               pr_err("failed to add %s\n", ndev->name);
+               goto err;
+       }
+err:
+       return err;
+}
+
+static struct rdma_link_ops rxe_link_ops = {
+       .type = "rxe",
+       .newlink = rxe_newlink,
+};
+
 static int __init rxe_module_init(void)
 {
        int err;
@@ -329,12 +357,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);
        ib_unregister_driver(RDMA_DRIVER_RXE);
        rxe_net_exit();
        rxe_cache_exit();
@@ -344,3 +374,5 @@ static void __exit rxe_module_exit(void)
 
 late_initcall(rxe_module_init);
 module_exit(rxe_module_exit);
+
+MODULE_ALIAS_RDMA_LINK("rxe");
index 63b3b89b894a2eb1c03c293950258f345d1d0ed6..2e2dff478833473ea106f6c0687cc09a7d0ec2d7 100644 (file)
@@ -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_rcv(struct sk_buff *skb);
 
index fb792f5bc0b7d49f8b69e60728b15a7f3f20bd6f..753cabcd441c91b6e1977569e3bc99445b2aac3a 100644 (file)
@@ -517,7 +517,7 @@ enum rdma_link_layer rxe_link_layer(struct rxe_dev *rxe, unsigned int port_num)
        return IB_LINK_LAYER_ETHERNET;
 }
 
-int rxe_net_add(struct net_device *ndev)
+int rxe_net_add(const char *ibdev_name, struct net_device *ndev)
 {
        int err;
        struct rxe_dev *rxe = NULL;
@@ -528,7 +528,7 @@ int 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 err;
index ad79514191bb9daf5fefda041dd9bea8da68aaae..2ca71d3d245ced2cd9034caf14a1f257dfc42915 100644 (file)
@@ -43,7 +43,7 @@ struct rxe_recv_sockets {
        struct socket *sk6;
 };
 
-int rxe_net_add(struct net_device *ndev);
+int rxe_net_add(const char *ibdev_name, struct net_device *ndev);
 
 int rxe_net_init(void);
 void rxe_net_exit(void);
index bdea899a58ac7f6a448d446aa6045c9019c68f81..1abed47ca22170b7f7c1d84ae1a6769415f24869 100644 (file)
@@ -78,7 +78,8 @@ enum rxe_device_param {
                                        | IB_DEVICE_SYS_IMAGE_GUID
                                        | IB_DEVICE_RC_RNR_NAK_GEN
                                        | IB_DEVICE_SRQ_RESIZE
-                                       | IB_DEVICE_MEM_MGT_EXTENSIONS,
+                                       | IB_DEVICE_MEM_MGT_EXTENSIONS
+                                       | IB_DEVICE_ALLOW_USER_UNREG,
        RXE_MAX_SGE                     = 32,
        RXE_MAX_SGE_RD                  = 32,
        RXE_MAX_CQ                      = 16384,
index 46587eb0da0e633517813f3301e9257890a2308a..ccda5f5a3bc0aad81915936e2c1d4e349de60e86 100644 (file)
@@ -81,7 +81,7 @@ static int rxe_param_set_add(const char *val, const struct kernel_param *kp)
                goto err;
        }
 
-       err = rxe_net_add(ndev);
+       err = rxe_net_add("rxe%d", ndev);
        if (err) {
                pr_err("failed to add %s\n", intf);
                goto err;
@@ -130,6 +130,6 @@ static const struct kernel_param_ops rxe_remove_ops = {
 };
 
 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");
index 79ad93b4140cea3dccc1d3000a52f5fefd6a67b8..bd6a379b79d34b686ec8037cb8e25ecca4222743 100644 (file)
@@ -1182,7 +1182,7 @@ static const struct ib_device_ops rxe_dev_ops = {
        INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd),
 };
 
-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;
@@ -1251,7 +1251,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");
+       err = ib_register_device(dev, ibdev_name);
        if (err)
                pr_warn("%s failed with error %d\n", __func__, err);
 
index a22822526a62c60cb89c8fad4a30e529e26af3f2..d02eb75ef282b9e5288f49ca82004103744cc526 100644 (file)
@@ -464,7 +464,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_mc_cleanup(struct rxe_pool_entry *arg);