[PATCH rdma-next] RDMA/cxgb4: free STAG index when TPT entry write fails
Leon Romanovsky <[email protected]> Sun, 26 Jul 2026 15:21:44 +0300
| Newsgroups | org.kernel.vger.linux-rdma,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260726-leak-of-allocated-stag-idx-in-write-v1-1-72e0c401fc1a@nvidia.com> |
From: Leon Romanovsky <[email protected]> write_tpt_entry() allocates a new STAG index with c4iw_get_resource() and bumps stats.stag.cur before programming the entry. When write_adapter_mem() fails, it returns the error without releasing the index or reversing the statistic. No MR is inserted into rhp->mrs, so deregistration never reclaims it, leaking the index until device teardown. Record whether this call allocated the index and, on a failed write, return it to tpt_table and decrement stats.stag.cur. Key the rollback on both the write error and that flag, not the error alone: a non-reset update carries a caller-owned STAG that this call did not allocate and must not free. Fixes: ec3eead21718 ("RDMA/cxgb4: Remove kfifo usage") Signed-off-by: Leon Romanovsky <[email protected]> --- drivers/infiniband/hw/cxgb4/mem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index dc2f494b1007..562dba759df4 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -271,6 +271,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, int err; struct fw_ri_tpte *tpt; u32 stag_idx; + bool stag_idx_allocated = false; static atomic_t key; if (c4iw_fatal_error(rdev)) @@ -292,6 +293,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, kfree(tpt); return -ENOMEM; } + stag_idx_allocated = true; mutex_lock(&rdev->stats.lock); rdev->stats.stag.cur += 32; if (rdev->stats.stag.cur > rdev->stats.stag.max) @@ -327,7 +329,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, (rdev->lldi.vr->stag.start >> 5), sizeof(*tpt), tpt, skb, wr_waitp); - if (reset_tpt_entry) { + if (reset_tpt_entry || (err && stag_idx_allocated)) { c4iw_put_resource(&rdev->resource.tpt_table, stag_idx); mutex_lock(&rdev->stats.lock); rdev->stats.stag.cur -= 32; --- base-commit: a273210687f255b12c2f6baf8f25ff80cdbb29ed change-id: 20260726-leak-of-allocated-stag-idx-in-write-3eb7938e4636 Best regards, -- Leon Romanovsky <[email protected]>