[PATCH] RDMA/core: Fix swapped list_add_tail() arguments in ib_add_sub_device()

lirongqing posted 1 patch 1 week, 1 day ago
drivers/infiniband/core/device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] RDMA/core: Fix swapped list_add_tail() arguments in ib_add_sub_device()
Posted by lirongqing 1 week, 1 day ago
From: Li RongQing <lirongqing@baidu.com>

ib_add_sub_device() links a new sub-device into its parent's sub-device
list with:

	list_add_tail(&parent->subdev_list_head, &sub->subdev_list);

list_add_tail(new, head) expects the node to insert as the first
argument and the list head as the second, so the call above does the
opposite of what was intended: it treats the parent's list head as the
new node and the sub-device's node as the list head.

Because _ib_alloc_device() initialises subdev_list to a self-referencing
empty head, the misplaced insertion does not crash, but it corrupts the
parent->subdev_list_head list.  After adding two or more sub-devices,
only the last one is reachable through the parent's head, and
ib_del_sub_device_and_put()'s list_del() on &sub->subdev_list rewrites
the head pointers, potentially severing earlier sub-devices from the
chain.  During parent teardown, the reverse iteration over
subdev_list_head then skips the orphaned sub-devices, so their
del_sub_dev() callbacks are never invoked and ib_device_put() on the
parent is never paired, leaking both the HW sub-devices and a refcount.

Swap the arguments to match the documented intent: insert the
sub-device node into the parent's list head.

Fixes: bca51197620a ("RDMA/core: Support IB sub device with type "SMI"")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
 drivers/infiniband/core/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 7a3ed5e..05dd890 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -3067,7 +3067,7 @@ int ib_add_sub_device(struct ib_device *parent,
 	sub->parent = parent;
 
 	mutex_lock(&parent->subdev_lock);
-	list_add_tail(&parent->subdev_list_head, &sub->subdev_list);
+	list_add_tail(&sub->subdev_list, &parent->subdev_list_head);
 	mutex_unlock(&parent->subdev_lock);
 
 	return ret;
-- 
2.9.4
Re: [PATCH] RDMA/core: Fix swapped list_add_tail() arguments in ib_add_sub_device()
Posted by Leon Romanovsky 6 days, 16 hours ago
On Wed, 16 Sep 2026 14:44:35 +0800, lirongqing wrote:
> ib_add_sub_device() links a new sub-device into its parent's sub-device
> list with:
> 
> 	list_add_tail(&parent->subdev_list_head, &sub->subdev_list);
> 
> list_add_tail(new, head) expects the node to insert as the first
> argument and the list head as the second, so the call above does the
> opposite of what was intended: it treats the parent's list head as the
> new node and the sub-device's node as the list head.
> 
> [...]

Applied, thanks!

[1/1] RDMA/core: Fix swapped list_add_tail() arguments in ib_add_sub_device()
      https://git.kernel.org/rdma/rdma/c/fad7b0dcb0821c

Best regards,
-- 
Leon Romanovsky <leon@kernel.org>