RDMA/hfi1: Defer device creation until probe succeeds

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.

Link: https://patch.msgid.link/20260708-clean-init-one-hfi1-v1-11-b9e9641268a5@nvidia.com
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
This commit is contained in:
Leon Romanovsky 2026-07-13 07:41:25 -04:00
parent d43b1c17f9
commit 9bab31776a

View File

@ -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;