[PATCH rdma-next 11/13] RDMA/hfi1: Defer device creation until probe succeeds

From: Leon Romanovsky

Date: Wed Jul 08 2026 - 06:50:07 EST


From: Leon Romanovsky <leonro@xxxxxxxxxx>

init_one() creates the character device before checking whether generic or
IB initialization failed, only to remove it immediately while unwinding.
Moreover, user_add() already calls user_remove() when device creation
fails.

Move hfi1_device_create() after the initialization failure path,
immediately before starting SDMA. The failure path then has no character
device to remove, and hfi1_device_create() continues to unwind its own
failures.

Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx>
---
drivers/infiniband/hw/hfi1/init.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 6c642b68ad86..d17f319ad9f2 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -1558,7 +1558,7 @@ static void postinit_cleanup(struct hfi1_devdata *dd)

static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int ret = 0, j, pidx, initfail;
+ int ret = 0, pidx, initfail;
struct hfi1_devdata *dd;
struct hfi1_pportdata *ppd;

@@ -1633,9 +1633,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

/*
* Now ready for use. this should be cleared whenever we
- * detect a reset, or initiate one. If earlier failure,
- * we still create devices, so diags, etc. can be used
- * to determine cause of problem.
+ * detect a reset, or initiate one.
*/
if (!initfail && !ret) {
dd->flags |= HFI1_INITTED;
@@ -1643,10 +1641,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
hfi1_dbg_ibdev_init(&dd->verbs_dev);
}

- j = hfi1_device_create(dd);
- if (j)
- dd_dev_err(dd, "Failed to create /dev devices: %d\n", -j);
-
if (initfail || ret) {
msix_clean_up_interrupts(dd);
stop_timers(dd);
@@ -1656,8 +1650,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(ppd->hfi1_wq);
destroy_workqueue(ppd->link_wq);
}
- if (!j)
- hfi1_device_remove(dd);
if (!ret)
hfi1_unregister_ib_device(dd);
hfi1_free_rx(dd);
@@ -1667,6 +1659,11 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return ret; /* everything already cleaned */
}

+ ret = hfi1_device_create(dd);
+ if (ret)
+ dd_dev_err(dd, "Failed to create /dev devices: %pe\n",
+ ERR_PTR(ret));
+
sdma_start(dd);

return 0;

--
2.54.0