RDMA/hfi1: Prevent use of lock before it is initialized
[ Upstream commit05c03dfd09
] If there is a failure during probe of hfi1 before the sdma_map_lock is initialized, the call to hfi1_free_devdata() will attempt to use a lock that has not been initialized. If the locking correctness validator is on then an INFO message and stack trace resembling the following may be seen: INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. Call Trace: register_lock_class+0x11b/0x880 __lock_acquire+0xf3/0x7930 lock_acquire+0xff/0x2d0 _raw_spin_lock_irq+0x46/0x60 sdma_clean+0x42a/0x660 [hfi1] hfi1_free_devdata+0x3a7/0x420 [hfi1] init_one+0x867/0x11a0 [hfi1] pci_device_probe+0x40e/0x8d0 The use of sdma_map_lock in sdma_clean() is for freeing the sdma_map memory, and sdma_map is not allocated/initialized until after sdma_map_lock has been initialized. This code only needs to be run if sdma_map is not NULL, and so checking for that condition will avoid trying to use the lock before it is initialized. Fixes:473291b3ea
("IB/hfi1: Fix for early release of sdma context") Fixes:7724105686
("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20220520183701.48973.72434.stgit@awfm-01.cornelisnetworks.com Reported-by: Zheyu Ma <zheyuma97@gmail.com> Signed-off-by: Douglas Miller <doug.miller@cornelisnetworks.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
119f99209d
Коммит
ca55150bff
|
@ -1288,11 +1288,13 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
|
|||
kvfree(sde->tx_ring);
|
||||
sde->tx_ring = NULL;
|
||||
}
|
||||
spin_lock_irq(&dd->sde_map_lock);
|
||||
sdma_map_free(rcu_access_pointer(dd->sdma_map));
|
||||
RCU_INIT_POINTER(dd->sdma_map, NULL);
|
||||
spin_unlock_irq(&dd->sde_map_lock);
|
||||
synchronize_rcu();
|
||||
if (rcu_access_pointer(dd->sdma_map)) {
|
||||
spin_lock_irq(&dd->sde_map_lock);
|
||||
sdma_map_free(rcu_access_pointer(dd->sdma_map));
|
||||
RCU_INIT_POINTER(dd->sdma_map, NULL);
|
||||
spin_unlock_irq(&dd->sde_map_lock);
|
||||
synchronize_rcu();
|
||||
}
|
||||
kfree(dd->per_sdma);
|
||||
dd->per_sdma = NULL;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче