drivers/infiniband/sw/rxe/rxe_mw.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/sw/rxe/rxe_mw.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/sw/rxe/rxe_mw.c
Extension
.c
Size
7152 bytes
Lines
339
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (unlikely(mw->state != RXE_MW_STATE_VALID)) {
			rxe_dbg_mw(mw,
				"attempt to bind a type 1 MW not in the valid state\n");
			return -EINVAL;
		}

		/* o10-36.2.2 */
		if (unlikely((access & IB_ZERO_BASED))) {
			rxe_dbg_mw(mw, "attempt to bind a zero based type 1 MW\n");
			return -EINVAL;
		}
	}

	if (mw->ibmw.type == IB_MW_TYPE_2) {
		/* o10-37.2.30 */
		if (unlikely(mw->state != RXE_MW_STATE_FREE)) {
			rxe_dbg_mw(mw,
				"attempt to bind a type 2 MW not in the free state\n");
			return -EINVAL;
		}

		/* C10-72 */
		if (unlikely(qp->pd != to_rpd(mw->ibmw.pd))) {
			rxe_dbg_mw(mw,
				"attempt to bind type 2 MW with qp with different PD\n");
			return -EINVAL;
		}

		/* o10-37.2.40 */
		if (unlikely(!mr || wqe->wr.wr.mw.length == 0)) {
			rxe_dbg_mw(mw,
				"attempt to invalidate type 2 MW by binding with NULL or zero length MR\n");
			return -EINVAL;
		}
	}

	/* remaining checks only apply to a nonzero MR */
	if (!mr)
		return 0;

	if (unlikely(mr->access & IB_ZERO_BASED)) {
		rxe_dbg_mw(mw, "attempt to bind MW to zero based MR\n");
		return -EINVAL;
	}

	/* C10-73 */
	if (unlikely(!(mr->access & IB_ACCESS_MW_BIND))) {
		rxe_dbg_mw(mw,
			"attempt to bind an MW to an MR without bind access\n");
		return -EINVAL;
	}

	/* C10-74 */
	if (unlikely((access &
		      (IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_ATOMIC)) &&
		     !(mr->access & IB_ACCESS_LOCAL_WRITE))) {
		rxe_dbg_mw(mw,
			"attempt to bind an Writable MW to an MR without local write access\n");
		return -EINVAL;
	}

	/* C10-75 */
	if (access & IB_ZERO_BASED) {
		if (unlikely(wqe->wr.wr.mw.length > mr->ibmr.length)) {
			rxe_dbg_mw(mw,
				"attempt to bind a ZB MW outside of the MR\n");
			return -EINVAL;
		}
	} else {
		if (unlikely((wqe->wr.wr.mw.addr < mr->ibmr.iova) ||
			     ((wqe->wr.wr.mw.addr + wqe->wr.wr.mw.length) >
			      (mr->ibmr.iova + mr->ibmr.length)))) {
			rxe_dbg_mw(mw,
				"attempt to bind a VA MW outside of the MR\n");
			return -EINVAL;
		}
	}

	return 0;
}

static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
		      struct rxe_mw *mw, struct rxe_mr *mr, int access)
{
	u32 key = wqe->wr.wr.mw.rkey & 0xff;

	mw->rkey = (mw->rkey & ~0xff) | key;
	mw->access = access;
	mw->state = RXE_MW_STATE_VALID;
	mw->addr = wqe->wr.wr.mw.addr;

Annotation

Implementation Notes