OSDN Git Service

RDMA: Report available cdevs through RDMA_NLDEV_CMD_GET_CHARDEV
authorJason Gunthorpe <jgg@mellanox.com>
Fri, 14 Jun 2019 00:38:19 +0000 (21:38 -0300)
committerDoug Ledford <dledford@redhat.com>
Wed, 19 Jun 2019 02:44:08 +0000 (22:44 -0400)
Update the struct ib_client for all modules exporting cdevs related to the
ibdevice to also implement RDMA_NLDEV_CMD_GET_CHARDEV. All cdevs are now
autoloadable and discoverable by userspace over netlink instead of relying
on sysfs.

uverbs also exposes the DRIVER_ID for drivers that are able to support
driver id binding in rdma-core.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/device.c
drivers/infiniband/core/nldev.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/mthca/mthca_provider.c
include/rdma/ib_verbs.h
include/uapi/rdma/rdma_netlink.h

index 7db8566..1de4ae5 100644 (file)
@@ -2428,6 +2428,9 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
        if (ops->uverbs_abi_ver)
                dev_ops->uverbs_abi_ver = ops->uverbs_abi_ver;
 
+       dev_ops->uverbs_no_driver_id_binding |=
+               ops->uverbs_no_driver_id_binding;
+
        SET_DEVICE_OP(dev_ops, add_gid);
        SET_DEVICE_OP(dev_ops, advise_mr);
        SET_DEVICE_OP(dev_ops, alloc_dm);
index 16b5d6d..3cad72a 100644 (file)
@@ -126,6 +126,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
                                    .len = 128 },
        [RDMA_NLDEV_ATTR_CHARDEV_NAME]          = { .type = NLA_NUL_STRING,
                                    .len = RDMA_NLDEV_ATTR_ENTRY_STRLEN },
+       [RDMA_NLDEV_ATTR_UVERBS_DRIVER_ID]      = { .type = NLA_U32 },
 };
 
 static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
index 39823c8..0274e9b 100644 (file)
@@ -52,6 +52,8 @@
 #include <rdma/rdma_cm_ib.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib.h>
+#include <rdma/rdma_netlink.h>
+#include "core_priv.h"
 
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -1788,6 +1790,19 @@ static struct miscdevice ucma_misc = {
        .fops           = &ucma_fops,
 };
 
+static int ucma_get_global_nl_info(struct ib_client_nl_info *res)
+{
+       res->abi = RDMA_USER_CM_ABI_VERSION;
+       res->cdev = ucma_misc.this_device;
+       return 0;
+}
+
+static struct ib_client rdma_cma_client = {
+       .name = "rdma_cm",
+       .get_global_nl_info = ucma_get_global_nl_info,
+};
+MODULE_ALIAS_RDMA_CLIENT("rdma_cm");
+
 static ssize_t show_abi_version(struct device *dev,
                                struct device_attribute *attr,
                                char *buf)
@@ -1816,7 +1831,14 @@ static int __init ucma_init(void)
                ret = -ENOMEM;
                goto err2;
        }
+
+       ret = ib_register_client(&rdma_cma_client);
+       if (ret)
+               goto err3;
+
        return 0;
+err3:
+       unregister_net_sysctl_table(ucma_ctl_table_hdr);
 err2:
        device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
 err1:
@@ -1826,6 +1848,7 @@ err1:
 
 static void __exit ucma_cleanup(void)
 {
+       ib_unregister_client(&rdma_cma_client);
        unregister_net_sysctl_table(ucma_ctl_table_hdr);
        device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
        misc_deregister(&ucma_misc);
index 671f07b..547090b 100644 (file)
@@ -54,6 +54,7 @@
 
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_mad.h>
+#include <rdma/rdma_netlink.h>
 
 #include "core_priv.h"
 
@@ -1124,11 +1125,48 @@ static const struct file_operations umad_sm_fops = {
        .llseek  = no_llseek,
 };
 
+static int ib_umad_get_nl_info(struct ib_device *ibdev, void *client_data,
+                              struct ib_client_nl_info *res)
+{
+       struct ib_umad_device *umad_dev = client_data;
+
+       if (!rdma_is_port_valid(ibdev, res->port))
+               return -EINVAL;
+
+       res->abi = IB_USER_MAD_ABI_VERSION;
+       res->cdev = &umad_dev->ports[res->port - rdma_start_port(ibdev)].dev;
+
+       return 0;
+}
+
 static struct ib_client umad_client = {
        .name   = "umad",
        .add    = ib_umad_add_one,
-       .remove = ib_umad_remove_one
+       .remove = ib_umad_remove_one,
+       .get_nl_info = ib_umad_get_nl_info,
 };
+MODULE_ALIAS_RDMA_CLIENT("umad");
+
+static int ib_issm_get_nl_info(struct ib_device *ibdev, void *client_data,
+                              struct ib_client_nl_info *res)
+{
+       struct ib_umad_device *umad_dev =
+               ib_get_client_data(ibdev, &umad_client);
+
+       if (!rdma_is_port_valid(ibdev, res->port))
+               return -EINVAL;
+
+       res->abi = IB_USER_MAD_ABI_VERSION;
+       res->cdev = &umad_dev->ports[res->port - rdma_start_port(ibdev)].sm_dev;
+
+       return 0;
+}
+
+static struct ib_client issm_client = {
+       .name = "issm",
+       .get_nl_info = ib_issm_get_nl_info,
+};
+MODULE_ALIAS_RDMA_CLIENT("issm");
 
 static ssize_t ibdev_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
@@ -1387,13 +1425,17 @@ static int __init ib_umad_init(void)
        }
 
        ret = ib_register_client(&umad_client);
-       if (ret) {
-               pr_err("couldn't register ib_umad client\n");
+       if (ret)
                goto out_class;
-       }
+
+       ret = ib_register_client(&issm_client);
+       if (ret)
+               goto out_client;
 
        return 0;
 
+out_client:
+       ib_unregister_client(&umad_client);
 out_class:
        class_unregister(&umad_class);
 
@@ -1411,6 +1453,7 @@ out:
 
 static void __exit ib_umad_cleanup(void)
 {
+       ib_unregister_client(&issm_client);
        ib_unregister_client(&umad_client);
        class_unregister(&umad_class);
        unregister_chrdev_region(base_umad_dev,
index 870b3dd..11c13c1 100644 (file)
@@ -51,6 +51,7 @@
 
 #include <rdma/ib.h>
 #include <rdma/uverbs_std_types.h>
+#include <rdma/rdma_netlink.h>
 
 #include "uverbs.h"
 #include "core_priv.h"
@@ -1148,12 +1149,41 @@ static const struct file_operations uverbs_mmap_fops = {
        .compat_ioctl = ib_uverbs_ioctl,
 };
 
+static int ib_uverbs_get_nl_info(struct ib_device *ibdev, void *client_data,
+                                struct ib_client_nl_info *res)
+{
+       struct ib_uverbs_device *uverbs_dev = client_data;
+       int ret;
+
+       if (res->port != -1)
+               return -EINVAL;
+
+       res->abi = ibdev->ops.uverbs_abi_ver;
+       res->cdev = &uverbs_dev->dev;
+
+       /*
+        * To support DRIVER_ID binding in userspace some of the driver need
+        * upgrading to expose their PCI dependent revision information
+        * through get_context instead of relying on modalias matching. When
+        * the drivers are fixed they can drop this flag.
+        */
+       if (!ibdev->ops.uverbs_no_driver_id_binding) {
+               ret = nla_put_u32(res->nl_msg, RDMA_NLDEV_ATTR_UVERBS_DRIVER_ID,
+                                 ibdev->ops.driver_id);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
 static struct ib_client uverbs_client = {
        .name   = "uverbs",
        .no_kverbs_req = true,
        .add    = ib_uverbs_add_one,
-       .remove = ib_uverbs_remove_one
+       .remove = ib_uverbs_remove_one,
+       .get_nl_info = ib_uverbs_get_nl_info,
 };
+MODULE_ALIAS_RDMA_CLIENT("uverbs");
 
 static ssize_t ibdev_show(struct device *device, struct device_attribute *attr,
                          char *buf)
index acba96f..810fa96 100644 (file)
@@ -1230,6 +1230,7 @@ static const struct ib_device_ops iwch_dev_ops = {
        .owner = THIS_MODULE,
        .driver_id = RDMA_DRIVER_CXGB3,
        .uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION,
+       .uverbs_no_driver_id_binding = 1,
 
        .alloc_hw_stats = iwch_alloc_stats,
        .alloc_mr = iwch_alloc_mr,
index 3e45b11..c0e819e 100644 (file)
@@ -417,6 +417,7 @@ static const struct ib_device_ops hns_roce_dev_ops = {
        .owner = THIS_MODULE,
        .driver_id = RDMA_DRIVER_HNS,
        .uverbs_abi_ver = 1,
+       .uverbs_no_driver_id_binding = 1,
 
        .add_gid = hns_roce_add_gid,
        .alloc_pd = hns_roce_alloc_pd,
index efd4e3d..d97124b 100644 (file)
@@ -1147,6 +1147,7 @@ static const struct ib_device_ops mthca_dev_ops = {
        .owner = THIS_MODULE,
        .driver_id = RDMA_DRIVER_MTHCA,
        .uverbs_abi_ver = MTHCA_UVERBS_ABI_VERSION,
+       .uverbs_no_driver_id_binding = 1,
 
        .alloc_pd = mthca_alloc_pd,
        .alloc_ucontext = mthca_alloc_ucontext,
index a1265e9..6f09fcc 100644 (file)
@@ -2321,6 +2321,7 @@ struct ib_device_ops {
        struct module *owner;
        enum rdma_driver_id driver_id;
        u32 uverbs_abi_ver;
+       unsigned int uverbs_no_driver_id_binding:1;
 
        int (*post_send)(struct ib_qp *qp, const struct ib_send_wr *send_wr,
                         const struct ib_send_wr **bad_send_wr);
index 9903db2..b27c021 100644 (file)
@@ -504,6 +504,7 @@ enum rdma_nldev_attr {
        RDMA_NLDEV_ATTR_CHARDEV_NAME,           /* string */
        RDMA_NLDEV_ATTR_CHARDEV_ABI,            /* u64 */
        RDMA_NLDEV_ATTR_CHARDEV,                /* u64 */
+       RDMA_NLDEV_ATTR_UVERBS_DRIVER_ID,       /* u64 */
 
        /*
         * Always the end