Commit 76675f6f authored by JinYu's avatar JinYu Committed by Jim Harris
Browse files

rdma: check ibv state after rdma update it



We found ibv state value may be unreasonable, so before we
use the state value we do some judgement. The unreasonable
state probably means hardware issue, so the process flow
become unpredicatable.
Fix GitHub issue #508.

Change-Id: I213f4d684b103cce7bc072aecd591e2c491e0596
Signed-off-by: default avatarJinYu <jin.yu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/436920


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarZiye Yang <optimistyzy@gmail.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent fa757dc9
Loading
Loading
Loading
Loading
+35 −12
Original line number Diff line number Diff line
@@ -408,6 +408,23 @@ spdk_nvmf_rdma_qpair_dec_refcnt(struct spdk_nvmf_rdma_qpair *rqpair)
	return new_refcnt;
}

static inline int
spdk_nvmf_rdma_check_ibv_state(enum ibv_qp_state state)
{
	switch (state) {
	case IBV_QPS_RESET:
	case IBV_QPS_INIT:
	case IBV_QPS_RTR:
	case IBV_QPS_RTS:
	case IBV_QPS_SQD:
	case IBV_QPS_SQE:
	case IBV_QPS_ERR:
		return 0;
	default:
		return -1;
	}
}

static enum ibv_qp_state
spdk_nvmf_rdma_update_ibv_state(struct spdk_nvmf_rdma_qpair *rqpair) {
	enum ibv_qp_state old_state, new_state;
@@ -443,6 +460,18 @@ spdk_nvmf_rdma_update_ibv_state(struct spdk_nvmf_rdma_qpair *rqpair) {
	}

	new_state = rqpair->ibv_attr.qp_state;

	rc = spdk_nvmf_rdma_check_ibv_state(new_state);
	if (rc)
	{
		SPDK_ERRLOG("QP#%d: bad state updated: %u, maybe hardware issue\n", rqpair->qpair.qid, new_state);
		/*
		 * IBV_QPS_UNKNOWN undefined if lib version smaller than libibverbs-1.1.8
		 * IBV_QPS_UNKNOWN is the enum element after IBV_QPS_ERR
		 */
		return IBV_QPS_ERR + 1;
	}

	if (old_state != new_state)
	{
		spdk_trace_record(TRACE_RDMA_QP_STATE_CHANGE, 0, 0,
@@ -458,7 +487,8 @@ static const char *str_ibv_qp_state[] = {
	"IBV_QPS_RTS",
	"IBV_QPS_SQD",
	"IBV_QPS_SQE",
	"IBV_QPS_ERR"
	"IBV_QPS_ERR",
	"IBV_QPS_UNKNOWN"
};

static int
@@ -491,20 +521,13 @@ spdk_nvmf_rdma_set_ibv_state(struct spdk_nvmf_rdma_qpair *rqpair,
		[IBV_QPS_ERR] = IBV_QP_STATE,
	};

	switch (new_state) {
	case IBV_QPS_RESET:
	case IBV_QPS_INIT:
	case IBV_QPS_RTR:
	case IBV_QPS_RTS:
	case IBV_QPS_SQD:
	case IBV_QPS_SQE:
	case IBV_QPS_ERR:
		break;
	default:
	rc = spdk_nvmf_rdma_check_ibv_state(new_state);
	if (rc) {
		SPDK_ERRLOG("QP#%d: bad state requested: %u\n",
			    rqpair->qpair.qid, new_state);
		return -1;
		return rc;
	}

	rqpair->ibv_attr.cur_qp_state = rqpair->ibv_attr.qp_state;
	rqpair->ibv_attr.qp_state = new_state;
	rqpair->ibv_attr.ah_attr.port_num = rqpair->ibv_attr.port_num;