Skip to content

Commit 60a8b5a

Browse files
Mike Marciniszynjgunthorpe
authored andcommitted
IB/hfi1: Fix leak of rcvhdrtail_dummy_kvaddr
This buffer is currently allocated in hfi1_init(): if (reinit) ret = init_after_reset(dd); else ret = loadtime_init(dd); if (ret) goto done; /* allocate dummy tail memory for all receive contexts */ dd->rcvhdrtail_dummy_kvaddr = dma_alloc_coherent(&dd->pcidev->dev, sizeof(u64), &dd->rcvhdrtail_dummy_dma, GFP_KERNEL); if (!dd->rcvhdrtail_dummy_kvaddr) { dd_dev_err(dd, "cannot allocate dummy tail memory\n"); ret = -ENOMEM; goto done; } The reinit triggered path will overwrite the old allocation and leak it. Fix by moving the allocation to hfi1_alloc_devdata() and the deallocation to hfi1_free_devdata(). Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Fixes: 46b010d ("staging/rdma/hfi1: Workaround to prevent corruption during packet delivery") Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent f6a3cfe commit 60a8b5a

File tree

1 file changed

+14
-19
lines changed
  • drivers/infiniband/hw/hfi1

1 file changed

+14
-19
lines changed

drivers/infiniband/hw/hfi1/init.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -875,18 +875,6 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
875875
if (ret)
876876
goto done;
877877

878-
/* allocate dummy tail memory for all receive contexts */
879-
dd->rcvhdrtail_dummy_kvaddr = dma_alloc_coherent(&dd->pcidev->dev,
880-
sizeof(u64),
881-
&dd->rcvhdrtail_dummy_dma,
882-
GFP_KERNEL);
883-
884-
if (!dd->rcvhdrtail_dummy_kvaddr) {
885-
dd_dev_err(dd, "cannot allocate dummy tail memory\n");
886-
ret = -ENOMEM;
887-
goto done;
888-
}
889-
890878
/* dd->rcd can be NULL if early initialization failed */
891879
for (i = 0; dd->rcd && i < dd->first_dyn_alloc_ctxt; ++i) {
892880
/*
@@ -1200,6 +1188,11 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
12001188
dd->tx_opstats = NULL;
12011189
kfree(dd->comp_vect);
12021190
dd->comp_vect = NULL;
1191+
if (dd->rcvhdrtail_dummy_kvaddr)
1192+
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
1193+
(void *)dd->rcvhdrtail_dummy_kvaddr,
1194+
dd->rcvhdrtail_dummy_dma);
1195+
dd->rcvhdrtail_dummy_kvaddr = NULL;
12031196
sdma_clean(dd, dd->num_sdma);
12041197
rvt_dealloc_device(&dd->verbs_dev.rdi);
12051198
}
@@ -1297,6 +1290,15 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
12971290
goto bail;
12981291
}
12991292

1293+
/* allocate dummy tail memory for all receive contexts */
1294+
dd->rcvhdrtail_dummy_kvaddr =
1295+
dma_alloc_coherent(&dd->pcidev->dev, sizeof(u64),
1296+
&dd->rcvhdrtail_dummy_dma, GFP_KERNEL);
1297+
if (!dd->rcvhdrtail_dummy_kvaddr) {
1298+
ret = -ENOMEM;
1299+
goto bail;
1300+
}
1301+
13001302
atomic_set(&dd->ipoib_rsm_usr_num, 0);
13011303
return dd;
13021304

@@ -1504,13 +1506,6 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
15041506

15051507
free_credit_return(dd);
15061508

1507-
if (dd->rcvhdrtail_dummy_kvaddr) {
1508-
dma_free_coherent(&dd->pcidev->dev, sizeof(u64),
1509-
(void *)dd->rcvhdrtail_dummy_kvaddr,
1510-
dd->rcvhdrtail_dummy_dma);
1511-
dd->rcvhdrtail_dummy_kvaddr = NULL;
1512-
}
1513-
15141509
/*
15151510
* Free any resources still in use (usually just kernel contexts)
15161511
* at unload; we do for ctxtcnt, because that's what we allocate.

0 commit comments

Comments
 (0)