RDMA/srpt: Fix srpt_alloc_rw_ctxs() unwind counters

When srpt_alloc_rw_ctxs() fails partway through a multi-buffer indirect
descriptor, the unwind path destroys RDMA contexts but leaves stale
n_rw_ctx and n_rdma values (and a dangling rw_ctxs pointer). Later
sq_wr_avail accounting in srpt_queue_response() or srpt_write_pending()
can then subtract the wrong number of send queue credits.

Reset the counters and clear rw_ctxs after freeing the heap
allocation before returning an error.

Fixes: b99f8e4d7b ("IB/srpt: convert to the generic RDMA READ/WRITE API")
Signed-off-by: TanZheng <tanzheng@kylinos.cn>
Link: https://patch.msgid.link/20260715101550.45345-1-kensanya@163.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
TanZheng 2026-07-15 18:15:50 +08:00 committed by Leon Romanovsky
parent d38c835925
commit b38f98e176

View File

@ -959,6 +959,7 @@ static int srpt_alloc_rw_ctxs(struct srpt_send_ioctx *ioctx,
struct srpt_rdma_ch *ch = ioctx->ch;
struct scatterlist *prev = NULL;
unsigned prev_nents;
u8 n_rdma, n_rw_ctx;
int ret, i;
if (nbufs == 1) {
@ -969,6 +970,9 @@ static int srpt_alloc_rw_ctxs(struct srpt_send_ioctx *ioctx,
return -ENOMEM;
}
n_rw_ctx = ioctx->n_rw_ctx;
n_rdma = ioctx->n_rdma;
for (i = ioctx->n_rw_ctx; i < nbufs; i++, db++) {
struct srpt_rw_ctx *ctx = &ioctx->rw_ctxs[i];
u64 remote_addr = be64_to_cpu(db->va);
@ -1015,6 +1019,9 @@ static int srpt_alloc_rw_ctxs(struct srpt_send_ioctx *ioctx,
}
if (ioctx->rw_ctxs != &ioctx->s_rw_ctx)
kfree(ioctx->rw_ctxs);
ioctx->rw_ctxs = NULL;
ioctx->n_rw_ctx = n_rw_ctx;
ioctx->n_rdma = n_rdma;
return ret;
}