public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
From: Zhu Yanjun <yanjun.zhu@linux.dev>
To: Evan Green <evgreen@meta.com>, Zhu Yanjun <zyjzyj2000@gmail.com>
Cc: wguay@meta.com, Jason Gunthorpe <jgg@ziepe.ca>,
	Leon Romanovsky <leon@kernel.org>,
	linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org
Subject: Re: [PATCH v2] RDMA/rxe: Generate async error for r_key violations
Date: Sat, 21 Feb 2026 02:35:48 -0800	[thread overview]
Message-ID: <2ce6c1d6-2634-415a-aa26-e998b4dc0135@linux.dev> (raw)
In-Reply-To: <20260220185533.252759-1-evgreen@meta.com>


在 2026/2/20 10:55, Evan Green 写道:
> Table 63 of the IBTA spec lists R_Key violations as a class C
> error. 9.9.3.1.3 Responder Class C Fault Behavior indicates an
> affiliated asynchronous error should be generated at the responder
> if the error can be associated to a QP but not a particular RX WQE.
>
> Relevant portion of the spec:
> C9-222.1.1: For an HCA responder using Reliable Connection service, for
> a Class C responder side error, the error shall be reported to the
> requester by generating the appropriate NAK code as specified in Table 63
> Responder Error Behavior Summary on page 448. If the error can be related
> to a particular QP but cannot be related to a particular WQE on that
> receive queue (e.g. the error occurred while executing an RDMA Write
> Request without immediate data), the error shall be reported to the
> responder’s client as an Affiliated Asynchronous error. See Section
> 10.10.2.3 Asynchronous Errors on page 576 for details. If the error can be
> related to a particular WQE on a given receive queue, the QP shall be
> placed into the error state and the error shall be reported to the
> responder’s client as a Completion error.
>
> Generate an affiliated asynchronous error upon Rkey violations
> if the opcode does not carry an immediate. This causes async
> events at the responder for all ops that generate R_Key violations
> except WRITE_WITH_IMM, where the error can ride in with the RX WQE.
>
> Signed-off-by: Evan Green <evgreen@meta.com>
> Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
>
> ---
>
> Changes in v2:
>   - Add spec paragraph to commit message (Yanjun)

Thank you very much. I’m fine with that. Let’s wait for comments from 
Leon or Jason.

Best Regards,

Zhu Yanjun


