Linux s390 Architecture development
 help / color / mirror / Atom feed
* [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace
@ 2026-07-16 13:23 Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 01/14] RDMA/core: Pass the net namespace to the device name lookups Jiri Pirko
                   ` (13 more replies)
  0 siblings, 14 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

RDMA device names are unique system-wide today:
__ib_device_get_by_name() checks a requested name against every
registered device regardless of the network namespace it lives in.
A device in one network namespace therefore cannot use a name already
taken in another, even in exclusive netns mode (netns_mode=0) where
the two are otherwise isolated. Net devices have no such restriction -
their names only need to be unique within a network namespace.

This series makes RDMA device names unique per network namespace,
matching net device semantics, and adapts the users that assumed
system-wide unique names.

Scoping reuses the existing rdma_dev_access_netns() predicate, so
behavior only changes in exclusive mode:
  - shared mode (default): names stay unique system-wide, no change;
  - exclusive mode: names only need to be unique within a namespace;
  - CONFIG_NET_NS=n: everything is init_net, names stay system-wide
    unique.

There are two users that cannot be made per-namespace and are
documented as known limitations instead of changed:
  - the rdma_cm configfs tree: configfs has no network namespace
    support, so it cannot represent two same-named devices;
  - SELinux ibendport labelling: endports are labelled by (device
    name, port) from a global policy; distinguishing same-named
    devices would need net namespace support in the SELinux policy
    language and tooling.

Tested with the new rxe_netns_names kselftest added in the last patch.

Jiri Pirko (14):
  RDMA/core: Pass the net namespace to the device name lookups
  RDMA/core: Handle device name conflicts when changing net namespace
  RDMA/core: Support renaming a device when changing its net namespace
  RDMA/nldev: Report net namespace move errors through extack
  RDMA/nldev: Allow setting the device name while changing net namespace
  net/smc: Look up the pnetid ib device within the net namespace
  RDMA/srp: Make the SRP sysfs class net namespace aware
  RDMA/cgroup: Disambiguate devices across net namespaces
  RDMA/cma: Document that CM configfs cannot be net namespace scoped
  RDMA/core: Document the SELinux ibendport net namespace limitation
  RDMA/core: Make device names unique per net namespace
  RDMA/rxe: Allow queue VMAs to outlive ucontexts
  RDMA/rxe: Implement disassociate_ucontext callback
  RDMA/selftests: Add rxe_netns_names test

 Documentation/ABI/testing/configfs-rdma_cm    |   4 +
 Documentation/admin-guide/cgroup-v1/rdma.rst  |   8 +
 Documentation/admin-guide/cgroup-v2.rst       |  15 +-
 drivers/infiniband/core/cgroup.c              |   1 +
 drivers/infiniband/core/cma_configfs.c        |   4 +
 drivers/infiniband/core/core_priv.h           |   3 +-
 drivers/infiniband/core/device.c              | 245 +++++++++++--
 drivers/infiniband/core/nldev.c               |  26 +-
 drivers/infiniband/core/security.c            |   6 +
 drivers/infiniband/sw/rxe/rxe_mmap.c          |  35 +-
 drivers/infiniband/sw/rxe/rxe_verbs.c         |   5 +
 drivers/infiniband/ulp/srp/ib_srp.c           |  16 +-
 include/linux/cgroup_rdma.h                   |   1 +
 include/uapi/rdma/rdma_netlink.h              |   5 +-
 kernel/cgroup/rdma.c                          |  71 +++-
 net/smc/smc_pnet.c                            |  20 +-
 tools/testing/selftests/rdma/Makefile         |   3 +-
 tools/testing/selftests/rdma/config           |   2 +
 .../testing/selftests/rdma/rxe_netns_names.sh | 334 ++++++++++++++++++
 19 files changed, 705 insertions(+), 99 deletions(-)
 create mode 100755 tools/testing/selftests/rdma/rxe_netns_names.sh

-- 
2.54.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 01/14] RDMA/core: Pass the net namespace to the device name lookups
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace Jiri Pirko
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Prepare for per-netns RDMA device names by passing the target net
namespace through the name lookup and allocation helpers. Keep current
global uniqueness behaviour.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/device.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index b8193e077a74..de610f52c9b2 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -351,7 +351,8 @@ void ib_device_put(struct ib_device *device)
 }
 EXPORT_SYMBOL(ib_device_put);
 
-static struct ib_device *__ib_device_get_by_name(const char *name)
+static struct ib_device *__ib_device_get_by_name(const char *name,
+						 const struct net *net)
 {
 	struct ib_device *device;
 	unsigned long index;
@@ -395,7 +396,7 @@ int ib_device_rename(struct ib_device *ibdev, const char *name)
 		return 0;
 	}
 
-	if (__ib_device_get_by_name(name)) {
+	if (__ib_device_get_by_name(name, rdma_dev_net(ibdev))) {
 		up_write(&devices_rwsem);
 		return -EEXIST;
 	}
@@ -435,7 +436,8 @@ int ib_device_set_dim(struct ib_device *ibdev, u8 use_dim)
 	return 0;
 }
 
-static int alloc_name(struct ib_device *ibdev, const char *name)
+/* Pick a free index for the '%d' style @name pattern. */
+static int alloc_name_id(struct net *net, const char *name)
 {
 	struct ib_device *device;
 	unsigned long index;
@@ -462,15 +464,22 @@ static int alloc_name(struct ib_device *ibdev, const char *name)
 	}
 
 	rc = ida_alloc(&inuse, GFP_KERNEL);
-	if (rc < 0)
-		goto out;
-
-	rc = dev_set_name(&ibdev->dev, name, rc);
 out:
 	ida_destroy(&inuse);
 	return rc;
 }
 
+static int alloc_name(struct ib_device *ibdev, const char *name)
+{
+	int id;
+
+	id = alloc_name_id(rdma_dev_net(ibdev), name);
+	if (id < 0)
+		return id;
+
+	return dev_set_name(&ibdev->dev, name, id);
+}
+
 static void ib_device_release(struct device *device)
 {
 	struct ib_device *dev = container_of(device, struct ib_device, dev);
@@ -1223,7 +1232,8 @@ static int assign_name(struct ib_device *device, const char *name)
 	if (ret)
 		goto out;
 
-	if (__ib_device_get_by_name(dev_name(&device->dev))) {
+	if (__ib_device_get_by_name(dev_name(&device->dev),
+				    rdma_dev_net(device))) {
 		ret = -ENFILE;
 		goto out;
 	}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 01/14] RDMA/core: Pass the net namespace to the device name lookups Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-17 13:24   ` sashiko-bot
  2026-07-16 13:23 ` [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its " Jiri Pirko
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Prepare namespace moves for per-netns names. Check user-initiated moves for
destination-name conflicts before disabling the device, keep same-netns
moves as no-ops, and make teardown moves detach from the exiting namespace
even if fallback naming fails.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v1->v2:
- fixed possible bogus race-triggered-WARN in rdma_dev_exit_net()
---
 drivers/infiniband/core/device.c | 155 ++++++++++++++++++++++++++-----
 drivers/infiniband/core/nldev.c  |   3 +
 2 files changed, 137 insertions(+), 21 deletions(-)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index de610f52c9b2..b55fb075d0ae 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -268,7 +268,7 @@ static struct notifier_block ibdev_lsm_nb = {
 };
 
 static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
-				 struct net *net);
+				 struct net *net, const char *fallback_pattern);
 
 /* Pointer to the RCU head at the start of the ib_port_data array */
 struct ib_port_data_rcu {
@@ -437,7 +437,8 @@ int ib_device_set_dim(struct ib_device *ibdev, u8 use_dim)
 }
 
 /* Pick a free index for the '%d' style @name pattern. */
-static int alloc_name_id(struct net *net, const char *name)
+static int __alloc_name_id(struct net *net, const char *name,
+			   const struct ib_device *skip)
 {
 	struct ib_device *device;
 	unsigned long index;
@@ -450,6 +451,8 @@ static int alloc_name_id(struct net *net, const char *name)
 	xa_for_each (&devices, index, device) {
 		char buf[IB_DEVICE_NAME_MAX];
 
+		if (device == skip)
+			continue;
 		if (sscanf(dev_name(&device->dev), name, &i) != 1)
 			continue;
 		if (i < 0 || i >= INT_MAX)
@@ -469,6 +472,11 @@ static int alloc_name_id(struct net *net, const char *name)
 	return rc;
 }
 
+static int alloc_name_id(struct net *net, const char *name)
+{
+	return __alloc_name_id(net, name, NULL);
+}
+
 static int alloc_name(struct ib_device *ibdev, const char *name)
 {
 	int id;
@@ -1160,8 +1168,17 @@ static void rdma_dev_exit_net(struct net *net)
 
 		/*
 		 * If the real device is in the NS then move it back to init.
+		 * Provide a fallback pattern so a name conflict in init_net
+		 * cannot make the teardown move fail.
 		 */
-		rdma_dev_change_netns(dev, net, &init_net);
+		if (net_eq(net, read_pnet(&dev->coredev.rdma_net))) {
+			ret = rdma_dev_change_netns(dev, net, &init_net,
+						    "ibdev%d");
+			if (ret && ret != -ENODEV)
+				WARN(1,
+				     "Failed to move RDMA device %s to init_net on netns exit: %d\n",
+				     dev_name(&dev->dev), ret);
+		}
 
 		put_device(&dev->dev);
 		down_read(&devices_rwsem);
@@ -1680,14 +1697,71 @@ void ib_unregister_device_queued(struct ib_device *ib_dev)
 }
 EXPORT_SYMBOL(ib_unregister_device_queued);
 
+static bool rdma_dev_name_in_netns(struct ib_device *skip, struct net *net,
+				   const char *name)
+{
+	struct ib_device *device;
+	unsigned long index;
+
+	lockdep_assert_held_write(&devices_rwsem);
+
+	xa_for_each(&devices, index, device)
+		if (device != skip &&
+		    !strcmp(name, dev_name(&device->dev)))
+			return true;
+
+	return false;
+}
+
+/*
+ * Choose the name @device should use in net namespace @net: keep the current
+ * name when it is free, otherwise use a trusted '%d' @fallback_pattern
+ * (namespace teardown) to pick a free index. The caller must hold the write
+ * side of devices_rwsem.
+ */
+static int rdma_dev_pick_netns_name(struct ib_device *device, struct net *net,
+				    const char *fallback_pattern,
+				    char *buf, size_t buf_len,
+				    const char **new_name)
+{
+	int id;
+
+	lockdep_assert_held_write(&devices_rwsem);
+
+	if (!rdma_dev_name_in_netns(device, net, dev_name(&device->dev))) {
+		*new_name = dev_name(&device->dev);
+		return 0;
+	}
+
+	if (!fallback_pattern)
+		return -EEXIST;
+
+	snprintf(buf, buf_len, "ibdev%u", device->index);
+	if (!rdma_dev_name_in_netns(device, net, buf)) {
+		*new_name = buf;
+		return 0;
+	}
+
+	id = __alloc_name_id(net, fallback_pattern, device);
+	if (id < 0)
+		return id;
+	snprintf(buf, buf_len, fallback_pattern, id);
+	*new_name = buf;
+	return 0;
+}
+
 /*
  * The caller must pass in a device that has the kref held and the refcount
  * released. If the device is in cur_net and still registered then it is moved
  * into net.
+ *
+ * Naming rules are handled by rdma_dev_pick_netns_name().
  */
 static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
-				 struct net *net)
+				 struct net *net, const char *fallback_pattern)
 {
+	char buf[IB_DEVICE_NAME_MAX];
+	const char *new_name;
 	int ret2 = -EINVAL;
 	int ret;
 
@@ -1704,30 +1778,63 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 		goto out;
 	}
 
+	if (!fallback_pattern) {
+		/*
+		 * Reject a predictable name conflict before tearing anything
+		 * down, so a doomed user move does not disable a live device.
+		 */
+		down_write(&devices_rwsem);
+		ret = rdma_dev_pick_netns_name(device, net, fallback_pattern,
+					       buf, sizeof(buf), &new_name);
+		up_write(&devices_rwsem);
+		if (ret)
+			goto out;
+	}
+
 	kobject_uevent(&device->dev.kobj, KOBJ_REMOVE);
 	disable_device(device);
 
 	/*
-	 * At this point no one can be using the device, so it is safe to
-	 * change the namespace.
+	 * Recompute the destination name under the write side of devices_rwsem
+	 * now that the device is disabled, closing races with a concurrent
+	 * registration or rename, then publish the new namespace at the sysfs
+	 * level.
 	 */
-	write_pnet(&device->coredev.rdma_net, net);
+	down_write(&devices_rwsem);
+	ret = rdma_dev_pick_netns_name(device, net, fallback_pattern, buf,
+				       sizeof(buf), &new_name);
+	if (ret) {
+		if (fallback_pattern) {
+			WARN(1,
+			     "%s: failed to pick device name during namespace teardown: %d\n",
+			     __func__, ret);
+			write_pnet(&device->coredev.rdma_net, net);
+			ret = 0;
+		}
+		goto rename_done;
+	}
 
-	down_read(&devices_rwsem);
-	/*
-	 * Currently rdma devices are system wide unique. So the device name
-	 * is guaranteed free in the new namespace. Publish the new namespace
-	 * at the sysfs level.
-	 */
-	ret = device_rename(&device->dev, dev_name(&device->dev));
-	up_read(&devices_rwsem);
+	write_pnet(&device->coredev.rdma_net, net);
+	ret = device_rename(&device->dev, new_name);
 	if (ret) {
-		dev_warn(&device->dev,
-			 "%s: Couldn't rename device after namespace change\n",
-			 __func__);
-		/* Try and put things back and re-enable the device */
-		write_pnet(&device->coredev.rdma_net, cur_net);
+		if (fallback_pattern) {
+			WARN(1,
+			     "%s: failed to rename device during namespace teardown: %d\n",
+			     __func__, ret);
+			ret = 0;
+		} else {
+			dev_warn(&device->dev,
+				 "%s: Couldn't rename device after namespace change\n",
+				 __func__);
+			/* Try and put things back and re-enable the device */
+			write_pnet(&device->coredev.rdma_net, cur_net);
+		}
+	} else {
+		strscpy(device->name, dev_name(&device->dev),
+			IB_DEVICE_NAME_MAX);
 	}
+rename_done:
+	up_write(&devices_rwsem);
 
 	ret2 = enable_device_and_get(device);
 	if (ret2) {
@@ -1766,6 +1873,12 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 		goto ns_err;
 	}
 
+	/* Moving a device to the namespace it already lives in is a no-op. */
+	if (net_eq(net, read_pnet(&dev->coredev.rdma_net))) {
+		ret = 0;
+		goto ns_err;
+	}
+
 	/*
 	 * All the ib_clients, including uverbs, are reset when the namespace is
 	 * changed and this cannot be blocked waiting for userspace to do
@@ -1778,7 +1891,7 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 
 	get_device(&dev->dev);
 	ib_device_put(dev);
-	ret = rdma_dev_change_netns(dev, current->nsproxy->net_ns, net);
+	ret = rdma_dev_change_netns(dev, current->nsproxy->net_ns, net, NULL);
 	put_device(&dev->dev);
 
 	put_net(net);
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index aae4f3f6bcba..32b6c4d68ca0 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -1196,6 +1196,9 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
 		err = ib_device_set_netns_put(skb, device, ns_fd);
+		if (err == -EEXIST)
+			NL_SET_ERR_MSG(extack,
+				       "Device name already exists in the target net namespace");
 		goto put_done;
 	}
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its net namespace
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 01/14] RDMA/core: Pass the net namespace to the device name lookups Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-17 13:24   ` sashiko-bot
  2026-07-16 13:23 ` [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack Jiri Pirko
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Allow namespace moves to request a destination device name. Keep requested
names on the same literal-name path as the existing RDMA rename operation,
and keep teardown fallback naming on the trusted kernel-controlled path.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/core_priv.h |  2 +-
 drivers/infiniband/core/device.c    | 48 ++++++++++++++++++++---------
 drivers/infiniband/core/nldev.c     |  2 +-
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 19104c542b27..3bd5bb7135a3 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -356,7 +356,7 @@ void ib_port_unregister_client_groups(struct ib_device *ibdev, u32 port_num,
 				     const struct attribute_group **groups);
 
 int ib_device_set_netns_put(struct sk_buff *skb,
-			    struct ib_device *dev, u32 ns_fd);
+			    struct ib_device *dev, u32 ns_fd, const char *name);
 
 int rdma_nl_net_init(struct rdma_dev_net *rnet);
 void rdma_nl_net_exit(struct rdma_dev_net *rnet);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index b55fb075d0ae..c0b6613dba4c 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -268,7 +268,8 @@ static struct notifier_block ibdev_lsm_nb = {
 };
 
 static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
-				 struct net *net, const char *fallback_pattern);
+				 struct net *net, const char *requested_name,
+				 const char *fallback_pattern);
 
 /* Pointer to the RCU head at the start of the ib_port_data array */
 struct ib_port_data_rcu {
@@ -1173,7 +1174,7 @@ static void rdma_dev_exit_net(struct net *net)
 		 */
 		if (net_eq(net, read_pnet(&dev->coredev.rdma_net))) {
 			ret = rdma_dev_change_netns(dev, net, &init_net,
-						    "ibdev%d");
+						    NULL, "ibdev%d");
 			if (ret && ret != -ENODEV)
 				WARN(1,
 				     "Failed to move RDMA device %s to init_net on netns exit: %d\n",
@@ -1714,12 +1715,13 @@ static bool rdma_dev_name_in_netns(struct ib_device *skip, struct net *net,
 }
 
 /*
- * Choose the name @device should use in net namespace @net: keep the current
- * name when it is free, otherwise use a trusted '%d' @fallback_pattern
- * (namespace teardown) to pick a free index. The caller must hold the write
- * side of devices_rwsem.
+ * Choose the name @device should use in net namespace @net. @requested_name
+ * is used as a literal device name when set. Otherwise keep the current name
+ * when it is free, or use a trusted '%d' @fallback_pattern for teardown. The
+ * caller must hold the write side of devices_rwsem.
  */
 static int rdma_dev_pick_netns_name(struct ib_device *device, struct net *net,
+				    const char *requested_name,
 				    const char *fallback_pattern,
 				    char *buf, size_t buf_len,
 				    const char **new_name)
@@ -1728,6 +1730,15 @@ static int rdma_dev_pick_netns_name(struct ib_device *device, struct net *net,
 
 	lockdep_assert_held_write(&devices_rwsem);
 
+	if (requested_name) {
+		if (!rdma_dev_name_in_netns(device, net, requested_name)) {
+			*new_name = requested_name;
+			return 0;
+		}
+
+		return -EEXIST;
+	}
+
 	if (!rdma_dev_name_in_netns(device, net, dev_name(&device->dev))) {
 		*new_name = dev_name(&device->dev);
 		return 0;
@@ -1758,7 +1769,8 @@ static int rdma_dev_pick_netns_name(struct ib_device *device, struct net *net,
  * Naming rules are handled by rdma_dev_pick_netns_name().
  */
 static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
-				 struct net *net, const char *fallback_pattern)
+				 struct net *net, const char *requested_name,
+				 const char *fallback_pattern)
 {
 	char buf[IB_DEVICE_NAME_MAX];
 	const char *new_name;
@@ -1784,8 +1796,9 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 		 * down, so a doomed user move does not disable a live device.
 		 */
 		down_write(&devices_rwsem);
-		ret = rdma_dev_pick_netns_name(device, net, fallback_pattern,
-					       buf, sizeof(buf), &new_name);
+		ret = rdma_dev_pick_netns_name(device, net, requested_name,
+					       fallback_pattern, buf,
+					       sizeof(buf), &new_name);
 		up_write(&devices_rwsem);
 		if (ret)
 			goto out;
@@ -1801,8 +1814,9 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 	 * level.
 	 */
 	down_write(&devices_rwsem);
-	ret = rdma_dev_pick_netns_name(device, net, fallback_pattern, buf,
-				       sizeof(buf), &new_name);
+	ret = rdma_dev_pick_netns_name(device, net, requested_name,
+				       fallback_pattern, buf, sizeof(buf),
+				       &new_name);
 	if (ret) {
 		if (fallback_pattern) {
 			WARN(1,
@@ -1857,7 +1871,7 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 }
 
 int ib_device_set_netns_put(struct sk_buff *skb,
-			    struct ib_device *dev, u32 ns_fd)
+			    struct ib_device *dev, u32 ns_fd, const char *name)
 {
 	struct net *net;
 	int ret;
@@ -1873,9 +1887,12 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 		goto ns_err;
 	}
 
-	/* Moving a device to the namespace it already lives in is a no-op. */
+	/*
+	 * Moving a device to the namespace it already lives in is a no-op; a
+	 * supplied name still renames it in place.
+	 */
 	if (net_eq(net, read_pnet(&dev->coredev.rdma_net))) {
-		ret = 0;
+		ret = name ? ib_device_rename(dev, name) : 0;
 		goto ns_err;
 	}
 
@@ -1891,7 +1908,8 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 
 	get_device(&dev->dev);
 	ib_device_put(dev);
-	ret = rdma_dev_change_netns(dev, current->nsproxy->net_ns, net, NULL);
+	ret = rdma_dev_change_netns(dev, current->nsproxy->net_ns, net, name,
+				    NULL);
 	put_device(&dev->dev);
 
 	put_net(net);
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index 32b6c4d68ca0..77a758080148 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -1195,7 +1195,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 		u32 ns_fd;
 
 		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
-		err = ib_device_set_netns_put(skb, device, ns_fd);
+		err = ib_device_set_netns_put(skb, device, ns_fd, NULL);
 		if (err == -EEXIST)
 			NL_SET_ERR_MSG(extack,
 				       "Device name already exists in the target net namespace");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (2 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its " Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-17 13:24   ` sashiko-bot
  2026-07-16 13:23 ` [PATCH rdma-next v3 05/14] RDMA/nldev: Allow setting the device name while changing net namespace Jiri Pirko
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Thread extack through the existing net namespace move helper and report the
main failure reasons from the core path. Keep the existing move UAPI shape
unchanged.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/core_priv.h |  3 ++-
 drivers/infiniband/core/device.c    | 24 ++++++++++++++++++++++--
 drivers/infiniband/core/nldev.c     |  6 ++----
 3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 3bd5bb7135a3..aaf330b0d333 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -356,7 +356,8 @@ void ib_port_unregister_client_groups(struct ib_device *ibdev, u32 port_num,
 				     const struct attribute_group **groups);
 
 int ib_device_set_netns_put(struct sk_buff *skb,
-			    struct ib_device *dev, u32 ns_fd, const char *name);
+			    struct ib_device *dev, u32 ns_fd, const char *name,
+			    struct netlink_ext_ack *extack);
 
 int rdma_nl_net_init(struct rdma_dev_net *rnet);
 void rdma_nl_net_exit(struct rdma_dev_net *rnet);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index c0b6613dba4c..366bd8463c07 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -1871,18 +1871,22 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 }
 
 int ib_device_set_netns_put(struct sk_buff *skb,
-			    struct ib_device *dev, u32 ns_fd, const char *name)
+			    struct ib_device *dev, u32 ns_fd, const char *name,
+			    struct netlink_ext_ack *extack)
 {
 	struct net *net;
 	int ret;
 
 	net = get_net_ns_by_fd(ns_fd);
 	if (IS_ERR(net)) {
+		NL_SET_ERR_MSG(extack, "Invalid target net namespace fd");
 		ret = PTR_ERR(net);
 		goto net_err;
 	}
 
 	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
+		NL_SET_ERR_MSG(extack,
+			       "Missing CAP_NET_ADMIN in the target net namespace");
 		ret = -EPERM;
 		goto ns_err;
 	}
@@ -1893,6 +1897,10 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 	 */
 	if (net_eq(net, read_pnet(&dev->coredev.rdma_net))) {
 		ret = name ? ib_device_rename(dev, name) : 0;
+
+		if (ret == -EEXIST)
+			NL_SET_ERR_MSG(extack,
+				       "Device name already exists in the target net namespace");
 		goto ns_err;
 	}
 
@@ -1901,7 +1909,16 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 	 * changed and this cannot be blocked waiting for userspace to do
 	 * something, so disassociation is mandatory.
 	 */
-	if (!dev->ops.disassociate_ucontext || ib_devices_shared_netns) {
+	if (ib_devices_shared_netns) {
+		NL_SET_ERR_MSG(extack,
+			       "Cannot change net namespace of RDMA device in shared netns mode");
+		ret = -EOPNOTSUPP;
+		goto ns_err;
+	}
+
+	if (!dev->ops.disassociate_ucontext) {
+		NL_SET_ERR_MSG(extack,
+			       "Device does not support namespace changes (no disassociate support)");
 		ret = -EOPNOTSUPP;
 		goto ns_err;
 	}
@@ -1911,6 +1928,9 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 	ret = rdma_dev_change_netns(dev, current->nsproxy->net_ns, net, name,
 				    NULL);
 	put_device(&dev->dev);
+	if (ret == -EEXIST)
+		NL_SET_ERR_MSG(extack,
+			       "Device name already exists in the target net namespace");
 
 	put_net(net);
 	return ret;
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index 77a758080148..8648e95700bf 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -1195,10 +1195,8 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 		u32 ns_fd;
 
 		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
-		err = ib_device_set_netns_put(skb, device, ns_fd, NULL);
-		if (err == -EEXIST)
-			NL_SET_ERR_MSG(extack,
-				       "Device name already exists in the target net namespace");
+		err = ib_device_set_netns_put(skb, device, ns_fd, NULL,
+					      extack);
 		goto put_done;
 	}
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 05/14] RDMA/nldev: Allow setting the device name while changing net namespace
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (3 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the " Jiri Pirko
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Accept RDMA_NLDEV_ATTR_DEV_NAME together with RDMA_NLDEV_NET_NS_FD so a
netlink move can rename the device in the destination namespace. Keep the
name semantics aligned with the existing RDMA rename path.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/device.c |  6 ++++++
 drivers/infiniband/core/nldev.c  | 27 ++++++++++++++++++---------
 include/uapi/rdma/rdma_netlink.h |  5 ++++-
 3 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 366bd8463c07..bb02640239d7 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -1901,6 +1901,9 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 		if (ret == -EEXIST)
 			NL_SET_ERR_MSG(extack,
 				       "Device name already exists in the target net namespace");
+		else if (ret == -EINVAL && name)
+			NL_SET_ERR_MSG(extack,
+				       "Unable to use requested device name in the target net namespace");
 		goto ns_err;
 	}
 
@@ -1931,6 +1934,9 @@ int ib_device_set_netns_put(struct sk_buff *skb,
 	if (ret == -EEXIST)
 		NL_SET_ERR_MSG(extack,
 			       "Device name already exists in the target net namespace");
+	else if (ret == -EINVAL && name)
+		NL_SET_ERR_MSG(extack,
+			       "Unable to use requested device name in the target net namespace");
 
 	put_net(net);
 	return ret;
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index 8648e95700bf..4efa387ec1be 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -1178,6 +1178,24 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (!device)
 		return -EINVAL;
 
+	if (tb[RDMA_NLDEV_NET_NS_FD]) {
+		char name[IB_DEVICE_NAME_MAX] = {};
+		u32 ns_fd;
+
+		if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
+			nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
+				    IB_DEVICE_NAME_MAX);
+			if (strlen(name) == 0) {
+				err = -EINVAL;
+				goto done;
+			}
+		}
+		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
+		err = ib_device_set_netns_put(skb, device, ns_fd,
+					      name[0] ? name : NULL, extack);
+		goto put_done;
+	}
+
 	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
 		char name[IB_DEVICE_NAME_MAX] = {};
 
@@ -1191,15 +1209,6 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto done;
 	}
 
-	if (tb[RDMA_NLDEV_NET_NS_FD]) {
-		u32 ns_fd;
-
-		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
-		err = ib_device_set_netns_put(skb, device, ns_fd, NULL,
-					      extack);
-		goto put_done;
-	}
-
 	if (tb[RDMA_NLDEV_ATTR_DEV_DIM]) {
 		u8 use_dim;
 
diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h
index 3af946ecbac3..ee11c3bbbae2 100644
--- a/include/uapi/rdma/rdma_netlink.h
+++ b/include/uapi/rdma/rdma_netlink.h
@@ -516,7 +516,10 @@ enum rdma_nldev_attr {
 	RDMA_NLDEV_ATTR_DEV_PROTOCOL,		/* string */
 
 	/*
-	 * File descriptor handle of the net namespace object
+	 * File descriptor handle of the net namespace object. May be combined
+	 * with RDMA_NLDEV_ATTR_DEV_NAME (a literal device name) to also rename
+	 * the device in the destination namespace; the move fails with -EEXIST
+	 * if that name is already taken there.
 	 */
 	RDMA_NLDEV_NET_NS_FD,			/* u32 */
 	/*
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the net namespace
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (4 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 05/14] RDMA/nldev: Allow setting the device name while changing net namespace Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-17 13:24   ` sashiko-bot
  2026-07-16 13:23 ` [PATCH rdma-next v3 07/14] RDMA/srp: Make the SRP sysfs class net namespace aware Jiri Pirko
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Scope smc_pnet_find_ib() to the caller's net namespace so pnetid setup
cannot bind to a same-named RDMA device from another namespace once names
become per-netns.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 net/smc/smc_pnet.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 63e286e2dfaa..ff9c9c35cc2f 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -304,13 +304,18 @@ static bool smc_pnetid_valid(const char *pnet_name, char *pnetid)
 	return true;
 }
 
-/* Find an infiniband device by a given name. The device might not exist. */
-static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
+/*
+ * Find an infiniband device by a given name, restricted to the devices
+ * accessible from @net. The device might not exist.
+ */
+static struct smc_ib_device *smc_pnet_find_ib(struct net *net, char *ib_name)
 {
 	struct smc_ib_device *ibdev;
 
 	mutex_lock(&smc_ib_devices.mutex);
 	list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
+		if (!rdma_dev_access_netns(ibdev->ibdev, net))
+			continue;
 		if (!strncmp(ibdev->ibdev->name, ib_name,
 			     sizeof(ibdev->ibdev->name)) ||
 		    (ibdev->ibdev->dev.parent &&
@@ -408,8 +413,8 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
 	return rc;
 }
 
-static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
-			   u8 ib_port, char *pnet_name)
+static int smc_pnet_add_ib(struct smc_pnettable *pnettable, struct net *net,
+			   char *ib_name, u8 ib_port, char *pnet_name)
 {
 	struct smc_pnetentry *tmp_pe, *new_pe;
 	struct smc_ib_device *ib_dev;
@@ -419,7 +424,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
 	bool new_ibdev;
 
 	/* try to apply the pnetid to active devices */
-	ib_dev = smc_pnet_find_ib(ib_name);
+	ib_dev = smc_pnet_find_ib(net, ib_name);
 	if (ib_dev) {
 		ibdev_applied = smc_pnet_apply_ib(ib_dev, ib_port, pnet_name);
 		if (ibdev_applied)
@@ -518,7 +523,7 @@ static int smc_pnet_enter(struct net *net, struct nlattr *tb[])
 			if (ibport < 1 || ibport > SMC_MAX_PORTS)
 				goto error;
 		}
-		rc = smc_pnet_add_ib(pnettable, string, ibport, pnet_name);
+		rc = smc_pnet_add_ib(pnettable, net, string, ibport, pnet_name);
 		if (!rc)
 			new_ibdev = true;
 		else if (rc != -EEXIST)
@@ -1170,6 +1175,9 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
 	struct smc_net *sn;
 	int rc = -ENOENT;
 
+	if (!rdma_dev_access_netns(smcibdev->ibdev, &init_net))
+		return -ENOENT;
+
 	/* get pnettable for init namespace */
 	sn = net_generic(&init_net, smc_net_id);
 	pnettable = &sn->pnettable;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 07/14] RDMA/srp: Make the SRP sysfs class net namespace aware
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (5 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the " Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 08/14] RDMA/cgroup: Disambiguate devices across net namespaces Jiri Pirko
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Tag srp_class by the RDMA device's net namespace so SRP hosts derived from
same-named RDMA devices can coexist across namespaces.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/ulp/srp/ib_srp.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 0caebbc2810f..2fc8e133c70f 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3189,10 +3189,24 @@ static struct attribute *srp_class_attrs[];
 
 ATTRIBUTE_GROUPS(srp_class);
 
+/*
+ * SRP hosts are named after their ib device, so tag the class by the ib
+ * device's net namespace.
+ */
+static const struct ns_common *srp_net_namespace(const struct device *dev)
+{
+	struct srp_host *host = container_of(dev, struct srp_host, dev);
+	struct net *net = rdma_dev_net(host->srp_dev->dev);
+
+	return net ? to_ns_common(net) : NULL;
+}
+
 static struct class srp_class = {
 	.name    = "infiniband_srp",
 	.dev_groups = srp_class_groups,
-	.dev_release = srp_release_dev
+	.dev_release = srp_release_dev,
+	.ns_type = &net_ns_type_operations,
+	.namespace = srp_net_namespace,
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 08/14] RDMA/cgroup: Disambiguate devices across net namespaces
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (6 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 07/14] RDMA/srp: Make the SRP sysfs class net namespace aware Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 09/14] RDMA/cma: Document that CM configfs cannot be net namespace scoped Jiri Pirko
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

RDMA device names are unique only within a network namespace, but an
RDMA cgroup can account resources for devices from multiple namespaces.
Duplicate names therefore make cgroup output ambiguous and can cause
limit writes to select the wrong device.

Use the system-wide RDMA device index to distinguish duplicate names
while preserving the existing UAPI for unique names. Reject ambiguous
name-only writes with -ENOTUNIQ and expose a complete device view to
administrators.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v1->v2:
- replace caller-netns filtering with global visibility and index-based
  disambiguation
---
 Documentation/admin-guide/cgroup-v1/rdma.rst |  8 +++
 Documentation/admin-guide/cgroup-v2.rst      | 15 ++++-
 drivers/infiniband/core/cgroup.c             |  1 +
 include/linux/cgroup_rdma.h                  |  1 +
 kernel/cgroup/rdma.c                         | 71 ++++++++++++++++----
 5 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/Documentation/admin-guide/cgroup-v1/rdma.rst b/Documentation/admin-guide/cgroup-v1/rdma.rst
index e69369b7252e..8d0c3a796ee3 100644
--- a/Documentation/admin-guide/cgroup-v1/rdma.rst
+++ b/Documentation/admin-guide/cgroup-v1/rdma.rst
@@ -90,6 +90,13 @@ Following resources can be accounted by rdma controller.
   hca_object 	Maximum number of HCA Objects
   ==========    =============================
 
+RDMA devices from all network namespaces are listed. Each line starts with
+the device name. If more than one device has the same name, ``index=N``
+follows the name, where ``N`` is the system-wide RDMA device index, unique
+among registered devices. When configuring a limit, the index is optional
+for a globally unique name and required for a duplicate name. A write without
+the required index fails with ``-ENOTUNIQ``.
+
 2. Usage Examples
 =================
 
@@ -97,6 +104,7 @@ Following resources can be accounted by rdma controller.
 
 	echo mlx4_0 hca_handle=2 hca_object=2000 > /sys/fs/cgroup/rdma/1/rdma.max
 	echo ocrdma1 hca_handle=3 > /sys/fs/cgroup/rdma/2/rdma.max
+	echo "rxe0 index=5 hca_handle=2" > /sys/fs/cgroup/rdma/3/rdma.max
 
 (b) Query resource limit::
 
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index 993446ab66d0..df74d554d2cd 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2752,6 +2752,11 @@ RDMA
 The "rdma" controller regulates the distribution and accounting of
 RDMA resources.
 
+RDMA devices from all network namespaces are listed. Each line starts with
+the device name. If more than one device has the same name, ``index=N``
+follows the name, where ``N`` is the system-wide RDMA device index, unique
+among registered devices.
+
 RDMA Interface Files
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -2760,7 +2765,11 @@ RDMA Interface Files
 	except root that describes current configured resource limit
 	for a RDMA/IB device.
 
-	Lines are keyed by device name and are not ordered.
+	Lines are keyed by device name and are not ordered. A write may
+	include ``index=N`` after the device name. The index is optional
+	when the name is globally unique. If multiple devices have that
+	name, the index is required and a write without it fails with
+	``-ENOTUNIQ``.
 	Each line contains space separated resource name and its configured
 	limit that can be distributed.
 
@@ -2776,6 +2785,10 @@ RDMA Interface Files
 	  mlx4_0 hca_handle=2 hca_object=2000
 	  ocrdma1 hca_handle=3 hca_object=max
 
+	For devices with duplicate names, select the device by index::
+
+	  echo "rxe0 index=5 hca_handle=2" > rdma.max
+
   rdma.current
 	A read-only file that describes current resource usage.
 	It exists for all the cgroup except root.
diff --git a/drivers/infiniband/core/cgroup.c b/drivers/infiniband/core/cgroup.c
index 1f037fe01450..8611b4e32cfb 100644
--- a/drivers/infiniband/core/cgroup.c
+++ b/drivers/infiniband/core/cgroup.c
@@ -17,6 +17,7 @@
 void ib_device_register_rdmacg(struct ib_device *device)
 {
 	device->cg_device.name = device->name;
+	device->cg_device.index = device->index;
 	rdmacg_register_device(&device->cg_device);
 }
 
diff --git a/include/linux/cgroup_rdma.h b/include/linux/cgroup_rdma.h
index 404e746552ca..9a5c9ee728e7 100644
--- a/include/linux/cgroup_rdma.h
+++ b/include/linux/cgroup_rdma.h
@@ -34,6 +34,7 @@ struct rdmacg_device {
 	struct list_head	dev_node;
 	struct list_head	rpools;
 	char			*name;
+	u32			index;
 };
 
 /*
diff --git a/kernel/cgroup/rdma.c b/kernel/cgroup/rdma.c
index 5e82a03b3270..9489f3df0bf3 100644
--- a/kernel/cgroup/rdma.c
+++ b/kernel/cgroup/rdma.c
@@ -19,6 +19,7 @@
 #define RDMACG_MAX_STR "max"
 
 enum rdmacg_limit_tokens {
+	RDMACG_DEVICE_INDEX,
 	RDMACG_HCA_HANDLE_VAL,
 	RDMACG_HCA_HANDLE_MAX,
 	RDMACG_HCA_OBJECT_VAL,
@@ -27,6 +28,7 @@ enum rdmacg_limit_tokens {
 };
 
 static const match_table_t rdmacg_limit_tokens = {
+	{ RDMACG_DEVICE_INDEX,		"index=%u"	},
 	{ RDMACG_HCA_HANDLE_VAL,	"hca_handle=%d"	},
 	{ RDMACG_HCA_HANDLE_MAX,	"hca_handle=max"	},
 	{ RDMACG_HCA_OBJECT_VAL,	"hca_object=%d"	},
@@ -464,17 +466,53 @@ void rdmacg_unregister_device(struct rdmacg_device *device)
 }
 EXPORT_SYMBOL(rdmacg_unregister_device);
 
-static struct rdmacg_device *rdmacg_get_device_locked(const char *name)
+static struct rdmacg_device *
+rdmacg_get_device_locked(const char *name, bool has_index, u32 index)
 {
+	struct rdmacg_device *match = NULL;
 	struct rdmacg_device *device;
 
 	lockdep_assert_held(&rdmacg_mutex);
 
-	list_for_each_entry(device, &rdmacg_devices, dev_node)
-		if (!strcmp(name, device->name))
-			return device;
+	list_for_each_entry(device, &rdmacg_devices, dev_node) {
+		if (strcmp(name, device->name))
+			continue;
 
-	return NULL;
+		if (has_index) {
+			if (device->index == index)
+				return device;
+			continue;
+		}
+
+		if (match)
+			return ERR_PTR(-ENOTUNIQ);
+		match = device;
+	}
+
+	return match ?: ERR_PTR(-ENODEV);
+}
+
+static bool
+rdmacg_device_name_unique_locked(const struct rdmacg_device *device)
+{
+	struct rdmacg_device *other;
+
+	lockdep_assert_held(&rdmacg_mutex);
+
+	list_for_each_entry(other, &rdmacg_devices, dev_node)
+		if (other != device && !strcmp(other->name, device->name))
+			return false;
+
+	return true;
+}
+
+static void rdmacg_print_device_key(struct seq_file *sf,
+				    const struct rdmacg_device *device)
+{
+	seq_puts(sf, device->name);
+	if (!rdmacg_device_name_unique_locked(device))
+		seq_printf(sf, " index=%u", device->index);
+	seq_putc(sf, ' ');
 }
 
 static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
@@ -488,6 +526,8 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
 	char *p;
 	int *new_limits;
 	unsigned long enables = 0;
+	u32 dev_index = 0;
+	bool has_index = false;
 	int i = 0, ret = 0;
 
 	/* extract the device name first */
@@ -503,7 +543,7 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
 		goto err;
 	}
 
-	/* parse resource limit tokens */
+	/* parse the optional device index and resource limit tokens */
 	while ((p = strsep(&options, " \t\n"))) {
 		substring_t args[MAX_OPT_ARGS];
 		int tok, intval;
@@ -513,6 +553,13 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
 
 		tok = match_token(p, rdmacg_limit_tokens, args);
 		switch (tok) {
+		case RDMACG_DEVICE_INDEX:
+			if (has_index || match_uint(&args[0], &dev_index)) {
+				ret = -EINVAL;
+				goto parse_err;
+			}
+			has_index = true;
+			break;
 		case RDMACG_HCA_HANDLE_VAL:
 			if (match_int(&args[0], &intval) || intval < 0) {
 				ret = -EINVAL;
@@ -546,9 +593,9 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
 	/* acquire lock to synchronize with hot plug devices */
 	mutex_lock(&rdmacg_mutex);
 
-	device = rdmacg_get_device_locked(dev_name);
-	if (!device) {
-		ret = -ENODEV;
+	device = rdmacg_get_device_locked(dev_name, has_index, dev_index);
+	if (IS_ERR(device)) {
+		ret = PTR_ERR(device);
 		goto dev_err;
 	}
 
@@ -626,7 +673,7 @@ static int rdmacg_resource_read(struct seq_file *sf, void *v)
 	mutex_lock(&rdmacg_mutex);
 
 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
-		seq_printf(sf, "%s ", device->name);
+		rdmacg_print_device_key(sf, device);
 
 		rpool = find_cg_rpool_locked(cg, device);
 		print_rpool_values(sf, rpool);
@@ -650,7 +697,7 @@ static int rdmacg_events_show(struct seq_file *sf, void *v)
 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
 		rpool = find_cg_rpool_locked(cg, device);
 
-		seq_printf(sf, "%s ", device->name);
+		rdmacg_print_device_key(sf, device);
 		for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
 			seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
 				   rdmacg_resource_names[i],
@@ -679,7 +726,7 @@ static int rdmacg_events_local_show(struct seq_file *sf, void *v)
 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
 		rpool = find_cg_rpool_locked(cg, device);
 
-		seq_printf(sf, "%s ", device->name);
+		rdmacg_print_device_key(sf, device);
 		for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
 			seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
 				   rdmacg_resource_names[i],
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 09/14] RDMA/cma: Document that CM configfs cannot be net namespace scoped
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (7 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 08/14] RDMA/cgroup: Disambiguate devices across net namespaces Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 10/14] RDMA/core: Document the SELinux ibendport net namespace limitation Jiri Pirko
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Document the rdma_cm configfs limitation: configfs is global, so same-named
RDMA devices in different net namespaces cannot both be represented there.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 Documentation/ABI/testing/configfs-rdma_cm | 4 ++++
 drivers/infiniband/core/cma_configfs.c     | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/Documentation/ABI/testing/configfs-rdma_cm b/Documentation/ABI/testing/configfs-rdma_cm
index 74f9506f42e7..739f7b6a1259 100644
--- a/Documentation/ABI/testing/configfs-rdma_cm
+++ b/Documentation/ABI/testing/configfs-rdma_cm
@@ -12,6 +12,10 @@ Description: 	Interface is used to configure RDMA-cable HCAs in respect to
 		for this HCA has to be created:
 		mkdir -p /config/rdma_cm/<hca>
 
+		Note: configfs has no network namespace support, so this
+		interface cannot represent two devices that share a name in
+		different network namespaces (possible in exclusive netns mode).
+
 
 What: 		/config/rdma_cm/<hca>/ports/<port-num>/default_roce_mode
 Date: 		November 29, 2015
diff --git a/drivers/infiniband/core/cma_configfs.c b/drivers/infiniband/core/cma_configfs.c
index 891e52afb8f4..c389d4e37b6b 100644
--- a/drivers/infiniband/core/cma_configfs.c
+++ b/drivers/infiniband/core/cma_configfs.c
@@ -65,6 +65,10 @@ static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)
 	return container_of(group, struct cma_dev_port_group, group);
 }
 
+/*
+ * configfs is not net namespace aware, so a name shared by devices in
+ * different namespaces resolves to the first match here.
+ */
 static bool filter_by_name(struct ib_device *ib_dev, void *cookie)
 {
 	return !strcmp(dev_name(&ib_dev->dev), cookie);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 10/14] RDMA/core: Document the SELinux ibendport net namespace limitation
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (8 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 09/14] RDMA/cma: Document that CM configfs cannot be net namespace scoped Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 11/14] RDMA/core: Make device names unique per net namespace Jiri Pirko
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Document that SELinux ibendport labels use a global (device name, port)
key, so same-named RDMA devices in different net namespaces share a label.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/security.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c
index 9af31d1d9d70..a82c46965416 100644
--- a/drivers/infiniband/core/security.c
+++ b/drivers/infiniband/core/security.c
@@ -700,6 +700,12 @@ int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
 	if (qp_type != IB_QPT_SMI)
 		return 0;
 
+	/*
+	 * SELinux labels an endport by (device name, port) from a global
+	 * policy. If devices in different net namespaces share a name, they get
+	 * the same label; distinguishing them would need net namespace support
+	 * in the policy language and tooling.
+	 */
 	spin_lock(&mad_agent_list_lock);
 	ret = security_ib_endport_manage_subnet(agent->security,
 						dev_name(&agent->device->dev),
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 11/14] RDMA/core: Make device names unique per net namespace
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (9 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 10/14] RDMA/core: Document the SELinux ibendport net namespace limitation Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 12/14] RDMA/rxe: Allow queue VMAs to outlive ucontexts Jiri Pirko
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Use rdma_dev_access_netns() to scope RDMA device name lookup and "%d" name
allocation to the relevant net namespace. Keep shared mode and
CONFIG_NET_NS=n behaviour system-wide.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/core/device.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index bb02640239d7..4c75078448a3 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -129,7 +129,7 @@ static DECLARE_RWSEM(rdma_nets_rwsem);
 bool ib_devices_shared_netns = true;
 module_param_named(netns_mode, ib_devices_shared_netns, bool, 0444);
 MODULE_PARM_DESC(netns_mode,
-		 "Share device among net namespaces; default=1 (shared)");
+		 "Share device among net namespaces; default=1 (shared). In exclusive mode device names are unique per net namespace");
 /**
  * rdma_dev_access_netns() - Return whether an rdma device can be accessed
  *			     from a specified net namespace or not.
@@ -359,7 +359,8 @@ static struct ib_device *__ib_device_get_by_name(const char *name,
 	unsigned long index;
 
 	xa_for_each (&devices, index, device)
-		if (!strcmp(name, dev_name(&device->dev)))
+		if (rdma_dev_access_netns(device, net) &&
+		    !strcmp(name, dev_name(&device->dev)))
 			return device;
 
 	return NULL;
@@ -437,7 +438,11 @@ int ib_device_set_dim(struct ib_device *ibdev, u8 use_dim)
 	return 0;
 }
 
-/* Pick a free index for the '%d' style @name pattern. */
+/*
+ * Pick a free index for the '%d' style @name pattern within net namespace
+ * @net. Returns the index on success or a negative errno. The caller builds
+ * the final unique device name from the returned index.
+ */
 static int __alloc_name_id(struct net *net, const char *name,
 			   const struct ib_device *skip)
 {
@@ -452,7 +457,7 @@ static int __alloc_name_id(struct net *net, const char *name,
 	xa_for_each (&devices, index, device) {
 		char buf[IB_DEVICE_NAME_MAX];
 
-		if (device == skip)
+		if (device == skip || !rdma_dev_access_netns(device, net))
 			continue;
 		if (sscanf(dev_name(&device->dev), name, &i) != 1)
 			continue;
@@ -1233,7 +1238,8 @@ static __net_init int rdma_dev_init_net(struct net *net)
 }
 
 /*
- * Assign the unique string device name and the unique device index. This is
+ * Assign the unique string device name and the unique device index. The device
+ * name is unique within the net namespace the device is assigned to. This is
  * undone by ib_dealloc_device.
  */
 static int assign_name(struct ib_device *device, const char *name)
@@ -1416,8 +1422,9 @@ static void ib_device_notify_register(struct ib_device *device)
 /**
  * ib_register_device - Register an IB device with IB core
  * @device: Device to register
- * @name: unique string device name. This may include a '%' which will
- * 	  cause a unique index to be added to the passed device name.
+ * @name: device name, unique within the device's net namespace. This may
+ *	  include a '%' which will cause a unique index to be added to the
+ *	  passed device name.
  * @dma_device: pointer to a DMA-capable device. If %NULL, then the IB
  *	        device will be used. In this case the caller should fully
  *		setup the ibdev for DMA. This usually means using dma_virt_ops.
@@ -1708,6 +1715,7 @@ static bool rdma_dev_name_in_netns(struct ib_device *skip, struct net *net,
 
 	xa_for_each(&devices, index, device)
 		if (device != skip &&
+		    rdma_dev_access_netns(device, net) &&
 		    !strcmp(name, dev_name(&device->dev)))
 			return true;
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 12/14] RDMA/rxe: Allow queue VMAs to outlive ucontexts
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (10 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 11/14] RDMA/core: Make device names unique per net namespace Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 13/14] RDMA/rxe: Implement disassociate_ucontext callback Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test Jiri Pirko
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Prepare queue mappings for asynchronous ucontext disassociation during
device disable. Rely on the VMA page references to preserve mapped
memory until the final unmap.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v1->v2:
- new patch
---
 drivers/infiniband/sw/rxe/rxe_mmap.c | 35 ++--------------------------
 1 file changed, 2 insertions(+), 33 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mmap.c b/drivers/infiniband/sw/rxe/rxe_mmap.c
index 7f723a2f3700..a4ead89ccbd3 100644
--- a/drivers/infiniband/sw/rxe/rxe_mmap.c
+++ b/drivers/infiniband/sw/rxe/rxe_mmap.c
@@ -11,7 +11,6 @@
 
 #include "rxe.h"
 #include "rxe_loc.h"
-#include "rxe_queue.h"
 
 void rxe_mmap_release(struct kref *ref)
 {
@@ -30,29 +29,6 @@ void rxe_mmap_release(struct kref *ref)
 	kfree(ip);
 }
 
-/*
- * open and close keep track of how many times the memory region is mapped,
- * to avoid releasing it.
- */
-static void rxe_vma_open(struct vm_area_struct *vma)
-{
-	struct rxe_mmap_info *ip = vma->vm_private_data;
-
-	kref_get(&ip->ref);
-}
-
-static void rxe_vma_close(struct vm_area_struct *vma)
-{
-	struct rxe_mmap_info *ip = vma->vm_private_data;
-
-	kref_put(&ip->ref, rxe_mmap_release);
-}
-
-static const struct vm_operations_struct rxe_vm_ops = {
-	.open = rxe_vma_open,
-	.close = rxe_vma_close,
-};
-
 /**
  * rxe_mmap - create a new mmap region
  * @context: the IB user context of the process making the mmap() call
@@ -106,17 +82,10 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 	list_del_init(&ip->pending_mmaps);
 	spin_unlock_bh(&rxe->pending_lock);
 
-	vma->vm_ops = &rxe_vm_ops;
-	vma->vm_private_data = ip;
-
 	ret = remap_vmalloc_range(vma, ip->obj, 0);
-	if (ret) {
-		vma->vm_private_data = NULL;
-		vma->vm_ops = NULL;
-		kref_put(&ip->ref, rxe_mmap_release);
+	kref_put(&ip->ref, rxe_mmap_release);
+	if (ret)
 		rxe_dbg_dev(rxe, "err %d from remap_vmalloc_range\n", ret);
-		goto done;
-	}
 
 done:
 	return ret;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 13/14] RDMA/rxe: Implement disassociate_ucontext callback
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (11 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 12/14] RDMA/rxe: Allow queue VMAs to outlive ucontexts Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-16 13:23 ` [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test Jiri Pirko
  13 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Implement an empty disassociate_ucontext() callback so the RDMA core
can move rxe devices between net namespaces. The core requires this
callback to reset user contexts without waiting for userspace.

rxe needs no teardown here: its user-mapped queues live in
reference-counted vmalloc memory (see rxe_mmap.c) that stays valid
while userspace holds the mappings.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/infiniband/sw/rxe/rxe_verbs.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 1ec130fee8ea..6eb10d2f0653 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -240,6 +240,10 @@ static void rxe_dealloc_ucontext(struct ib_ucontext *ibuc)
 		rxe_err_uc(uc, "cleanup failed, err = %d\n", err);
 }
 
+static void rxe_disassociate_ucontext(struct ib_ucontext *ibuc)
+{
+}
+
 /* pd */
 static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
@@ -1478,6 +1482,7 @@ static const struct ib_device_ops rxe_dev_ops = {
 	.destroy_srq = rxe_destroy_srq,
 	.detach_mcast = rxe_detach_mcast,
 	.device_group = &rxe_attr_group,
+	.disassociate_ucontext = rxe_disassociate_ucontext,
 	.enable_driver = rxe_enable_driver,
 	.get_dma_mr = rxe_get_dma_mr,
 	.get_hw_stats = rxe_ib_get_hw_stats,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test
  2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
                   ` (12 preceding siblings ...)
  2026-07-16 13:23 ` [PATCH rdma-next v3 13/14] RDMA/rxe: Implement disassociate_ucontext callback Jiri Pirko
@ 2026-07-16 13:23 ` Jiri Pirko
  2026-07-17  4:22   ` Zhu Yanjun
  2026-07-17 13:24   ` sashiko-bot
  13 siblings, 2 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-16 13:23 UTC (permalink / raw)
  To: linux-rdma
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia,
	yanjun.zhu, cui.tao

From: Jiri Pirko <jiri@nvidia.com>

Add a kselftest script that exercises per-netns RDMA device naming
with RXE. Cover duplicate names across namespaces, move conflict
handling, move-with-rename, and same-namespace rename requests.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- added wait for rdma devices are removed
- added retry for old rdma netns mode restore
v1->v2:
- fixed ktap_set_plan
- s/RXE_A/RXE_SAME/ in dup rename
---
 tools/testing/selftests/rdma/Makefile         |   3 +-
 tools/testing/selftests/rdma/config           |   2 +
 .../testing/selftests/rdma/rxe_netns_names.sh | 334 ++++++++++++++++++
 3 files changed, 338 insertions(+), 1 deletion(-)
 create mode 100755 tools/testing/selftests/rdma/rxe_netns_names.sh

diff --git a/tools/testing/selftests/rdma/Makefile b/tools/testing/selftests/rdma/Makefile
index 07af7f15c1bf..a91c14c45006 100644
--- a/tools/testing/selftests/rdma/Makefile
+++ b/tools/testing/selftests/rdma/Makefile
@@ -3,6 +3,7 @@ TEST_PROGS := rxe_rping_between_netns.sh \
 		rxe_ipv6.sh \
 		rxe_socket_with_netns.sh \
 		rxe_test_NETDEV_UNREGISTER.sh \
-		rxe_sent_rcvd_bytes.sh
+		rxe_sent_rcvd_bytes.sh \
+		rxe_netns_names.sh
 
 include ../lib.mk
diff --git a/tools/testing/selftests/rdma/config b/tools/testing/selftests/rdma/config
index 4ffb814e253b..e1ff54ec0f57 100644
--- a/tools/testing/selftests/rdma/config
+++ b/tools/testing/selftests/rdma/config
@@ -1,3 +1,5 @@
 CONFIG_TUN
 CONFIG_VETH
+CONFIG_DUMMY
+CONFIG_NET_NS
 CONFIG_RDMA_RXE
diff --git a/tools/testing/selftests/rdma/rxe_netns_names.sh b/tools/testing/selftests/rdma/rxe_netns_names.sh
new file mode 100755
index 000000000000..f40118407f4c
--- /dev/null
+++ b/tools/testing/selftests/rdma/rxe_netns_names.sh
@@ -0,0 +1,334 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Exercise RDMA device name handling across network namespaces.
+
+source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
+
+NAME_PREFIX="rxe_netns_names_$$"
+NETDEV_PREFIX="rxn$$"
+NS1="${NAME_PREFIX}ns1"
+NS2="${NAME_PREFIX}ns2"
+RXE_A="${NAME_PREFIX}rxe_a"
+RXE_B="${NAME_PREFIX}rxe_b"
+RXE_SAME="${NAME_PREFIX}rxe_same"
+RXE_NEW="${NAME_PREFIX}rxe_new"
+DUMMY_A="${NETDEV_PREFIX}a"
+DUMMY_B="${NETDEV_PREFIX}b"
+OLD_MODE=""
+MODE_CHANGED=0
+MODS=("dummy" "rdma_rxe")
+TEST_SAME_NAMES="same RDMA device name can exist in two net namespaces"
+TEST_MOVE_CONFLICT="move without rename fails on destination name conflict"
+TEST_MOVE_RENAME="move then rename succeeds"
+TEST_COMBINED_MOVE_RENAME="move with requested destination name succeeds"
+TEST_SAME_NETNS_DUP_RENAME="same-netns rename rejects duplicate name"
+TEST_TEARDOWN_RETURN="netns delete returns device to init_net and renames on conflict"
+
+ksft_skip()
+{
+	ktap_skip_all "$*"
+	exit "$KSFT_SKIP"
+}
+
+fail()
+{
+	ktap_exit_fail_msg "$*"
+}
+
+need_cmd()
+{
+	command -v "$1" >/dev/null 2>&1 || ksft_skip "missing command: $1"
+}
+
+rdma_ns()
+{
+	local ns=$1
+
+	shift
+	ip netns exec "$ns" rdma "$@"
+}
+
+rdma_dev_exists()
+{
+	local ns=$1
+	local dev=$2
+
+	if [ -n "$ns" ]; then
+		rdma_ns "$ns" dev show "$dev" >/dev/null 2>&1
+	else
+		rdma dev show "$dev" >/dev/null 2>&1
+	fi
+}
+
+add_dummy()
+{
+	local netdev=$1
+
+	ip link add "$netdev" type dummy || return 1
+	ip link set "$netdev" up || return 1
+}
+
+add_rxe()
+{
+	local dev=$1
+	local netdev=$2
+
+	rdma link add "$dev" type rxe netdev "$netdev"
+}
+
+rdma_dev_on_netdev()
+{
+	local netdev=$1
+
+	rdma link show 2>/dev/null | awk -v want="$netdev" '
+		{
+			for (i = 1; i < NF; i++)
+				if ($i == "netdev" && $(i + 1) == want) {
+					dev = $2
+					sub(/\/.*/, "", dev)
+					print dev
+					exit
+				}
+		}'
+}
+
+wait_rdma_dev_on_netdev()
+{
+	local netdev=$1
+	local dev
+	local i
+
+	for i in $(seq 1 50); do
+		dev=$(rdma_dev_on_netdev "$netdev")
+		if [ -n "$dev" ]; then
+			echo "$dev"
+			return 0
+		fi
+		sleep 0.1
+	done
+
+	return 1
+}
+
+# ip link del returns after NETDEV_UNREGISTER, but rxe tears the RDMA device
+# down asynchronously via ib_unregister_device_queued(). Wait until our names
+# are gone.
+wait_rdma_devs_gone()
+{
+	local i name ns
+	local names=("$RXE_A" "$RXE_B" "$RXE_SAME" "$RXE_NEW")
+
+	for i in $(seq 1 50); do
+		local found=0
+
+		for name in "${names[@]}"; do
+			if rdma_dev_exists "" "$name"; then
+				found=1
+				break
+			fi
+			for ns in "$NS1" "$NS2"; do
+				ip netns exec "$ns" true 2>/dev/null || continue
+				if rdma_dev_exists "$ns" "$name"; then
+					found=1
+					break 2
+				fi
+			done
+		done
+
+		[ "$found" -eq 0 ] && return 0
+		sleep 0.1
+	done
+
+	return 1
+}
+
+setup_devs()
+{
+	cleanup_devs || return 1
+
+	add_dummy "$DUMMY_A" || return 1
+	add_dummy "$DUMMY_B" || return 1
+
+	add_rxe "$RXE_A" "$DUMMY_A" || return 1
+	add_rxe "$RXE_B" "$DUMMY_B" || return 1
+}
+
+cleanup_devs()
+{
+	ip link del "$DUMMY_A" 2>/dev/null
+	ip link del "$DUMMY_B" 2>/dev/null
+	wait_rdma_devs_gone
+}
+
+setup()
+{
+	OLD_MODE=$(rdma system show 2>/dev/null |
+		   sed -n 's/.*netns \([^ ]*\).*/\1/p')
+	[ -n "$OLD_MODE" ] || ksft_skip "failed to read RDMA netns mode"
+
+	rdma system set netns exclusive >/dev/null 2>&1 ||
+		ksft_skip "rdma netns exclusive mode is not supported"
+	MODE_CHANGED=1
+
+	ip netns add "$NS1" || return 1
+	ip netns add "$NS2" || return 1
+}
+
+# ip netns del returns before rdma_dev_exit_net() removes the net from
+# rdma_nets. rdma_compatdev_set() returns -EBUSY until that completes, so
+# retry the mode restore instead of leaving the system in exclusive mode.
+restore_netns_mode()
+{
+	local i
+
+	[ "$MODE_CHANGED" -eq 1 ] || return 0
+
+	for i in $(seq 1 50); do
+		if rdma system set netns "$OLD_MODE" >/dev/null 2>&1; then
+			MODE_CHANGED=0
+			return 0
+		fi
+		sleep 0.1
+	done
+
+	echo "warning: failed to restore RDMA netns mode to $OLD_MODE" >&2
+	return 1
+}
+
+cleanup()
+{
+	cleanup_devs
+
+	ip netns del "$NS1" 2>/dev/null
+	ip netns del "$NS2" 2>/dev/null
+
+	restore_netns_mode
+
+	for m in "${MODS[@]}"; do
+		modprobe -r "$m" 2>/dev/null
+	done
+}
+
+rdma_supports_combined_move_rename()
+{
+	rdma dev help 2>&1 | grep -Eq 'netns .*name|name .*netns'
+}
+
+[ "$(id -u)" -eq 0 ] || ksft_skip "must be run as root"
+need_cmd ip
+need_cmd rdma
+need_cmd modprobe
+
+trap cleanup EXIT
+
+for m in "${MODS[@]}"; do
+	modinfo "$m" >/dev/null 2>&1 || ksft_skip "module $m not found"
+	modprobe "$m" || fail "failed to load $m"
+done
+
+setup || fail "failed to create net namespaces"
+
+ktap_print_header
+ktap_set_plan 6
+
+if setup_devs &&
+   rdma dev set "$RXE_A" netns "$NS1" &&
+   rdma_ns "$NS1" dev set "$RXE_A" name "$RXE_SAME" &&
+   rdma dev set "$RXE_B" netns "$NS2" &&
+   rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME" &&
+   rdma_dev_exists "$NS1" "$RXE_SAME" &&
+   rdma_dev_exists "$NS2" "$RXE_SAME"; then
+	ktap_test_pass "$TEST_SAME_NAMES"
+else
+	ktap_test_fail "$TEST_SAME_NAMES"
+fi
+cleanup_devs
+
+if ! setup_devs ||
+   ! rdma dev set "$RXE_A" netns "$NS1" ||
+   ! rdma_ns "$NS1" dev set "$RXE_A" name "$RXE_SAME" ||
+   ! rdma dev set "$RXE_B" netns "$NS2" ||
+   ! rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME"; then
+	ktap_test_fail "$TEST_MOVE_CONFLICT"
+elif rdma_ns "$NS1" dev set "$RXE_SAME" netns "$NS2" >/dev/null 2>&1; then
+	ktap_test_fail "$TEST_MOVE_CONFLICT"
+elif rdma_dev_exists "$NS1" "$RXE_SAME" &&
+     rdma_dev_exists "$NS2" "$RXE_SAME"; then
+	ktap_test_pass "$TEST_MOVE_CONFLICT"
+else
+	ktap_test_fail "$TEST_MOVE_CONFLICT"
+fi
+cleanup_devs
+
+if ! setup_devs; then
+	ktap_test_fail "$TEST_MOVE_RENAME"
+elif rdma dev set "$RXE_A" netns "$NS2" &&
+     rdma_ns "$NS2" dev set "$RXE_A" name "$RXE_NEW"; then
+	if rdma_dev_exists "$NS2" "$RXE_NEW" &&
+	   ! rdma_dev_exists "" "$RXE_A"; then
+		ktap_test_pass "$TEST_MOVE_RENAME"
+	else
+		ktap_test_fail "$TEST_MOVE_RENAME"
+	fi
+else
+	ktap_test_fail "$TEST_MOVE_RENAME"
+fi
+cleanup_devs
+
+if ! rdma_supports_combined_move_rename; then
+	ktap_test_skip "$TEST_COMBINED_MOVE_RENAME"
+elif ! setup_devs; then
+	ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
+elif rdma dev set "$RXE_A" netns "$NS2" name "$RXE_NEW"; then
+	if rdma_dev_exists "$NS2" "$RXE_NEW" &&
+	   ! rdma_dev_exists "" "$RXE_A"; then
+		ktap_test_pass "$TEST_COMBINED_MOVE_RENAME"
+	else
+		ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
+	fi
+else
+	ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
+fi
+cleanup_devs
+
+if ! setup_devs; then
+	ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
+elif rdma dev set "$RXE_A" name "$RXE_SAME" &&
+     rdma dev set "$RXE_B" name "$RXE_NEW"; then
+	if rdma dev set "$RXE_SAME" name "$RXE_NEW" >/dev/null 2>&1; then
+		ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
+	elif rdma_dev_exists "" "$RXE_SAME" &&
+	     rdma_dev_exists "" "$RXE_NEW"; then
+		ktap_test_pass "$TEST_SAME_NETNS_DUP_RENAME"
+	else
+		ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
+	fi
+else
+	ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
+fi
+cleanup_devs
+
+if ! setup_devs; then
+	ktap_test_fail "$TEST_TEARDOWN_RETURN"
+elif ! rdma dev set "$RXE_A" name "$RXE_SAME" ||
+     ! rdma dev set "$RXE_B" netns "$NS2" ||
+     ! rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME" ||
+     ! rdma_dev_exists "$NS2" "$RXE_SAME"; then
+	ktap_test_fail "$TEST_TEARDOWN_RETURN"
+else
+	ip netns del "$NS2"
+	returned=$(wait_rdma_dev_on_netdev "$DUMMY_B")
+	ktap_print_msg "device returned to init_net as '${returned:-<missing>}'"
+	if rdma_dev_exists "" "$RXE_SAME" &&
+	   [ -n "$returned" ] &&
+	   [ "$returned" != "$RXE_SAME" ] &&
+	   [ "${returned#ibdev}" != "$returned" ]; then
+		ktap_test_pass "$TEST_TEARDOWN_RETURN"
+	else
+		ktap_test_fail "$TEST_TEARDOWN_RETURN"
+	fi
+fi
+cleanup_devs
+
+ktap_finished
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test
  2026-07-16 13:23 ` [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test Jiri Pirko
@ 2026-07-17  4:22   ` Zhu Yanjun
  2026-07-17 13:24   ` sashiko-bot
  1 sibling, 0 replies; 24+ messages in thread
From: Zhu Yanjun @ 2026-07-17  4:22 UTC (permalink / raw)
  To: Jiri Pirko, linux-rdma, yanjun.zhu@linux.dev
  Cc: cgroups, netdev, linux-s390, linux-kselftest, jgg, leon, parav,
	mbloch, cmeiohas, roman.gushchin, bvanassche, zyjzyj2000, shuah,
	tj, mkoutny, hannes, alibuda, dust.li, sidraya, wenjia, cui.tao


在 2026/7/16 6:23, Jiri Pirko 写道:
> From: Jiri Pirko <jiri@nvidia.com>
>
> Add a kselftest script that exercises per-netns RDMA device naming
> with RXE. Cover duplicate names across namespaces, move conflict
> handling, move-with-rename, and same-namespace rename requests.
>
> Signed-off-by: Jiri Pirko <jiri@nvidia.com>
> ---
> v2->v3:
> - added wait for rdma devices are removed
> - added retry for old rdma netns mode restore
> v1->v2:
> - fixed ktap_set_plan
> - s/RXE_A/RXE_SAME/ in dup rename
> ---
>   tools/testing/selftests/rdma/Makefile         |   3 +-
>   tools/testing/selftests/rdma/config           |   2 +
>   .../testing/selftests/rdma/rxe_netns_names.sh | 334 ++++++++++++++++++
>   3 files changed, 338 insertions(+), 1 deletion(-)
>   create mode 100755 tools/testing/selftests/rdma/rxe_netns_names.sh
>
> diff --git a/tools/testing/selftests/rdma/Makefile b/tools/testing/selftests/rdma/Makefile
> index 07af7f15c1bf..a91c14c45006 100644
> --- a/tools/testing/selftests/rdma/Makefile
> +++ b/tools/testing/selftests/rdma/Makefile
> @@ -3,6 +3,7 @@ TEST_PROGS := rxe_rping_between_netns.sh \
>   		rxe_ipv6.sh \
>   		rxe_socket_with_netns.sh \
>   		rxe_test_NETDEV_UNREGISTER.sh \
> -		rxe_sent_rcvd_bytes.sh
> +		rxe_sent_rcvd_bytes.sh \
> +		rxe_netns_names.sh
>   
>   include ../lib.mk
> diff --git a/tools/testing/selftests/rdma/config b/tools/testing/selftests/rdma/config
> index 4ffb814e253b..e1ff54ec0f57 100644
> --- a/tools/testing/selftests/rdma/config
> +++ b/tools/testing/selftests/rdma/config
> @@ -1,3 +1,5 @@
>   CONFIG_TUN
>   CONFIG_VETH
> +CONFIG_DUMMY
> +CONFIG_NET_NS
>   CONFIG_RDMA_RXE
> diff --git a/tools/testing/selftests/rdma/rxe_netns_names.sh b/tools/testing/selftests/rdma/rxe_netns_names.sh
> new file mode 100755
> index 000000000000..f40118407f4c
> --- /dev/null
> +++ b/tools/testing/selftests/rdma/rxe_netns_names.sh
> @@ -0,0 +1,334 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Exercise RDMA device name handling across network namespaces.
> +
> +source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
> +
> +NAME_PREFIX="rxe_netns_names_$$"
> +NETDEV_PREFIX="rxn$$"
> +NS1="${NAME_PREFIX}ns1"
> +NS2="${NAME_PREFIX}ns2"
> +RXE_A="${NAME_PREFIX}rxe_a"
> +RXE_B="${NAME_PREFIX}rxe_b"
> +RXE_SAME="${NAME_PREFIX}rxe_same"
> +RXE_NEW="${NAME_PREFIX}rxe_new"
> +DUMMY_A="${NETDEV_PREFIX}a"
> +DUMMY_B="${NETDEV_PREFIX}b"
> +OLD_MODE=""
> +MODE_CHANGED=0
> +MODS=("dummy" "rdma_rxe")
> +TEST_SAME_NAMES="same RDMA device name can exist in two net namespaces"
> +TEST_MOVE_CONFLICT="move without rename fails on destination name conflict"
> +TEST_MOVE_RENAME="move then rename succeeds"
> +TEST_COMBINED_MOVE_RENAME="move with requested destination name succeeds"
> +TEST_SAME_NETNS_DUP_RENAME="same-netns rename rejects duplicate name"
> +TEST_TEARDOWN_RETURN="netns delete returns device to init_net and renames on conflict"
> +
> +ksft_skip()
> +{
> +	ktap_skip_all "$*"
> +	exit "$KSFT_SKIP"
> +}
> +
> +fail()
> +{
> +	ktap_exit_fail_msg "$*"
> +}
> +
> +need_cmd()
> +{
> +	command -v "$1" >/dev/null 2>&1 || ksft_skip "missing command: $1"
> +}
> +
> +rdma_ns()
> +{
> +	local ns=$1
> +
> +	shift
> +	ip netns exec "$ns" rdma "$@"
> +}
> +
> +rdma_dev_exists()
> +{
> +	local ns=$1
> +	local dev=$2
> +
> +	if [ -n "$ns" ]; then
> +		rdma_ns "$ns" dev show "$dev" >/dev/null 2>&1
> +	else
> +		rdma dev show "$dev" >/dev/null 2>&1
> +	fi
> +}
> +
> +add_dummy()
> +{
> +	local netdev=$1
> +
> +	ip link add "$netdev" type dummy || return 1
> +	ip link set "$netdev" up || return 1
> +}
> +
> +add_rxe()
> +{
> +	local dev=$1
> +	local netdev=$2
> +
> +	rdma link add "$dev" type rxe netdev "$netdev"
> +}
> +
> +rdma_dev_on_netdev()
> +{
> +	local netdev=$1
> +
> +	rdma link show 2>/dev/null | awk -v want="$netdev" '
> +		{
> +			for (i = 1; i < NF; i++)
> +				if ($i == "netdev" && $(i + 1) == want) {
> +					dev = $2
> +					sub(/\/.*/, "", dev)
> +					print dev
> +					exit
> +				}
> +		}'
> +}
> +
> +wait_rdma_dev_on_netdev()
> +{
> +	local netdev=$1
> +	local dev
> +	local i
> +
> +	for i in $(seq 1 50); do
> +		dev=$(rdma_dev_on_netdev "$netdev")
> +		if [ -n "$dev" ]; then
> +			echo "$dev"
> +			return 0
> +		fi
> +		sleep 0.1
> +	done
> +
> +	return 1
> +}
> +
> +# ip link del returns after NETDEV_UNREGISTER, but rxe tears the RDMA device
> +# down asynchronously via ib_unregister_device_queued(). Wait until our names
> +# are gone.
> +wait_rdma_devs_gone()
> +{
> +	local i name ns
> +	local names=("$RXE_A" "$RXE_B" "$RXE_SAME" "$RXE_NEW")
> +
> +	for i in $(seq 1 50); do
> +		local found=0
> +
> +		for name in "${names[@]}"; do
> +			if rdma_dev_exists "" "$name"; then
> +				found=1
> +				break
> +			fi
> +			for ns in "$NS1" "$NS2"; do
> +				ip netns exec "$ns" true 2>/dev/null || continue
> +				if rdma_dev_exists "$ns" "$name"; then
> +					found=1
> +					break 2
> +				fi
> +			done
> +		done
> +
> +		[ "$found" -eq 0 ] && return 0
> +		sleep 0.1
> +	done
> +
> +	return 1
> +}
> +
> +setup_devs()
> +{
> +	cleanup_devs || return 1
> +
> +	add_dummy "$DUMMY_A" || return 1
> +	add_dummy "$DUMMY_B" || return 1
> +
> +	add_rxe "$RXE_A" "$DUMMY_A" || return 1
> +	add_rxe "$RXE_B" "$DUMMY_B" || return 1
> +}
> +
> +cleanup_devs()
> +{
> +	ip link del "$DUMMY_A" 2>/dev/null
> +	ip link del "$DUMMY_B" 2>/dev/null
> +	wait_rdma_devs_gone
> +}
> +
> +setup()
> +{
> +	OLD_MODE=$(rdma system show 2>/dev/null |
> +		   sed -n 's/.*netns \([^ ]*\).*/\1/p')
> +	[ -n "$OLD_MODE" ] || ksft_skip "failed to read RDMA netns mode"
> +
> +	rdma system set netns exclusive >/dev/null 2>&1 ||
> +		ksft_skip "rdma netns exclusive mode is not supported"
> +	MODE_CHANGED=1
> +
> +	ip netns add "$NS1" || return 1
> +	ip netns add "$NS2" || return 1
> +}
> +
> +# ip netns del returns before rdma_dev_exit_net() removes the net from
> +# rdma_nets. rdma_compatdev_set() returns -EBUSY until that completes, so
> +# retry the mode restore instead of leaving the system in exclusive mode.
> +restore_netns_mode()
> +{
> +	local i
> +
> +	[ "$MODE_CHANGED" -eq 1 ] || return 0
> +
> +	for i in $(seq 1 50); do
> +		if rdma system set netns "$OLD_MODE" >/dev/null 2>&1; then
> +			MODE_CHANGED=0
> +			return 0
> +		fi
> +		sleep 0.1
> +	done
> +
> +	echo "warning: failed to restore RDMA netns mode to $OLD_MODE" >&2
> +	return 1
> +}
> +
> +cleanup()
> +{
> +	cleanup_devs
> +
> +	ip netns del "$NS1" 2>/dev/null
> +	ip netns del "$NS2" 2>/dev/null
> +
> +	restore_netns_mode
> +
> +	for m in "${MODS[@]}"; do
> +		modprobe -r "$m" 2>/dev/null
> +	done
> +}
> +
> +rdma_supports_combined_move_rename()
> +{
> +	rdma dev help 2>&1 | grep -Eq 'netns .*name|name .*netns'
> +}
> +
> +[ "$(id -u)" -eq 0 ] || ksft_skip "must be run as root"
> +need_cmd ip
> +need_cmd rdma
> +need_cmd modprobe
> +
> +trap cleanup EXIT
> +
> +for m in "${MODS[@]}"; do
> +	modinfo "$m" >/dev/null 2>&1 || ksft_skip "module $m not found"
> +	modprobe "$m" || fail "failed to load $m"
> +done
> +
> +setup || fail "failed to create net namespaces"
> +
> +ktap_print_header
> +ktap_set_plan 6

Hi, Jiri

Thanks a lot.

With the first version of this patch series, I already ran the selftests 
with RXE, and everything worked as expected.

Only test case 4 was skipped because it depends on a recent commit.

Once that commit is merged, I'll rerun the tests.

As for the numbering, I'm fine with changing it from 7 to 6.

Thanks a lot.

Zhu Yanjun

> +
> +if setup_devs &&
> +   rdma dev set "$RXE_A" netns "$NS1" &&
> +   rdma_ns "$NS1" dev set "$RXE_A" name "$RXE_SAME" &&
> +   rdma dev set "$RXE_B" netns "$NS2" &&
> +   rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME" &&
> +   rdma_dev_exists "$NS1" "$RXE_SAME" &&
> +   rdma_dev_exists "$NS2" "$RXE_SAME"; then
> +	ktap_test_pass "$TEST_SAME_NAMES"
> +else
> +	ktap_test_fail "$TEST_SAME_NAMES"
> +fi
> +cleanup_devs
> +
> +if ! setup_devs ||
> +   ! rdma dev set "$RXE_A" netns "$NS1" ||
> +   ! rdma_ns "$NS1" dev set "$RXE_A" name "$RXE_SAME" ||
> +   ! rdma dev set "$RXE_B" netns "$NS2" ||
> +   ! rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME"; then
> +	ktap_test_fail "$TEST_MOVE_CONFLICT"
> +elif rdma_ns "$NS1" dev set "$RXE_SAME" netns "$NS2" >/dev/null 2>&1; then
> +	ktap_test_fail "$TEST_MOVE_CONFLICT"
> +elif rdma_dev_exists "$NS1" "$RXE_SAME" &&
> +     rdma_dev_exists "$NS2" "$RXE_SAME"; then
> +	ktap_test_pass "$TEST_MOVE_CONFLICT"
> +else
> +	ktap_test_fail "$TEST_MOVE_CONFLICT"
> +fi
> +cleanup_devs
> +
> +if ! setup_devs; then
> +	ktap_test_fail "$TEST_MOVE_RENAME"
> +elif rdma dev set "$RXE_A" netns "$NS2" &&
> +     rdma_ns "$NS2" dev set "$RXE_A" name "$RXE_NEW"; then
> +	if rdma_dev_exists "$NS2" "$RXE_NEW" &&
> +	   ! rdma_dev_exists "" "$RXE_A"; then
> +		ktap_test_pass "$TEST_MOVE_RENAME"
> +	else
> +		ktap_test_fail "$TEST_MOVE_RENAME"
> +	fi
> +else
> +	ktap_test_fail "$TEST_MOVE_RENAME"
> +fi
> +cleanup_devs
> +
> +if ! rdma_supports_combined_move_rename; then
> +	ktap_test_skip "$TEST_COMBINED_MOVE_RENAME"
> +elif ! setup_devs; then
> +	ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
> +elif rdma dev set "$RXE_A" netns "$NS2" name "$RXE_NEW"; then
> +	if rdma_dev_exists "$NS2" "$RXE_NEW" &&
> +	   ! rdma_dev_exists "" "$RXE_A"; then
> +		ktap_test_pass "$TEST_COMBINED_MOVE_RENAME"
> +	else
> +		ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
> +	fi
> +else
> +	ktap_test_fail "$TEST_COMBINED_MOVE_RENAME"
> +fi
> +cleanup_devs
> +
> +if ! setup_devs; then
> +	ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
> +elif rdma dev set "$RXE_A" name "$RXE_SAME" &&
> +     rdma dev set "$RXE_B" name "$RXE_NEW"; then
> +	if rdma dev set "$RXE_SAME" name "$RXE_NEW" >/dev/null 2>&1; then
> +		ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
> +	elif rdma_dev_exists "" "$RXE_SAME" &&
> +	     rdma_dev_exists "" "$RXE_NEW"; then
> +		ktap_test_pass "$TEST_SAME_NETNS_DUP_RENAME"
> +	else
> +		ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
> +	fi
> +else
> +	ktap_test_fail "$TEST_SAME_NETNS_DUP_RENAME"
> +fi
> +cleanup_devs
> +
> +if ! setup_devs; then
> +	ktap_test_fail "$TEST_TEARDOWN_RETURN"
> +elif ! rdma dev set "$RXE_A" name "$RXE_SAME" ||
> +     ! rdma dev set "$RXE_B" netns "$NS2" ||
> +     ! rdma_ns "$NS2" dev set "$RXE_B" name "$RXE_SAME" ||
> +     ! rdma_dev_exists "$NS2" "$RXE_SAME"; then
> +	ktap_test_fail "$TEST_TEARDOWN_RETURN"
> +else
> +	ip netns del "$NS2"
> +	returned=$(wait_rdma_dev_on_netdev "$DUMMY_B")
> +	ktap_print_msg "device returned to init_net as '${returned:-<missing>}'"
> +	if rdma_dev_exists "" "$RXE_SAME" &&
> +	   [ -n "$returned" ] &&
> +	   [ "$returned" != "$RXE_SAME" ] &&
> +	   [ "${returned#ibdev}" != "$returned" ]; then
> +		ktap_test_pass "$TEST_TEARDOWN_RETURN"
> +	else
> +		ktap_test_fail "$TEST_TEARDOWN_RETURN"
> +	fi
> +fi
> +cleanup_devs
> +
> +ktap_finished

-- 
Best Regards,
Yanjun.Zhu


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace
  2026-07-16 13:23 ` [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace Jiri Pirko
@ 2026-07-17 13:24   ` sashiko-bot
  2026-07-17 14:06     ` Jiri Pirko
  0 siblings, 1 reply; 24+ messages in thread
From: sashiko-bot @ 2026-07-17 13:24 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Heiko Carstens, tj, mkoutny, hannes, linux-s390, Vasily Gorbik,
	Alexander Gordeev

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Skipping device_rename() during namespace teardown fallback leaves the sysfs kobject tagged with a dying namespace, leading to Use-After-Free.
--

--- Patch [2]: [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace ---
commit 8e5328bda494a60bcfbc9c96c81fb95f503e0fdd
Author: Jiri Pirko <jiri@resnulli.us>

RDMA/core: Handle device name conflicts when changing net namespace
    
Prepare namespace moves for per-netns names. Check user-initiated moves for
destination-name conflicts before disabling the device, keep same-netns
moves as no-ops, and make teardown moves detach from the exiting namespace
even if fallback naming fails.

> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index de610f52c9b23..b55fb075d0aef 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
[ ... ]
> @@ -1704,30 +1778,63 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
>  		goto out;
>  	}
>  
[ ... ]
>  	/*
> -	 * At this point no one can be using the device, so it is safe to
> -	 * change the namespace.
> +	 * Recompute the destination name under the write side of devices_rwsem
> +	 * now that the device is disabled, closing races with a concurrent
> +	 * registration or rename, then publish the new namespace at the sysfs
> +	 * level.
>  	 */
> -	write_pnet(&device->coredev.rdma_net, net);
> +	down_write(&devices_rwsem);
> +	ret = rdma_dev_pick_netns_name(device, net, fallback_pattern, buf,
> +				       sizeof(buf), &new_name);
> +	if (ret) {
> +		if (fallback_pattern) {
> +			WARN(1,
> +			     "%s: failed to pick device name during namespace teardown: %d\n",
> +			     __func__, ret);
> +			write_pnet(&device->coredev.rdma_net, net);
> +			ret = 0;
> +		}
> +		goto rename_done;
> +	}
>  
> -	down_read(&devices_rwsem);
> -	/*
> -	 * Currently rdma devices are system wide unique. So the device name
> -	 * is guaranteed free in the new namespace. Publish the new namespace
> -	 * at the sysfs level.
> -	 */
> -	ret = device_rename(&device->dev, dev_name(&device->dev));
> -	up_read(&devices_rwsem);
> +	write_pnet(&device->coredev.rdma_net, net);
> +	ret = device_rename(&device->dev, new_name);
>  	if (ret) {
> -		dev_warn(&device->dev,
> -			 "%s: Couldn't rename device after namespace change\n",
> -			 __func__);
> -		/* Try and put things back and re-enable the device */
> -		write_pnet(&device->coredev.rdma_net, cur_net);
> +		if (fallback_pattern) {
> +			WARN(1,
> +			     "%s: failed to rename device during namespace teardown: %d\n",
> +			     __func__, ret);
> +			ret = 0;
> +		} else {

[Severity: High]
This isn't a bug introduced by this patch, but does skipping device_rename()
during namespace teardown fallback leave the sysfs kobject tagged with a dying
namespace?

If rdma_dev_pick_netns_name() fails and the code jumps to rename_done, or if
device_rename() fails and the error is suppressed by setting ret = 0, the
kernfs_node->ns tag for the device's sysfs directory would appear to remain
pointing to the dying network namespace.

Once the network namespace is freed, couldn't a subsequent sysfs traversal or
lookup calling kernfs_ns_id(kn->ns) dereference the freed pointer and result
in a use-after-free?

> +			dev_warn(&device->dev,
> +				 "%s: Couldn't rename device after namespace change\n",
> +				 __func__);
> +			/* Try and put things back and re-enable the device */
> +			write_pnet(&device->coredev.rdma_net, cur_net);
> +		}
> +	} else {
> +		strscpy(device->name, dev_name(&device->dev),
> +			IB_DEVICE_NAME_MAX);
>  	}
> +rename_done:
> +	up_write(&devices_rwsem);
>  
>  	ret2 = enable_device_and_get(device);
>  	if (ret2) {

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=2

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack
  2026-07-16 13:23 ` [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack Jiri Pirko
@ 2026-07-17 13:24   ` sashiko-bot
  0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-07-17 13:24 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Vasily Gorbik, tj, Alexander Gordeev, linux-s390, hannes,
	Heiko Carstens, mkoutny

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The newly added feature to support renaming an RDMA device while moving its network namespace is inaccessible from userspace due to a logic flaw in the netlink handler. Additionally, providing both attributes silently aborts the namespace move.
--

--- Patch [4]: [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack ---
commit dd68e4a951ab0b58504bc034673213514633a1a1
Author: Jiri Pirko <jiri@resnulli.us>

RDMA/nldev: Report net namespace move errors through extack

Thread extack through the existing net namespace move helper and report the
main failure reasons from the core path. Keep the existing move UAPI shape
unchanged.

> diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
> index 77a7580801486..8648e95700bfa 100644
> --- a/drivers/infiniband/core/nldev.c
> +++ b/drivers/infiniband/core/nldev.c
> @@ -1195,10 +1195,8 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		u32 ns_fd;
>  
>  		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
> -		err = ib_device_set_netns_put(skb, device, ns_fd, NULL);
> -		if (err == -EEXIST)
> -			NL_SET_ERR_MSG(extack,
> -				       "Device name already exists in the target net namespace");
> +		err = ib_device_set_netns_put(skb, device, ns_fd, NULL,
> +					      extack);

[Severity: High]
Does this logic prioritize the device rename and exit early, preventing the
namespace move from occurring if both attributes are present?

Looking at nldev_set_doit(), if a user with CAP_NET_ADMIN provides both
RDMA_NLDEV_ATTR_DEV_NAME and RDMA_NLDEV_NET_NS_FD in a single message:

    if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
        /* ... */
        err = ib_device_rename(device, name);
        goto done;
    }

won't the handler process the rename and hit a goto done; silently skipping
the namespace move? This could result in a success response while leaving the
device in the old namespace.

Additionally, it unconditionally passes NULL as the name to
ib_device_set_netns_put() in the patched hunk above. Doesn't this render
the rename-on-move functionality completely inaccessible from userspace?

>  		goto put_done;
>  	}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=4

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the net namespace
  2026-07-16 13:23 ` [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the " Jiri Pirko
@ 2026-07-17 13:24   ` sashiko-bot
  2026-07-17 14:08     ` Jiri Pirko
  0 siblings, 1 reply; 24+ messages in thread
From: sashiko-bot @ 2026-07-17 13:24 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: tj, Alexander Gordeev, hannes, mkoutny, Heiko Carstens,
	Vasily Gorbik, linux-s390

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] `smc_pnet_find_ib()` and `smc_pnet_find_smcd()` return unreferenced pointers leading to a Use-After-Free during concurrent device removal.
--

--- Patch [6]: [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the net namespace ---
commit 22bac16fe9606993a05fb72609386eb7b37fed92
Author: Jiri Pirko <jiri@resnulli.us>

net/smc: Look up the pnetid ib device within the net namespace

Scope smc_pnet_find_ib() to the caller's net namespace so pnetid setup
cannot bind to a same-named RDMA device from another namespace once names
become per-netns.

> diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
> index 63e286e2dfaa8..ff9c9c35cc2f5 100644
> --- a/net/smc/smc_pnet.c
> +++ b/net/smc/smc_pnet.c

[ ... ]

> @@ -408,8 +413,8 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
>  	return rc;
>  }
>  
> -static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
> -			   u8 ib_port, char *pnet_name)
> +static int smc_pnet_add_ib(struct smc_pnettable *pnettable, struct net *net,
> +			   char *ib_name, u8 ib_port, char *pnet_name)
>  {
>  	struct smc_pnetentry *tmp_pe, *new_pe;
>  	struct smc_ib_device *ib_dev;
> @@ -419,7 +424,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
>  	bool new_ibdev;
>  
>  	/* try to apply the pnetid to active devices */
> -	ib_dev = smc_pnet_find_ib(ib_name);
> +	ib_dev = smc_pnet_find_ib(net, ib_name);

[Severity: Critical]
This isn't a bug introduced by this patch, but does returning an unreferenced
pointer from smc_pnet_find_ib() create a use-after-free window?

Looking at smc_pnet_find_ib(), the function holds smc_ib_devices.mutex while
finding the device, but then drops the lock and returns the raw ibdev pointer:

net/smc/smc_pnet.c:smc_pnet_find_ib() {
    ...
    out:
        mutex_unlock(&smc_ib_devices.mutex);
        return ibdev;
}

If a concurrent device removal path acquires the mutex, removes the device
from the list, and frees the struct smc_ib_device via kfree(), could the
netlink thread subsequently dereference the freed pointer?

>  	if (ib_dev) {
>  		ibdev_applied = smc_pnet_apply_ib(ib_dev, ib_port, pnet_name);
>  		if (ibdev_applied)

For example, smc_pnet_apply_ib() re-acquires the mutex and writes to
ib_dev->pnetid, and the caller then reads ib_dev->ibdev->name for logging.

Does this same unreferenced pointer pattern also affect smc_pnet_find_smcd()
when it is called immediately after?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=6

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its net namespace
  2026-07-16 13:23 ` [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its " Jiri Pirko
@ 2026-07-17 13:24   ` sashiko-bot
  0 siblings, 0 replies; 24+ messages in thread
From: sashiko-bot @ 2026-07-17 13:24 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: tj, linux-s390, Vasily Gorbik, Alexander Gordeev, hannes, mkoutny,
	Heiko Carstens

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The netlink handler fails to pass the requested device name to `ib_device_set_netns_put` during a network namespace change, and ignores namespace moves entirely if a rename is also requested.
--

--- Patch [3]: [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its net namespace ---
commit 65e19be4bcb60d41b06e567081d99cee8fd2722c
Author: Jiri Pirko <jiri@resnulli.us>

RDMA/core: Support renaming a device when changing its net namespace

This commit adds support for renaming a device at the same time it is moved
to a new network namespace. It allows namespace moves to request a specific
destination device name, falling back to a trusted kernel-controlled pattern
if none is provided.

> diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
> index 32b6c4d68ca0a..77a7580801486 100644
> --- a/drivers/infiniband/core/nldev.c
> +++ b/drivers/infiniband/core/nldev.c
> @@ -1195,7 +1195,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		u32 ns_fd;
>  
>  		ns_fd = nla_get_u32(tb[RDMA_NLDEV_NET_NS_FD]);
> -		err = ib_device_set_netns_put(skb, device, ns_fd);
> +		err = ib_device_set_netns_put(skb, device, ns_fd, NULL);

[Severity: Medium]
Does this hardcoded NULL prevent the core feature from being reached?

It appears the newly added name parameter in ib_device_set_netns_put() is 
never populated with the requested device name from the netlink attributes 
in nldev_set_doit(). 

If a user provides both RDMA_NLDEV_ATTR_DEV_NAME and RDMA_NLDEV_NET_NS_FD,
the rename-during-move functionality cannot be used. Additionally, if the
name attribute is parsed in a separate block, the function appears to take
an early exit path, bypassing the namespace move entirely.

Could this be updated to properly process both attributes and pass the
requested device name during the move?

>  		if (err == -EEXIST)
>  			NL_SET_ERR_MSG(extack,
>  				       "Device name already exists in the target net namespace");

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=3

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test
  2026-07-16 13:23 ` [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test Jiri Pirko
  2026-07-17  4:22   ` Zhu Yanjun
@ 2026-07-17 13:24   ` sashiko-bot
  2026-07-17 14:09     ` Jiri Pirko
  1 sibling, 1 reply; 24+ messages in thread
From: sashiko-bot @ 2026-07-17 13:24 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: tj, mkoutny, hannes, Vasily Gorbik, linux-s390, Heiko Carstens,
	Alexander Gordeev

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] `wait_rdma_devs_gone()` fails to wait for dynamically renamed RDMA devices (e.g., `ibdevX`) to finish asynchronous unregistration, potentially causing module unload failures.
--

--- Patch [14]: [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test ---
commit dabec57822c009814520c6cece67efb39fb7b1f8
Author: Jiri Pirko <jiri@resnulli.us>

RDMA/selftests: Add rxe_netns_names test

This commit adds a kselftest script that exercises per-netns RDMA device
naming with RXE. It covers duplicate names, conflicts, move-with-rename, and
same-namespace rename requests.

> diff --git a/tools/testing/selftests/rdma/rxe_netns_names.sh b/tools/testing/selftests/rdma/rxe_netns_names.sh
> new file mode 100755
> index 0000000000000..f40118407f4c0
> --- /dev/null
> +++ b/tools/testing/selftests/rdma/rxe_netns_names.sh

[ ... ]

> +wait_rdma_devs_gone()
> +{
> +	local i name ns
> +	local names=("$RXE_A" "$RXE_B" "$RXE_SAME" "$RXE_NEW")

[Severity: Medium]
Does this hardcoded list of names miss dynamically assigned fallback names
like 'ibdevX'?

During the TEST_TEARDOWN_RETURN test, the device moves back to init_net and
conflicts with an existing name, receiving a dynamic fallback name (e.g.,
ibdev0). When cleanup_devs() deletes the underlying dummy netdevs, it calls
wait_rdma_devs_gone() to wait for asynchronous unregistration.

Since the dynamic name isn't in this list of expected names, the function may
return early before the device actually finishes tearing down. Could this
cause the script to fail to unload the rdma_rxe module or leave a dirty state
for subsequent tests?

> +
> +	for i in $(seq 1 50); do
> +		local found=0
> +
> +		for name in "${names[@]}"; do
> +			if rdma_dev_exists "" "$name"; then
> +				found=1
> +				break
> +			fi

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=14

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace
  2026-07-17 13:24   ` sashiko-bot
@ 2026-07-17 14:06     ` Jiri Pirko
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-17 14:06 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: Heiko Carstens, tj, mkoutny, hannes, linux-s390, Vasily Gorbik,
	Alexander Gordeev

Fri, Jul 17, 2026 at 03:24:24PM +0200, sashiko-bot@kernel.org wrote:
>Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
>Pre-existing issues:
>- [High] Skipping device_rename() during namespace teardown fallback leaves the sysfs kobject tagged with a dying namespace, leading to Use-After-Free.
>--
>
>--- Patch [2]: [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace ---
>commit 8e5328bda494a60bcfbc9c96c81fb95f503e0fdd
>Author: Jiri Pirko <jiri@resnulli.us>
>
>RDMA/core: Handle device name conflicts when changing net namespace
>    
>Prepare namespace moves for per-netns names. Check user-initiated moves for
>destination-name conflicts before disabling the device, keep same-netns
>moves as no-ops, and make teardown moves detach from the exiting namespace
>even if fallback naming fails.
>
>> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
>> index de610f52c9b23..b55fb075d0aef 100644
>> --- a/drivers/infiniband/core/device.c
>> +++ b/drivers/infiniband/core/device.c
>[ ... ]
>> @@ -1704,30 +1778,63 @@ static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
>>  		goto out;
>>  	}
>>  
>[ ... ]
>>  	/*
>> -	 * At this point no one can be using the device, so it is safe to
>> -	 * change the namespace.
>> +	 * Recompute the destination name under the write side of devices_rwsem
>> +	 * now that the device is disabled, closing races with a concurrent
>> +	 * registration or rename, then publish the new namespace at the sysfs
>> +	 * level.
>>  	 */
>> -	write_pnet(&device->coredev.rdma_net, net);
>> +	down_write(&devices_rwsem);
>> +	ret = rdma_dev_pick_netns_name(device, net, fallback_pattern, buf,
>> +				       sizeof(buf), &new_name);
>> +	if (ret) {
>> +		if (fallback_pattern) {
>> +			WARN(1,
>> +			     "%s: failed to pick device name during namespace teardown: %d\n",
>> +			     __func__, ret);
>> +			write_pnet(&device->coredev.rdma_net, net);
>> +			ret = 0;
>> +		}
>> +		goto rename_done;
>> +	}
>>  
>> -	down_read(&devices_rwsem);
>> -	/*
>> -	 * Currently rdma devices are system wide unique. So the device name
>> -	 * is guaranteed free in the new namespace. Publish the new namespace
>> -	 * at the sysfs level.
>> -	 */
>> -	ret = device_rename(&device->dev, dev_name(&device->dev));
>> -	up_read(&devices_rwsem);
>> +	write_pnet(&device->coredev.rdma_net, net);
>> +	ret = device_rename(&device->dev, new_name);
>>  	if (ret) {
>> -		dev_warn(&device->dev,
>> -			 "%s: Couldn't rename device after namespace change\n",
>> -			 __func__);
>> -		/* Try and put things back and re-enable the device */
>> -		write_pnet(&device->coredev.rdma_net, cur_net);
>> +		if (fallback_pattern) {
>> +			WARN(1,
>> +			     "%s: failed to rename device during namespace teardown: %d\n",
>> +			     __func__, ret);
>> +			ret = 0;
>> +		} else {
>
>[Severity: High]
>This isn't a bug introduced by this patch, but does skipping device_rename()
>during namespace teardown fallback leave the sysfs kobject tagged with a dying
>namespace?
>
>If rdma_dev_pick_netns_name() fails and the code jumps to rename_done, or if
>device_rename() fails and the error is suppressed by setting ret = 0, the
>kernfs_node->ns tag for the device's sysfs directory would appear to remain
>pointing to the dying network namespace.
>
>Once the network namespace is freed, couldn't a subsequent sysfs traversal or
>lookup calling kernfs_ns_id(kn->ns) dereference the freed pointer and result
>in a use-after-free?

unrelated to this patch/set. Ignoring.


>
>> +			dev_warn(&device->dev,
>> +				 "%s: Couldn't rename device after namespace change\n",
>> +				 __func__);
>> +			/* Try and put things back and re-enable the device */
>> +			write_pnet(&device->coredev.rdma_net, cur_net);
>> +		}
>> +	} else {
>> +		strscpy(device->name, dev_name(&device->dev),
>> +			IB_DEVICE_NAME_MAX);
>>  	}
>> +rename_done:
>> +	up_write(&devices_rwsem);
>>  
>>  	ret2 = enable_device_and_get(device);
>>  	if (ret2) {
>
>-- 
>Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=2

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the net namespace
  2026-07-17 13:24   ` sashiko-bot
@ 2026-07-17 14:08     ` Jiri Pirko
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-17 14:08 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: tj, Alexander Gordeev, hannes, mkoutny, Heiko Carstens,
	Vasily Gorbik, linux-s390

Fri, Jul 17, 2026 at 03:24:27PM +0200, sashiko-bot@kernel.org wrote:
>Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
>Pre-existing issues:
>- [Critical] `smc_pnet_find_ib()` and `smc_pnet_find_smcd()` return unreferenced pointers leading to a Use-After-Free during concurrent device removal.
>--
>
>--- Patch [6]: [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the net namespace ---
>commit 22bac16fe9606993a05fb72609386eb7b37fed92
>Author: Jiri Pirko <jiri@resnulli.us>
>
>net/smc: Look up the pnetid ib device within the net namespace
>
>Scope smc_pnet_find_ib() to the caller's net namespace so pnetid setup
>cannot bind to a same-named RDMA device from another namespace once names
>become per-netns.
>
>> diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
>> index 63e286e2dfaa8..ff9c9c35cc2f5 100644
>> --- a/net/smc/smc_pnet.c
>> +++ b/net/smc/smc_pnet.c
>
>[ ... ]
>
>> @@ -408,8 +413,8 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
>>  	return rc;
>>  }
>>  
>> -static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
>> -			   u8 ib_port, char *pnet_name)
>> +static int smc_pnet_add_ib(struct smc_pnettable *pnettable, struct net *net,
>> +			   char *ib_name, u8 ib_port, char *pnet_name)
>>  {
>>  	struct smc_pnetentry *tmp_pe, *new_pe;
>>  	struct smc_ib_device *ib_dev;
>> @@ -419,7 +424,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
>>  	bool new_ibdev;
>>  
>>  	/* try to apply the pnetid to active devices */
>> -	ib_dev = smc_pnet_find_ib(ib_name);
>> +	ib_dev = smc_pnet_find_ib(net, ib_name);
>
>[Severity: Critical]
>This isn't a bug introduced by this patch, but does returning an unreferenced
>pointer from smc_pnet_find_ib() create a use-after-free window?
>
>Looking at smc_pnet_find_ib(), the function holds smc_ib_devices.mutex while
>finding the device, but then drops the lock and returns the raw ibdev pointer:
>
>net/smc/smc_pnet.c:smc_pnet_find_ib() {
>    ...
>    out:
>        mutex_unlock(&smc_ib_devices.mutex);
>        return ibdev;
>}
>
>If a concurrent device removal path acquires the mutex, removes the device
>from the list, and frees the struct smc_ib_device via kfree(), could the
>netlink thread subsequently dereference the freed pointer?
>
>>  	if (ib_dev) {
>>  		ibdev_applied = smc_pnet_apply_ib(ib_dev, ib_port, pnet_name);
>>  		if (ibdev_applied)
>
>For example, smc_pnet_apply_ib() re-acquires the mutex and writes to
>ib_dev->pnetid, and the caller then reads ib_dev->ibdev->name for logging.
>
>Does this same unreferenced pointer pattern also affect smc_pnet_find_smcd()
>when it is called immediately after?

Unrelated to this patch/set. Ignoring.


>
>-- 
>Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=6

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test
  2026-07-17 13:24   ` sashiko-bot
@ 2026-07-17 14:09     ` Jiri Pirko
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2026-07-17 14:09 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: tj, mkoutny, hannes, Vasily Gorbik, linux-s390, Heiko Carstens,
	Alexander Gordeev

Fri, Jul 17, 2026 at 03:24:28PM +0200, sashiko-bot@kernel.org wrote:
>Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>- [Medium] `wait_rdma_devs_gone()` fails to wait for dynamically renamed RDMA devices (e.g., `ibdevX`) to finish asynchronous unregistration, potentially causing module unload failures.
>--
>
>--- Patch [14]: [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test ---
>commit dabec57822c009814520c6cece67efb39fb7b1f8
>Author: Jiri Pirko <jiri@resnulli.us>
>
>RDMA/selftests: Add rxe_netns_names test
>
>This commit adds a kselftest script that exercises per-netns RDMA device
>naming with RXE. It covers duplicate names, conflicts, move-with-rename, and
>same-namespace rename requests.
>
>> diff --git a/tools/testing/selftests/rdma/rxe_netns_names.sh b/tools/testing/selftests/rdma/rxe_netns_names.sh
>> new file mode 100755
>> index 0000000000000..f40118407f4c0
>> --- /dev/null
>> +++ b/tools/testing/selftests/rdma/rxe_netns_names.sh
>
>[ ... ]
>
>> +wait_rdma_devs_gone()
>> +{
>> +	local i name ns
>> +	local names=("$RXE_A" "$RXE_B" "$RXE_SAME" "$RXE_NEW")
>
>[Severity: Medium]
>Does this hardcoded list of names miss dynamically assigned fallback names
>like 'ibdevX'?
>
>During the TEST_TEARDOWN_RETURN test, the device moves back to init_net and
>conflicts with an existing name, receiving a dynamic fallback name (e.g.,
>ibdev0). When cleanup_devs() deletes the underlying dummy netdevs, it calls
>wait_rdma_devs_gone() to wait for asynchronous unregistration.

*Very* unlikely. Ignoring.


>
>Since the dynamic name isn't in this list of expected names, the function may
>return early before the device actually finishes tearing down. Could this
>cause the script to fail to unload the rdma_rxe module or leave a dirty state
>for subsequent tests?
>
>> +
>> +	for i in $(seq 1 50); do
>> +		local found=0
>> +
>> +		for name in "${names[@]}"; do
>> +			if rdma_dev_exists "" "$name"; then
>> +				found=1
>> +				break
>> +			fi
>
>[ ... ]
>
>-- 
>Sashiko AI review · https://sashiko.dev/#/patchset/20260716132316.1495242-1-jiri@resnulli.us?part=14

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2026-07-17 14:16 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 13:23 [PATCH rdma-next v3 00/14] RDMA: Make device names unique per net namespace Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 01/14] RDMA/core: Pass the net namespace to the device name lookups Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 02/14] RDMA/core: Handle device name conflicts when changing net namespace Jiri Pirko
2026-07-17 13:24   ` sashiko-bot
2026-07-17 14:06     ` Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 03/14] RDMA/core: Support renaming a device when changing its " Jiri Pirko
2026-07-17 13:24   ` sashiko-bot
2026-07-16 13:23 ` [PATCH rdma-next v3 04/14] RDMA/nldev: Report net namespace move errors through extack Jiri Pirko
2026-07-17 13:24   ` sashiko-bot
2026-07-16 13:23 ` [PATCH rdma-next v3 05/14] RDMA/nldev: Allow setting the device name while changing net namespace Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 06/14] net/smc: Look up the pnetid ib device within the " Jiri Pirko
2026-07-17 13:24   ` sashiko-bot
2026-07-17 14:08     ` Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 07/14] RDMA/srp: Make the SRP sysfs class net namespace aware Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 08/14] RDMA/cgroup: Disambiguate devices across net namespaces Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 09/14] RDMA/cma: Document that CM configfs cannot be net namespace scoped Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 10/14] RDMA/core: Document the SELinux ibendport net namespace limitation Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 11/14] RDMA/core: Make device names unique per net namespace Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 12/14] RDMA/rxe: Allow queue VMAs to outlive ucontexts Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 13/14] RDMA/rxe: Implement disassociate_ucontext callback Jiri Pirko
2026-07-16 13:23 ` [PATCH rdma-next v3 14/14] RDMA/selftests: Add rxe_netns_names test Jiri Pirko
2026-07-17  4:22   ` Zhu Yanjun
2026-07-17 13:24   ` sashiko-bot
2026-07-17 14:09     ` Jiri Pirko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox