When smc_ib_map_mr_sg() maps fewer entries than the SG table holds, smc_ib_get_memory_region() returns -EINVAL with the memory region still allocated and its pointer left in buf_slot->mr[link_idx]. The caller only undoes the DMA mapping and frees the SG table, and because buf_desc->is_map_ib[] is set only after this function succeeds, smcr_buf_unmap_link() later skips the buffer. Both the MR and the pd->usecnt reference taken by ib_alloc_mr() are lost. The stale pointer is also harmful: a retry takes the "already done" shortcut and treats a memory region that was never mapped as valid. Deregister the memory region and clear the slot before returning. Fixes: 897e1c245773 ("net/smc: use separate memory regions for RMBs") Cc: stable@vger.kernel.org Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex Signed-off-by: Wentao Liang --- net/smc/smc_ib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index daaa8a72da90..fa21d269196e 100644 --- a/net/smc/smc_ib.c +++ b/net/smc/smc_ib.c @@ -735,8 +735,11 @@ int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags, } if (smc_ib_map_mr_sg(buf_slot, link_idx) != - buf_slot->sgt[link_idx].orig_nents) + buf_slot->sgt[link_idx].orig_nents) { + smc_ib_put_memory_region(buf_slot->mr[link_idx]); + buf_slot->mr[link_idx] = NULL; return -EINVAL; + } return 0; } -- 2.34.1