[PATCH rdma-next 4/6] RDMA/core: Add interface to read device namespace sharing mode

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

 



From: Parav Pandit <parav@xxxxxxxxxxxx>

Add an interface via netlink command to query whether rdma devices are
shared among multiple net namespaces or not.
When using rdma tool, it can be queried as,

$rdma sys show netns
netns: shared

Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx>
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
---
 drivers/infiniband/core/core_priv.h     |  2 ++
 drivers/infiniband/core/device.c        | 10 ++++----
 drivers/infiniband/core/net_namespace.c | 15 ++++++++++++
 drivers/infiniband/core/nldev.c         | 32 +++++++++++++++++++++++++
 include/uapi/rdma/rdma_netlink.h        | 10 +++++++-
 5 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 9ebce87c7961..1ba188efec44 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -59,6 +59,8 @@ extern struct list_head ib_device_list;
 extern struct mutex ib_device_mutex;
 extern struct rw_semaphore ib_lists_rwsem;
 
+extern ushort ib_devices_shared_netns;
+
 int  ib_device_register_sysfs(struct ib_device *device,
 			      int (*port_callback)(struct ib_device *,
 						   u8, struct kobject *));
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 12877984b10c..68934bf14f76 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -676,11 +676,13 @@ int ib_register_device(struct ib_device *device, const char *name,
 		goto cg_cleanup;
 	}
 
-	device->netns_shared = 1;
-	/* Perform this under device mutex lock, so that it can synchronize
-	 * with _init_net() to avoid duplicate additions for a given device.
+	/* Perform compat device creation under device mutex lock, so that it
+	 * can synchronize with _init_net() notifier to avoid duplicate
+	 * additions for a given device.
 	 */
-	rdma_compatdev_add(device);
+	device->netns_shared = ib_devices_shared_netns;
+	if (ib_devices_shared_netns)
+		rdma_compatdev_add(device);
 
 	device->reg_state = IB_DEV_REGISTERED;
 
diff --git a/drivers/infiniband/core/net_namespace.c b/drivers/infiniband/core/net_namespace.c
index 569049dd4216..57b1fe3d1d16 100644
--- a/drivers/infiniband/core/net_namespace.c
+++ b/drivers/infiniband/core/net_namespace.c
@@ -32,6 +32,17 @@ struct rdma_dev_net {
 };
 
 static unsigned int rdma_dev_net_id;
+/**
+ * ib_devices_shared_netns - rdma devices shared between multiple
+ *			     network namespaces or not.
+ * true = shared mode:
+ * All IB devices can be shared among multiple network namespace.
+ * This is default mode.
+ * false = single namespace mode:
+ * IB device resides in only one net namespace.
+ *
+ */
+ushort ib_devices_shared_netns = 1;
 
 static void rdma_compatdev_release(struct device *dev)
 {
@@ -180,6 +191,9 @@ static __net_init int rdma_dev_init_net(struct net *net)
 	 * which also tries to add compat devices.
 	 */
 	mutex_lock(&ib_device_mutex);
+	if (!ib_devices_shared_netns)
+		goto done;
+
 	/* Hold ib_lists_rwsem read lock; thereby not assume that
 	 * ib_device_mutex is always locked while accessing ib_device_list.
 	 */
@@ -187,6 +201,7 @@ static __net_init int rdma_dev_init_net(struct net *net)
 	list_for_each_entry(device, &ib_device_list, core_list)
 		rdma_compatdev_create(device, net);
 	up_read(&ib_lists_rwsem);
+done:
 	mutex_unlock(&ib_device_mutex);
 	return 0;
 }
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index 9591193cf285..881b620bed7a 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -107,6 +107,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
 	[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_SYS_ATTR_NETNS_MODE]	= { .type = NLA_U8 },
 };
 
 static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
@@ -1107,6 +1108,34 @@ static int nldev_res_get_pd_dumpit(struct sk_buff *skb,
 	return res_get_common_dumpit(skb, cb, RDMA_RESTRACK_PD);
 }
 
+static int nldev_get_sys_get_dumpit(struct sk_buff *skb,
+				    struct netlink_callback *cb)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+	struct nlmsghdr *nlh;
+	int err;
+
+	err = nlmsg_parse(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+			  nldev_policy, NULL);
+	if (err)
+		return err;
+
+	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
+					 RDMA_NLDEV_CMD_SYS_GET),
+			0, 0);
+
+	err = nla_put_u8(skb, RDMA_NLDEV_SYS_ATTR_NETNS_MODE,
+			 (u8)ib_devices_shared_netns);
+	if (err) {
+		nlmsg_cancel(skb, nlh);
+		return err;
+	}
+
+	nlmsg_end(skb, nlh);
+	return skb->len;
+}
+
 static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 	[RDMA_NLDEV_CMD_GET] = {
 		.doit = nldev_get_doit,
@@ -1149,6 +1178,9 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 	[RDMA_NLDEV_CMD_RES_PD_GET] = {
 		.dump = nldev_res_get_pd_dumpit,
 	},
+	[RDMA_NLDEV_CMD_SYS_GET] = {
+		.dump = nldev_get_sys_get_dumpit,
+	},
 };
 
 void __init nldev_init(void)
diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h
index 2e18b77a817f..1cda30f392e7 100644
--- a/include/uapi/rdma/rdma_netlink.h
+++ b/include/uapi/rdma/rdma_netlink.h
@@ -229,7 +229,9 @@ enum rdma_nldev_command {
 	RDMA_NLDEV_CMD_GET, /* can dump */
 	RDMA_NLDEV_CMD_SET,
 
-	/* 3 - 4 are free to use */
+	RDMA_NLDEV_CMD_SYS_GET, /* can dump */
+
+	/* 4 is free to use */
 
 	RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */
 
@@ -430,6 +432,12 @@ enum rdma_nldev_attr {
 	RDMA_NLDEV_ATTR_DRIVER_S64,		/* s64 */
 	RDMA_NLDEV_ATTR_DRIVER_U64,		/* u64 */
 
+	/*
+	 * net namespace mode for rdma subsystem:
+	 * either shared or exclusive among multiple net namespaces.
+	 */
+	RDMA_NLDEV_SYS_ATTR_NETNS_MODE,		/* u8 */
+
 	/*
 	 * Always the end
 	 */
-- 
2.19.1




[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