Skip to content

Commit 0099103

Browse files
committed
RDMA/uverbs: Fix error unwind in ib_uverbs_add_one
The error path has several mistakes - cdev_del should not be called if cdev_device_add fails - We must call put_device on all the goto exit paths as that is what frees the uapi, SRCU and the struct itself. While we are here consolidate all the uvdev_dev init that cannot fail at the top. Fixes: c5c4d92 ("RDMA/uverbs: Use cdev_device_add() instead of cdev_add()") Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Reviewed-by: Parav Pandit <parav@mellanox.com>
1 parent 0965cc9 commit 0099103

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

drivers/infiniband/core/uverbs_main.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,13 +1028,21 @@ static void ib_uverbs_add_one(struct ib_device *device)
10281028
return;
10291029
}
10301030

1031+
device_initialize(&uverbs_dev->dev);
1032+
uverbs_dev->dev.class = uverbs_class;
1033+
uverbs_dev->dev.parent = device->dev.parent;
1034+
uverbs_dev->dev.release = ib_uverbs_release_dev;
1035+
uverbs_dev->groups[0] = &dev_attr_group;
1036+
uverbs_dev->dev.groups = uverbs_dev->groups;
10311037
atomic_set(&uverbs_dev->refcount, 1);
10321038
init_completion(&uverbs_dev->comp);
10331039
uverbs_dev->xrcd_tree = RB_ROOT;
10341040
mutex_init(&uverbs_dev->xrcd_tree_mutex);
10351041
mutex_init(&uverbs_dev->lists_mutex);
10361042
INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list);
10371043
INIT_LIST_HEAD(&uverbs_dev->uverbs_events_file_list);
1044+
rcu_assign_pointer(uverbs_dev->ib_dev, device);
1045+
uverbs_dev->num_comp_vectors = device->num_comp_vectors;
10381046

10391047
devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
10401048
if (devnum >= IB_UVERBS_MAX_DEVICES)
@@ -1046,19 +1054,10 @@ static void ib_uverbs_add_one(struct ib_device *device)
10461054
else
10471055
base = IB_UVERBS_BASE_DEV + devnum;
10481056

1049-
rcu_assign_pointer(uverbs_dev->ib_dev, device);
1050-
uverbs_dev->num_comp_vectors = device->num_comp_vectors;
1051-
10521057
if (ib_uverbs_create_uapi(device, uverbs_dev))
10531058
goto err_uapi;
10541059

1055-
device_initialize(&uverbs_dev->dev);
1056-
uverbs_dev->dev.class = uverbs_class;
1057-
uverbs_dev->dev.parent = device->dev.parent;
10581060
uverbs_dev->dev.devt = base;
1059-
uverbs_dev->dev.release = ib_uverbs_release_dev;
1060-
uverbs_dev->groups[0] = &dev_attr_group;
1061-
uverbs_dev->dev.groups = uverbs_dev->groups;
10621061
dev_set_name(&uverbs_dev->dev, "uverbs%d", uverbs_dev->devnum);
10631062

10641063
cdev_init(&uverbs_dev->cdev,
@@ -1067,20 +1066,18 @@ static void ib_uverbs_add_one(struct ib_device *device)
10671066

10681067
ret = cdev_device_add(&uverbs_dev->cdev, &uverbs_dev->dev);
10691068
if (ret)
1070-
goto err_cdev;
1069+
goto err_uapi;
10711070

10721071
ib_set_client_data(device, &uverbs_client, uverbs_dev);
10731072
return;
10741073

1075-
err_cdev:
1076-
cdev_del(&uverbs_dev->cdev);
1077-
put_device(&uverbs_dev->dev);
10781074
err_uapi:
10791075
clear_bit(devnum, dev_map);
10801076
err:
10811077
if (atomic_dec_and_test(&uverbs_dev->refcount))
10821078
ib_uverbs_comp_dev(uverbs_dev);
10831079
wait_for_completion(&uverbs_dev->comp);
1080+
put_device(&uverbs_dev->dev);
10841081
return;
10851082
}
10861083

0 commit comments

Comments
 (0)