Commit 81f44409 authored by Krzysztof Czurylo's avatar Krzysztof Czurylo Committed by Leon Romanovsky
Browse files

RDMA/irdma: Fix data race in irdma_free_pble



Protects pble_rsrc counters with mutex to prevent data race.
Fixes the following data race in irdma_free_pble reported by KCSAN:

BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma]

write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5:
 irdma_free_pble+0x3b/0xb0 [irdma]
 irdma_dereg_mr+0x108/0x110 [irdma]
 ib_dereg_mr_user+0x74/0x160 [ib_core]
 uverbs_free_mr+0x26/0x30 [ib_uverbs]
 destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs]
 uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs]
 uobj_destroy+0x61/0xb0 [ib_uverbs]
 ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs]
 ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs]
 ib_uverbs_ioctl+0x111/0x190 [ib_uverbs]
 __x64_sys_ioctl+0xc9/0x100
 do_syscall_64+0x44/0xa0
 entry_SYSCALL_64_after_hwframe+0x6e/0xd8

read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2:
 irdma_free_pble+0x23/0xb0 [irdma]
 irdma_dereg_mr+0x108/0x110 [irdma]
 ib_dereg_mr_user+0x74/0x160 [ib_core]
 uverbs_free_mr+0x26/0x30 [ib_uverbs]
 destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs]
 uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs]
 uobj_destroy+0x61/0xb0 [ib_uverbs]
 ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs]
 ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs]
 ib_uverbs_ioctl+0x111/0x190 [ib_uverbs]
 __x64_sys_ioctl+0xc9/0x100
 do_syscall_64+0x44/0xa0
 entry_SYSCALL_64_after_hwframe+0x6e/0xd8

value changed: 0x0000000000005a62 -> 0x0000000000005a68

Fixes: e8c4dbc2 ("RDMA/irdma: Add PBLE resource manager")
Signed-off-by: default avatarKrzysztof Czurylo <krzysztof.czurylo@intel.com>
Signed-off-by: default avatarTatyana Nikolova <tatyana.e.nikolova@intel.com>
Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent a5219281
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -506,12 +506,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,
void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,
		     struct irdma_pble_alloc *palloc)
{
	pble_rsrc->freedpbles += palloc->total_cnt;

	if (palloc->level == PBLE_LEVEL_2)
		free_lvl2(pble_rsrc, palloc);
	else
		irdma_prm_return_pbles(&pble_rsrc->pinfo,
				       &palloc->level1.chunkinfo);

	mutex_lock(&pble_rsrc->pble_mutex_lock);
	pble_rsrc->freedpbles += palloc->total_cnt;
	pble_rsrc->stats_alloc_freed++;
	mutex_unlock(&pble_rsrc->pble_mutex_lock);
}