The current teardown logic for dd->pio_map and dd->sdma_map frees the
structures while they might still be accessed by RCU readers. Although the
pointer is nulled under a spinlock, the memory is reclaimed before waiting
for the grace period to end.
This patch fixes the sequence by:
1. Extracting the pointer under the lock.
2. Clearing the RCU-protected pointer.
3. Waiting for readers to finish with synchronize_rcu().
4. Finally freeing the memory.
Fixes: 7724105686e7 ("IB/hfi1: add driver files")
Link: https://patch.msgid.link/r/20260206050836.5890-1-lirongqing@baidu.com
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
void free_pio_map(struct hfi1_devdata *dd)
{
+ struct pio_vl_map *map;
+
/* Free PIO map if allocated */
if (rcu_access_pointer(dd->pio_map)) {
spin_lock_irq(&dd->pio_map_lock);
- pio_map_free(rcu_access_pointer(dd->pio_map));
+ map = rcu_access_pointer(dd->pio_map);
RCU_INIT_POINTER(dd->pio_map, NULL);
spin_unlock_irq(&dd->pio_map_lock);
synchronize_rcu();
+ pio_map_free(map);
}
kfree(dd->kernel_send_context);
dd->kernel_send_context = NULL;
{
size_t i;
struct sdma_engine *sde;
+ struct sdma_vl_map *map;
if (dd->sdma_pad_dma) {
dma_free_coherent(&dd->pcidev->dev, SDMA_PAD,
}
if (rcu_access_pointer(dd->sdma_map)) {
spin_lock_irq(&dd->sde_map_lock);
- sdma_map_free(rcu_access_pointer(dd->sdma_map));
+ map = rcu_access_pointer(dd->sdma_map);
RCU_INIT_POINTER(dd->sdma_map, NULL);
spin_unlock_irq(&dd->sde_map_lock);
synchronize_rcu();
+ sdma_map_free(map);
}
kfree(dd->per_sdma);
dd->per_sdma = NULL;