>
>   drivers/infiniband/sw/rxe/rxe_resp.c  | 56 ++++++++++++++++++++-------
>   drivers/infiniband/sw/rxe/rxe_verbs.h |  1 +
>   2 files changed, 44 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
> index 711f73e0bbb1..9faf8c09aa8e 100644
> --- a/drivers/infiniband/sw/rxe/rxe_resp.c
> +++ b/drivers/infiniband/sw/rxe/rxe_resp.c
> @@ -37,6 +37,7 @@ static char *resp_state_name[] = {
>   	[RESPST_ERR_MISSING_OPCODE_LAST_D1E]	= "ERR_MISSING_OPCODE_LAST_D1E",
>   	[RESPST_ERR_TOO_MANY_RDMA_ATM_REQ]	= "ERR_TOO_MANY_RDMA_ATM_REQ",
>   	[RESPST_ERR_RNR]			= "ERR_RNR",
> +	[RESPST_ERR_RKEY_VIOLATION_EVENT]	= "ERR_RKEY_VIOLATION_EVENT",
>   	[RESPST_ERR_RKEY_VIOLATION]		= "ERR_RKEY_VIOLATION",
>   	[RESPST_ERR_INVALIDATE_RKEY]		= "ERR_INVALIDATE_RKEY_VIOLATION",
>   	[RESPST_ERR_LENGTH]			= "ERR_LENGTH",
> @@ -423,6 +424,19 @@ static void qp_resp_from_atmeth(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
>   	qp->resp.resid = sizeof(u64);
>   }
>   
> +/* Transition to an rkey violation state. C9-222.1 requires an async event
> + * at the responder, but only if the error cannot be attached to an RX WQE.
> + * WRITE_WITH_IMM is the only op that might have that more precise RX WQE
> + * to pin the error on.
> + */
> +static enum resp_states get_rkey_violation_state(struct rxe_pkt_info *pkt)
> +{
> +	if (pkt->mask & RXE_IMMDT_MASK)
> +		return RESPST_ERR_RKEY_VIOLATION;
> +
> +	return RESPST_ERR_RKEY_VIOLATION_EVENT;
> +}
> +
>   /* resolve the packet rkey to qp->resp.mr or set qp->resp.mr to NULL
>    * if an invalid rkey is received or the rdma length is zero. For middle
>    * or last packets use the stored value of mr.
> @@ -486,14 +500,14 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
>   		mw = rxe_lookup_mw(qp, access, rkey);
>   		if (!mw) {
>   			rxe_dbg_qp(qp, "no MW matches rkey %#x\n", rkey);
> -			state = RESPST_ERR_RKEY_VIOLATION;
> +			state = get_rkey_violation_state(pkt);
>   			goto err;
>   		}
>   
>   		mr = mw->mr;
>   		if (!mr) {
>   			rxe_dbg_qp(qp, "MW doesn't have an MR\n");
> -			state = RESPST_ERR_RKEY_VIOLATION;
> +			state = get_rkey_violation_state(pkt);
>   			goto err;
>   		}
>   
> @@ -507,7 +521,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
>   		mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
>   		if (!mr) {
>   			rxe_dbg_qp(qp, "no MR matches rkey %#x\n", rkey);
> -			state = RESPST_ERR_RKEY_VIOLATION;
> +			state = get_rkey_violation_state(pkt);
>   			goto err;
>   		}
>   	}
> @@ -521,7 +535,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
>   	}
>   
>   	if (mr_check_range(mr, va + qp->resp.offset, resid)) {
> -		state = RESPST_ERR_RKEY_VIOLATION;
> +		state = get_rkey_violation_state(pkt);
>   		goto err;
>   	}
>   
> @@ -586,7 +600,7 @@ static enum resp_states write_data_in(struct rxe_qp *qp,
>   	err = rxe_mr_copy(qp->resp.mr, qp->resp.va + qp->resp.offset,
>   			  payload_addr(pkt), data_len, RXE_TO_MR_OBJ);
>   	if (err) {
> -		rc = RESPST_ERR_RKEY_VIOLATION;
> +		rc = get_rkey_violation_state(pkt);
>   		goto out;
>   	}
>   
> @@ -667,7 +681,7 @@ static enum resp_states process_flush(struct rxe_qp *qp,
>   
>   	if (res->flush.type & IB_FLUSH_PERSISTENT) {
>   		if (rxe_flush_pmem_iova(mr, start, length))
> -			return RESPST_ERR_RKEY_VIOLATION;
> +			return get_rkey_violation_state(pkt);
>   		/* Make data persistent. */
>   		wmb();
>   	} else if (res->flush.type & IB_FLUSH_GLOBAL) {
> @@ -1383,6 +1397,20 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
>   	return rc;
>   }
>   
> +static void do_qp_event(struct rxe_qp *qp, enum ib_event_type etype)
> +{
> +	struct ib_event event;
> +	struct ib_qp *ibqp = &qp->ibqp;
> +
> +	event.event = etype;
> +	event.device = ibqp->device;
> +	event.element.qp = ibqp;
> +	if (ibqp->event_handler) {
> +		rxe_dbg_qp(qp, "reporting QP event %d\n", etype);
> +		ibqp->event_handler(&event, ibqp->qp_context);
> +	}
> +}
> +
>   /* Process a class A or C. Both are treated the same in this implementation. */
>   static void do_class_ac_error(struct rxe_qp *qp, u8 syndrome,
>   			      enum ib_wc_status status)
> @@ -1476,14 +1504,9 @@ static void flush_recv_queue(struct rxe_qp *qp, bool notify)
>   	int err;
>   
>   	if (qp->srq) {
> -		if (notify && qp->ibqp.event_handler) {
> -			struct ib_event ev;
> +		if (notify && qp->ibqp.event_handler)
> +			do_qp_event(qp, IB_EVENT_QP_LAST_WQE_REACHED);
>   
> -			ev.device = qp->ibqp.device;
> -			ev.element.qp = &qp->ibqp;
> -			ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
> -			qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
> -		}
>   		return;
>   	}
>   
> @@ -1613,6 +1636,13 @@ int rxe_receiver(struct rxe_qp *qp)
>   			state = RESPST_CLEANUP;
>   			break;
>   
> +		case RESPST_ERR_RKEY_VIOLATION_EVENT:
> +			if (qp_type(qp) == IB_QPT_RC)
> +				do_qp_event(qp, IB_EVENT_QP_ACCESS_ERR);
> +
> +			state = RESPST_ERR_RKEY_VIOLATION;
> +			break;
> +
>   		case RESPST_ERR_RKEY_VIOLATION:
>   			if (qp_type(qp) == IB_QPT_RC) {
>   				/* Class C */
> diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
> index fb149f37e91d..d92f80d16f78 100644
> --- a/drivers/infiniband/sw/rxe/rxe_verbs.h
> +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
> @@ -154,6 +154,7 @@ enum resp_states {
>   	RESPST_ERR_MISSING_OPCODE_LAST_D1E,
>   	RESPST_ERR_TOO_MANY_RDMA_ATM_REQ,
>   	RESPST_ERR_RNR,
> +	RESPST_ERR_RKEY_VIOLATION_EVENT,
>   	RESPST_ERR_RKEY_VIOLATION,
>   	RESPST_ERR_INVALIDATE_RKEY,
>   	RESPST_ERR_LENGTH,

-- 
Best Regards,
Yanjun.Zhu


  reply	other threads:[~2026-02-21 10:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-20 18:55 [PATCH v2] RDMA/rxe: Generate async error for r_key violations Evan Green
2026-02-21 10:35 ` Zhu Yanjun [this message]
2026-02-24  9:57 ` Leon Romanovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2ce6c1d6-2634-415a-aa26-e998b4dc0135@linux.dev \
    --to=yanjun.zhu@linux.dev \
    --cc=evgreen@meta.com \
    --cc=jgg@ziepe.ca \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=wguay@meta.com \
    --cc=zyjzyj2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox