Re: [PATCH v8 07/12] SIW queue pair methods

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 26, 2019 at 03:18:47PM +0200, Bernard Metzler wrote:
> From: Bernard Metzler <bmt@xxxxxxxxxxxxxxxxxxx>
>
> Signed-off-by: Bernard Metzler <bmt@xxxxxxxxxxxxxx>
> ---
>  drivers/infiniband/sw/siw/siw_qp.c | 1354 ++++++++++++++++++++++++++++
>  1 file changed, 1354 insertions(+)
>  create mode 100644 drivers/infiniband/sw/siw/siw_qp.c
>
> diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c
> new file mode 100644
> index 000000000000..9c94a406288c
> --- /dev/null
> +++ b/drivers/infiniband/sw/siw/siw_qp.c
> @@ -0,0 +1,1354 @@

...

> +int siw_qp_modify(struct siw_qp *qp, struct siw_qp_attrs *attrs,
> +		  enum siw_qp_attr_mask mask)
> +{
> +	int drop_conn = 0, rv = 0;
> +
> +	if (!mask)
> +		return 0;
> +
> +	siw_dbg_qp(qp, "state: %s => %s\n",
> +		   siw_qp_state_to_string[qp->attrs.state],
> +		   siw_qp_state_to_string[attrs->state]);
> +
> +	if (mask != SIW_QP_ATTR_STATE)
> +		siw_qp_modify_nonstate(qp, attrs, mask);
> +
> +	if (!(mask & SIW_QP_ATTR_STATE))
> +		return 0;
> +
> +	switch (qp->attrs.state) {
> +	case SIW_QP_STATE_IDLE:
> +	case SIW_QP_STATE_RTR:
> +		switch (attrs->state) {
> +		case SIW_QP_STATE_RTS:
> +
> +			if (attrs->flags & SIW_MPA_CRC) {
> +				rv = siw_qp_enable_crc(qp);
> +				if (rv)
> +					break;
> +			}
> +			if (!(mask & SIW_QP_ATTR_LLP_HANDLE)) {
> +				siw_dbg_qp(qp, "no socket\n");
> +				rv = -EINVAL;
> +				break;
> +			}
> +			if (!(mask & SIW_QP_ATTR_MPA)) {
> +				siw_dbg_qp(qp, "no MPA\n");
> +				rv = -EINVAL;
> +				break;
> +			}
> +			siw_dbg_qp(qp, "enter rts, peer 0x%08x, loc 0x%08x\n",
> +				   qp->cep->llp.raddr.sin_addr.s_addr,
> +				   qp->cep->llp.laddr.sin_addr.s_addr);
> +			/*
> +			 * Initialize iWARP TX state
> +			 */
> +			qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_SEND] = 0;
> +			qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ] = 0;
> +			qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_TERMINATE] = 0;
> +
> +			/*
> +			 * Initialize iWARP RX state
> +			 */
> +			qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_SEND] = 1;
> +			qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ] = 1;
> +			qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_TERMINATE] = 1;
> +
> +			/*
> +			 * init IRD free queue, caller has already checked
> +			 * limits.
> +			 */
> +			rv = siw_qp_readq_init(qp, attrs->irq_size,
> +					       attrs->orq_size);
> +			if (rv)
> +				break;
> +
> +			qp->attrs.sk = attrs->sk;
> +			qp->attrs.state = SIW_QP_STATE_RTS;
> +			break;
> +
> +		case SIW_QP_STATE_ERROR:
> +			siw_rq_flush(qp);
> +			qp->attrs.state = SIW_QP_STATE_ERROR;
> +			if (qp->cep) {
> +				siw_cep_put(qp->cep);
> +				qp->cep = NULL;
> +			}
> +			break;
> +
> +		case SIW_QP_STATE_RTR:
> +			/* ignore */
> +			break;
> +
> +		default:
> +			siw_dbg_qp(qp, "state transition undefined: %s => %s\n",
> +				   siw_qp_state_to_string[qp->attrs.state],
> +				   siw_qp_state_to_string[attrs->state]);
> +			break;
> +		}
> +		break;
> +
> +	case SIW_QP_STATE_RTS:
> +		switch (attrs->state) {
> +		case SIW_QP_STATE_CLOSING:
> +			/*
> +			 * Verbs: move to IDLE if SQ and ORQ are empty.
> +			 * Move to ERROR otherwise. But first of all we must
> +			 * close the connection. So we keep CLOSING or ERROR
> +			 * as a transient state, schedule connection drop work
> +			 * and wait for the socket state change upcall to
> +			 * come back closed.
> +			 */
> +			if (tx_wqe(qp)->wr_status == SIW_WR_IDLE) {
> +				qp->attrs.state = SIW_QP_STATE_CLOSING;
> +			} else {
> +				qp->attrs.state = SIW_QP_STATE_ERROR;
> +				siw_sq_flush(qp);
> +			}
> +			siw_rq_flush(qp);
> +
> +			drop_conn = 1;
> +			break;
> +
> +		case SIW_QP_STATE_TERMINATE:
> +			qp->attrs.state = SIW_QP_STATE_TERMINATE;
> +
> +			siw_init_terminate(qp, TERM_ERROR_LAYER_RDMAP,
> +					   RDMAP_ETYPE_CATASTROPHIC,
> +					   RDMAP_ECODE_UNSPECIFIED, 1);
> +			drop_conn = 1;
> +			break;
> +
> +		case SIW_QP_STATE_ERROR:
> +			/*
> +			 * This is an emergency close.
> +			 *
> +			 * Any in progress transmit operation will get
> +			 * cancelled.
> +			 * This will likely result in a protocol failure,
> +			 * if a TX operation is in transit. The caller
> +			 * could unconditional wait to give the current
> +			 * operation a chance to complete.
> +			 * Esp., how to handle the non-empty IRQ case?
> +			 * The peer was asking for data transfer at a valid
> +			 * point in time.
> +			 */
> +			siw_sq_flush(qp);
> +			siw_rq_flush(qp);
> +			qp->attrs.state = SIW_QP_STATE_ERROR;
> +			drop_conn = 1;
> +			break;
> +
> +		default:
> +			siw_dbg_qp(qp, "state transition undefined: %s => %s\n",
> +				   siw_qp_state_to_string[qp->attrs.state],
> +				   siw_qp_state_to_string[attrs->state]);
> +			break;
> +		}
> +		break;
> +
> +	case SIW_QP_STATE_TERMINATE:
> +		switch (attrs->state) {
> +		case SIW_QP_STATE_ERROR:
> +			siw_rq_flush(qp);
> +			qp->attrs.state = SIW_QP_STATE_ERROR;
> +
> +			if (tx_wqe(qp)->wr_status != SIW_WR_IDLE)
> +				siw_sq_flush(qp);
> +			break;
> +
> +		default:
> +			siw_dbg_qp(qp, "state transition undefined: %s => %s\n",
> +				   siw_qp_state_to_string[qp->attrs.state],
> +				   siw_qp_state_to_string[attrs->state]);
> +		}
> +		break;
> +
> +	case SIW_QP_STATE_CLOSING:
> +		switch (attrs->state) {
> +		case SIW_QP_STATE_IDLE:
> +			WARN_ON(tx_wqe(qp)->wr_status != SIW_WR_IDLE);
> +			qp->attrs.state = SIW_QP_STATE_IDLE;
> +			break;
> +
> +		case SIW_QP_STATE_CLOSING:
> +			/*
> +			 * The LLP may already moved the QP to closing
> +			 * due to graceful peer close init
> +			 */
> +			break;
> +
> +		case SIW_QP_STATE_ERROR:
> +			/*
> +			 * QP was moved to CLOSING by LLP event
> +			 * not yet seen by user.
> +			 */
> +			qp->attrs.state = SIW_QP_STATE_ERROR;
> +
> +			if (tx_wqe(qp)->wr_status != SIW_WR_IDLE)
> +				siw_sq_flush(qp);
> +
> +			siw_rq_flush(qp);
> +			break;
> +
> +		default:
> +			siw_dbg_qp(qp, "state transition undefined: %s => %s\n",
> +				   siw_qp_state_to_string[qp->attrs.state],
> +				   siw_qp_state_to_string[attrs->state]);
> +
> +			return -ECONNABORTED;
> +		}
> +		break;
> +
> +	default:
> +		siw_dbg_qp(qp, " noop: state %s\n",
> +			   siw_qp_state_to_string[qp->attrs.state]);
> +		break;
> +	}
> +	if (drop_conn)
> +		siw_qp_cm_drop(qp, 0);

I wonder if it is just a bad name, but why modify QP should handle
connections?

Thanks



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux