Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f71bb00 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Doug Ledford
Browse files

RDMA: Report available cdevs through RDMA_NLDEV_CMD_GET_CHARDEV



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: default avatarJason Gunthorpe <jgg@mellanox.com>
Reviewed-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 0e2d00eb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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,
+23 −0
Original line number Diff line number Diff line
@@ -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 @@ static int __init ucma_init(void)

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);
+47 −4
Original line number Diff line number Diff line
@@ -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 @@ static int __init ib_umad_init(void)

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,
+31 −1
Original line number Diff line number Diff line
@@ -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)
Loading