Commit 4351ca3f authored by Håkon Bugge's avatar Håkon Bugge Committed by Jakub Kicinski
Browse files

rds: ib: Increment i_fastreg_wrs before bailing out



We need to increment i_fastreg_wrs before we bail out from
rds_ib_post_reg_frmr().

We have a fixed budget of how many FRWR operations that can be
outstanding using the dedicated QP used for memory registrations and
de-registrations. This budget is enforced by the atomic_t
i_fastreg_wrs. If we bail out early in rds_ib_post_reg_frmr(), we will
"leak" the possibility of posting an FRWR operation, and if that
accumulates, no FRWR operation can be carried out.

Fixes: 1659185f ("RDS: IB: Support Fastreg MR (FRMR) memory registration mode")
Fixes: 3a2886cc ("net/rds: Keep track of and wait for FRWR segments in use upon shutdown")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarHåkon Bugge <haakon.bugge@oracle.com>
Reviewed-by: default avatarAllison Henderson <allison.henderson@oracle.com>
Link: https://patch.msgid.link/20250911133336.451212-1-haakon.bugge@oracle.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2e5fb2ff
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -133,12 +133,15 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)

	ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_dma_len,
				&off, PAGE_SIZE);
	if (unlikely(ret != ibmr->sg_dma_len))
		return ret < 0 ? ret : -EINVAL;
	if (unlikely(ret != ibmr->sg_dma_len)) {
		ret = ret < 0 ? ret : -EINVAL;
		goto out_inc;
	}

	if (cmpxchg(&frmr->fr_state,
		    FRMR_IS_FREE, FRMR_IS_INUSE) != FRMR_IS_FREE)
		return -EBUSY;
	if (cmpxchg(&frmr->fr_state, FRMR_IS_FREE, FRMR_IS_INUSE) != FRMR_IS_FREE) {
		ret = -EBUSY;
		goto out_inc;
	}

	atomic_inc(&ibmr->ic->i_fastreg_inuse_count);

@@ -166,11 +169,10 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
		/* Failure here can be because of -ENOMEM as well */
		rds_transition_frwr_state(ibmr, FRMR_IS_INUSE, FRMR_IS_STALE);

		atomic_inc(&ibmr->ic->i_fastreg_wrs);
		if (printk_ratelimit())
			pr_warn("RDS/IB: %s returned error(%d)\n",
				__func__, ret);
		goto out;
		goto out_inc;
	}

	/* Wait for the registration to complete in order to prevent an invalid
@@ -179,8 +181,10 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
	 */
	wait_event(frmr->fr_reg_done, !frmr->fr_reg);

out:
	return ret;

out_inc:
	atomic_inc(&ibmr->ic->i_fastreg_wrs);
	return ret;
}