Re: [PATCH v3 1/2] RDMA/Core: add RDMA_NLDEV_CMD_NEWLINK/DELLINK support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey Mike,


On 11/29/2018 7:29 PM, Ruhl, Michael J wrote:
>> -----Original Message-----
>> From: linux-rdma-owner@xxxxxxxxxxxxxxx [mailto:linux-rdma-
>> owner@xxxxxxxxxxxxxxx] On Behalf Of Steve Wise
>> Sent: Tuesday, November 27, 2018 10:37 AM
>> To: dledford@xxxxxxxxxx; jgg@xxxxxxxxxxxx
>> Cc: linux-rdma@xxxxxxxxxxxxxxx; BMT@xxxxxxxxxxxxxx
>> Subject: [PATCH v3 1/2] RDMA/Core: add
>> RDMA_NLDEV_CMD_NEWLINK/DELLINK support
>>
>> Add support for new LINK messages to allow adding and deleting rdma
>> interfaces.  This will be used initially for soft rdma drivers which
>> instantiate device instances dynamically by the admin specifying a
>> netdev device to use.  The rdma_rxe module will be the first user of
>> these messages.
>>
>> The design is modeled after RTNL_NEWLINK/DELLINK:  rdma drivers
>> register with the rdma core if they provide link add/delete functions.
>> Each driver registers with a unique "type" string, that is used to
>> dispatch messages coming from user space.  A new RDMA_NLDEV_ATTR is
>> defined for the "type" string.  User mode will pass 3 attributes in a
>> NEWLINK message: RDMA_NLDEV_ATTR_IBDEV_NAME for the desired rdma
>> device
>> name to be created, RDMA_NLDEV_ATTR_LINK_TYPE for the "type" of link
>> being added, and RDMA_NLDEV_ATTR_NDEV_NAME for the net_device interface
>> to use for this link. The DELLINK message will contain the IBDEV_NAME
>> and LINK_TYPE attributes.
>>
>> Signed-off-by: Steve Wise <swise@xxxxxxxxxxxxxxxxxxxxx>
>> Reviewed-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
>> ---
>> drivers/infiniband/core/nldev.c  | 131
>> +++++++++++++++++++++++++++++++++++++++
>> include/rdma/rdma_netlink.h      |  12 ++++
>> include/uapi/rdma/rdma_netlink.h |  11 +++-
>> 3 files changed, 152 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
>> index 63cc74483188..04d8af0ccb25 100644
>> --- a/drivers/infiniband/core/nldev.c
>> +++ b/drivers/infiniband/core/nldev.c
>> @@ -33,6 +33,7 @@
>> #include <linux/module.h>
>> #include <linux/pid.h>
>> #include <linux/pid_namespace.h>
>> +#include <linux/mutex.h>
>> #include <net/netlink.h>
>> #include <rdma/rdma_cm.h>
>> #include <rdma/rdma_netlink.h>
>> @@ -107,6 +108,8 @@
>> 	[RDMA_NLDEV_ATTR_DRIVER_U32]		= { .type = NLA_U32 },
>> 	[RDMA_NLDEV_ATTR_DRIVER_S64]		= { .type = NLA_S64 },
>> 	[RDMA_NLDEV_ATTR_DRIVER_U64]		= { .type = NLA_U64 },
>> +	[RDMA_NLDEV_ATTR_LINK_TYPE]		= { .type =
>> NLA_NUL_STRING,
>> +				    .len = RDMA_NLDEV_ATTR_ENTRY_STRLEN },
>> };
>>
>> static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
>> @@ -1103,6 +1106,126 @@ static int nldev_res_get_pd_dumpit(struct sk_buff
>> *skb,
>> 	return res_get_common_dumpit(skb, cb, RDMA_RESTRACK_PD);
>> }
>>
>> +static LIST_HEAD(link_ops);
>> +static DEFINE_MUTEX(link_ops_mutex);
>> +
>> +static const struct rdma_link_ops *link_ops_get(const char *type)
>> +{
>> +	const struct rdma_link_ops *ops;
>> +
>> +	list_for_each_entry(ops, &link_ops, list) {
>> +		if (!strcmp(ops->type, type))
>> +			goto out;
>> +	}
>> +	ops = NULL;
>> +out:
>> +	return ops;
>> +}
>> +
>> +void rdma_link_register(struct rdma_link_ops *ops)
>> +{
>> +	mutex_lock(&link_ops_mutex);
>> +	if (link_ops_get(ops->type)) {
>> +		WARN_ONCE("Duplicate rdma_link_ops! %s\n", ops->type);
>> +		goto out;
>> +	}
>> +	list_add(&ops->list, &link_ops);
>> +out:
>> +	mutex_unlock(&link_ops_mutex);
>> +}
>> +EXPORT_SYMBOL(rdma_link_register);
>> +
>> +void rdma_link_unregister(struct rdma_link_ops *ops)
>> +{
>> +	mutex_lock(&link_ops_mutex);
>> +	list_del(&ops->list);
>> +	mutex_unlock(&link_ops_mutex);
>> +}
>> +EXPORT_SYMBOL(rdma_link_unregister);
>> +
>> +static int nldev_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>> +			  struct netlink_ext_ack *extack)
>> +{
>> +	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
>> +	char ibdev_name[IB_DEVICE_NAME_MAX];
>> +	const struct rdma_link_ops *ops;
>> +	char ndev_name[IFNAMSIZ];
>> +	char type[IFNAMSIZ];
>> +	int err;
>> +
>> +	err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
>> +			  nldev_policy, extack);
>> +	if (err || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
>> +	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] ||
>> !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
>> +		return -EINVAL;
>> +
>> +	if (nla_len(tb[RDMA_NLDEV_ATTR_DEV_NAME]) > sizeof(ibdev_name) ||
>> +	    nla_len(tb[RDMA_NLDEV_ATTR_LINK_TYPE]) > sizeof(type) ||
>> +	    nla_len(tb[RDMA_NLDEV_ATTR_NDEV_NAME]) > sizeof(ndev_name))
>> +		return -EINVAL;
>> +
>> +	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
>> +		    sizeof(ibdev_name));
>> +	if (strchr(ibdev_name, '%'))
>> +		return -EINVAL;
>> +
>> +	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
>> +	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
>> +		    sizeof(ndev_name));
>> +
>> +	mutex_lock(&link_ops_mutex);
>> +	ops = link_ops_get(type);
>> +#ifdef CONFIG_MODULES
>> +	if (!ops) {
>> +		mutex_unlock(&link_ops_mutex);
>> +		request_module("rdma-link-%s", type);
>> +		mutex_lock(&link_ops_mutex);
>> +		ops = link_ops_get(type);
>> +	}
>> +#endif
>> +	if (ops)
>> +		err = ops->newlink(ibdev_name, ndev_name);
>> +	else
>> +		err = -ENODEV;
>> +	mutex_unlock(&link_ops_mutex);
> Hi Steve,
>
> Should the mutex be held while calling the callback?  If the newlink or dellink
> callbacks need to sleep (probably dellink specifically), I think holding the mutex
> might not be a good idea.
>
> Mike

It is required to ensure the link_ops don't get unregistered while in
use.   See our previous discussion:

https://www.spinics.net/lists/linux-rdma/msg70989.html

Thanks,

Steve.




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux