svn commit: r309450 - in stable: 10/contrib/ofed/libcxgb4/src 10/sys/dev/cxgbe/iw_cxgbe 11/contrib/ofed/libcxgb4/src 11/sys/dev/cxgbe/iw_cxgbe

John Baldwin jhb at FreeBSD.org
Sat Dec 3 00:18:40 UTC 2016


Author: jhb
Date: Sat Dec  3 00:18:38 2016
New Revision: 309450
URL: https://svnweb.freebsd.org/changeset/base/309450

Log:
  MFC 304854: cxgbe/iw_cxgbe: Various fixes to the iWARP driver.
  
  - Return appropriate error code instead of ENOMEM when sosend() fails in
    send_mpa_req.
  - Fix for problematic race during destroy_qp.
  - Abortive close in the failure of send_mpa_reject() instead of normal close.
  - Remove the unnecessary doorbell flowcontrol logic.
  
  Sponsored by:	Chelsio Communications

Modified:
  stable/10/contrib/ofed/libcxgb4/src/qp.c
  stable/10/sys/dev/cxgbe/iw_cxgbe/cm.c
  stable/10/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
  stable/10/sys/dev/cxgbe/iw_cxgbe/qp.c
  stable/10/sys/dev/cxgbe/iw_cxgbe/t4.h
Directory Properties:
  stable/10/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/11/contrib/ofed/libcxgb4/src/qp.c
  stable/11/sys/dev/cxgbe/iw_cxgbe/cm.c
  stable/11/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
  stable/11/sys/dev/cxgbe/iw_cxgbe/qp.c
  stable/11/sys/dev/cxgbe/iw_cxgbe/t4.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/10/contrib/ofed/libcxgb4/src/qp.c
==============================================================================
--- stable/10/contrib/ofed/libcxgb4/src/qp.c	Fri Dec  2 23:05:14 2016	(r309449)
+++ stable/10/contrib/ofed/libcxgb4/src/qp.c	Sat Dec  3 00:18:38 2016	(r309450)
@@ -392,11 +392,9 @@ int c4iw_post_send(struct ibv_qp *ibqp, 
 		t4_sq_produce(&qhp->wq, len16);
 		idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
 	}
-	if (t4_wq_db_enabled(&qhp->wq)) {
-		t4_ring_sq_db(&qhp->wq, idx, dev_is_t5(qhp->rhp),
-			      len16, wqe);
-	} else
-		ring_kernel_db(qhp, qhp->wq.sq.qid, idx);
+
+	t4_ring_sq_db(&qhp->wq, idx, dev_is_t5(qhp->rhp),
+			len16, wqe);
 	qhp->wq.sq.queue[qhp->wq.sq.size].status.host_wq_pidx = \
 			(qhp->wq.sq.wq_pidx);
 	pthread_spin_unlock(&qhp->lock);
@@ -458,11 +456,9 @@ int c4iw_post_receive(struct ibv_qp *ibq
 		wr = wr->next;
 		num_wrs--;
 	}
-	if (t4_wq_db_enabled(&qhp->wq))
-		t4_ring_rq_db(&qhp->wq, idx, dev_is_t5(qhp->rhp),
-			      len16, wqe);
-	else
-		ring_kernel_db(qhp, qhp->wq.rq.qid, idx);
+
+	t4_ring_rq_db(&qhp->wq, idx, dev_is_t5(qhp->rhp),
+			len16, wqe);
 	qhp->wq.rq.queue[qhp->wq.rq.size].status.host_wq_pidx = \
 			(qhp->wq.rq.wq_pidx);
 	pthread_spin_unlock(&qhp->lock);

Modified: stable/10/sys/dev/cxgbe/iw_cxgbe/cm.c
==============================================================================
--- stable/10/sys/dev/cxgbe/iw_cxgbe/cm.c	Fri Dec  2 23:05:14 2016	(r309449)
+++ stable/10/sys/dev/cxgbe/iw_cxgbe/cm.c	Sat Dec  3 00:18:38 2016	(r309450)
@@ -81,6 +81,8 @@ static void process_req(struct work_stru
 static void start_ep_timer(struct c4iw_ep *ep);
 static int stop_ep_timer(struct c4iw_ep *ep);
 static int set_tcpinfo(struct c4iw_ep *ep);
+static void process_timeout(struct c4iw_ep *ep);
+static void process_timedout_eps(void);
 static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc);
 static void __state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state tostate);
 static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state tostate);
@@ -91,7 +93,7 @@ static struct rtentry * find_route(__be3
 static int close_socket(struct c4iw_ep_common *epc, int close);
 static int shutdown_socket(struct c4iw_ep_common *epc);
 static void abort_socket(struct c4iw_ep *ep);
-static void send_mpa_req(struct c4iw_ep *ep);
+static int send_mpa_req(struct c4iw_ep *ep);
 static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen);
 static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen);
 static void close_complete_upcall(struct c4iw_ep *ep, int status);
@@ -174,20 +176,91 @@ static void ref_qp(struct c4iw_ep *ep)
 	c4iw_qp_add_ref(&ep->com.qp->ibqp);
 }
 
+static void process_timeout(struct c4iw_ep *ep)
+{
+	struct c4iw_qp_attributes attrs;
+	int abort = 1;
+
+	mutex_lock(&ep->com.mutex);
+	CTR4(KTR_IW_CXGBE, "%s ep :%p, tid:%u, state %d", __func__,
+			ep, ep->hwtid, ep->com.state);
+	set_bit(TIMEDOUT, &ep->com.history);
+	switch (ep->com.state) {
+	case MPA_REQ_SENT:
+		connect_reply_upcall(ep, -ETIMEDOUT);
+		break;
+	case MPA_REQ_WAIT:
+	case MPA_REQ_RCVD:
+	case MPA_REP_SENT:
+	case FPDU_MODE:
+		break;
+	case CLOSING:
+	case MORIBUND:
+		if (ep->com.cm_id && ep->com.qp) {
+			attrs.next_state = C4IW_QP_STATE_ERROR;
+			c4iw_modify_qp(ep->com.dev, ep->com.qp,
+					C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
+		}
+		close_complete_upcall(ep, -ETIMEDOUT);
+		break;
+	case ABORTING:
+	case DEAD:
+		/*
+		 * These states are expected if the ep timed out at the same
+		 * time as another thread was calling stop_ep_timer().
+		 * So we silently do nothing for these states.
+		 */
+		abort = 0;
+		break;
+	default:
+		CTR4(KTR_IW_CXGBE, "%s unexpected state ep %p tid %u state %u\n"
+				, __func__, ep, ep->hwtid, ep->com.state);
+		abort = 0;
+	}
+	mutex_unlock(&ep->com.mutex);
+	if (abort)
+		c4iw_ep_disconnect(ep, 1, GFP_KERNEL);
+	c4iw_put_ep(&ep->com);
+	return;
+}
+
+static void process_timedout_eps(void)
+{
+	struct c4iw_ep *ep;
+
+	spin_lock(&timeout_lock);
+	while (!list_empty(&timeout_list)) {
+		struct list_head *tmp;
+		tmp = timeout_list.next;
+		list_del(tmp);
+		tmp->next = tmp->prev = NULL;
+		spin_unlock(&timeout_lock);
+		ep = list_entry(tmp, struct c4iw_ep, entry);
+		process_timeout(ep);
+		spin_lock(&timeout_lock);
+	}
+	spin_unlock(&timeout_lock);
+	return;
+}
+
 static void
 process_req(struct work_struct *ctx)
 {
 	struct c4iw_ep_common *epc;
 
+	process_timedout_eps();
 	spin_lock(&req_lock);
 	while (!TAILQ_EMPTY(&req_list)) {
 		epc = TAILQ_FIRST(&req_list);
 		TAILQ_REMOVE(&req_list, epc, entry);
 		epc->entry.tqe_prev = NULL;
 		spin_unlock(&req_lock);
+		CTR3(KTR_IW_CXGBE, "%s so :%p, ep:%p", __func__,
+				epc->so, epc);
 		if (epc->so)
 			process_socket_event((struct c4iw_ep *)epc);
 		c4iw_put_ep(epc);
+		process_timedout_eps();
 		spin_lock(&req_lock);
 	}
 	spin_unlock(&req_lock);
@@ -252,8 +325,17 @@ close_socket(struct c4iw_ep_common *epc,
 	struct socket *so = epc->so;
 	int rc;
 
-	CTR4(KTR_IW_CXGBE, "%s: so %p, ep %p, state %s", __func__, epc, so,
-	    states[epc->state]);
+	CTR5(KTR_IW_CXGBE, "%s:csoB so %p, ep %p, state %s, tid %d", __func__,
+			so, epc, states[epc->state],
+			((struct c4iw_ep *)epc)->hwtid);
+	mutex_lock(&epc->so_mutex);
+	if ((so == NULL) || (so->so_count == 0)) {
+		mutex_unlock(&epc->so_mutex);
+		CTR5(KTR_IW_CXGBE, "%s:cso1 so %p, ep %p, state %s, tid %d",
+				__func__, so, epc, states[epc->state],
+				((struct c4iw_ep *)epc)->hwtid);
+		return -EINVAL;
+	}
 
 	SOCK_LOCK(so);
 	soupcall_clear(so, SO_RCV);
@@ -265,6 +347,7 @@ close_socket(struct c4iw_ep_common *epc,
                 rc = soshutdown(so, SHUT_WR | SHUT_RD);
 	epc->so = NULL;
 
+	mutex_unlock(&epc->so_mutex);
 	return (rc);
 }
 
@@ -272,10 +355,23 @@ static int
 shutdown_socket(struct c4iw_ep_common *epc)
 {
 
-	CTR4(KTR_IW_CXGBE, "%s: so %p, ep %p, state %s", __func__, epc->so, epc,
-	    states[epc->state]);
+	struct socket *so = epc->so;
+	int rc;
 
-	return (soshutdown(epc->so, SHUT_WR));
+	CTR5(KTR_IW_CXGBE, "%s:ssoB so %p, ep %p, state %s, tid %d", __func__,
+			epc->so, epc, states[epc->state],
+			((struct c4iw_ep *)epc)->hwtid);
+	mutex_lock(&epc->so_mutex);
+	if ((so == NULL) || (so->so_count == 0)) {
+		mutex_unlock(&epc->so_mutex);
+		CTR5(KTR_IW_CXGBE, "%s:sso1 so %p, ep %p, state %s, tid %d",
+			__func__, epc->so, epc, states[epc->state],
+			((struct c4iw_ep *)epc)->hwtid);
+		return -EINVAL;
+	}
+	rc = soshutdown(so, SHUT_WR);
+	mutex_unlock(&epc->so_mutex);
+	return rc;
 }
 
 static void
@@ -285,9 +381,9 @@ abort_socket(struct c4iw_ep *ep)
 	int rc;
 	struct linger l;
 
-	CTR4(KTR_IW_CXGBE, "%s ep %p so %p state %s", __func__, ep, ep->com.so,
-	    states[ep->com.state]);
-
+	CTR5(KTR_IW_CXGBE, "%s ep %p so %p state %s tid %d", __func__, ep,
+			ep->com.so, states[ep->com.state], ep->hwtid);
+	mutex_lock(&ep->com.so_mutex);
 	l.l_onoff = 1;
 	l.l_linger = 0;
 
@@ -303,6 +399,7 @@ abort_socket(struct c4iw_ep *ep)
 		log(LOG_ERR, "%s: can't set linger to 0, no RST! err %d\n",
 		    __func__, rc);
 	}
+	mutex_unlock(&ep->com.so_mutex);
 }
 
 static void
@@ -431,7 +528,8 @@ process_conn_error(struct c4iw_ep *ep)
 	int ret;
 	int state;
 
-	state = state_read(&ep->com);
+	mutex_lock(&ep->com.mutex);
+	state = ep->com.state;
 	CTR5(KTR_IW_CXGBE, "%s:pceB ep %p so %p so->so_error %u state %s",
 	    __func__, ep, ep->com.so, ep->com.so->so_error,
 	    states[ep->com.state]);
@@ -488,6 +586,7 @@ process_conn_error(struct c4iw_ep *ep)
 		case DEAD:
 			CTR2(KTR_IW_CXGBE, "%s so_error %d IN DEAD STATE!!!!",
 			    __func__, ep->com.so->so_error);
+			mutex_unlock(&ep->com.mutex);
 			return;
 
 		default:
@@ -496,12 +595,18 @@ process_conn_error(struct c4iw_ep *ep)
 	}
 
 	if (state != ABORTING) {
+		if (ep->parent_ep) {
+			CTR2(KTR_IW_CXGBE, "%s:pce1 %p", __func__, ep);
+			close_socket(&ep->com, 1);
+		} else {
+			CTR2(KTR_IW_CXGBE, "%s:pce2 %p", __func__, ep);
+			close_socket(&ep->com, 0);
+		}
 
-		CTR2(KTR_IW_CXGBE, "%s:pce1 %p", __func__, ep);
-		close_socket(&ep->com, 0);
-		state_set(&ep->com, DEAD);
+		__state_set(&ep->com, DEAD);
 		c4iw_put_ep(&ep->com);
 	}
+	mutex_unlock(&ep->com.mutex);
 	CTR2(KTR_IW_CXGBE, "%s:pceE %p", __func__, ep);
 	return;
 }
@@ -563,16 +668,19 @@ process_close_complete(struct c4iw_ep *e
 			break;
 
 		case DEAD:
-		default:
 			CTR2(KTR_IW_CXGBE, "%s:pcc6 %p DEAD", __func__, ep);
-			panic("%s:pcc6 %p DEAD", __func__, ep);
+			break;
+		default:
+			CTR2(KTR_IW_CXGBE, "%s:pcc7 %p unknown ep state",
+					__func__, ep);
+			panic("%s:pcc6 %p unknown ep state", __func__, ep);
 			break;
 	}
 	mutex_unlock(&ep->com.mutex);
 
 	if (release) {
 
-		CTR2(KTR_IW_CXGBE, "%s:pcc7 %p", __func__, ep);
+		CTR2(KTR_IW_CXGBE, "%s:pcc8 %p", __func__, ep);
 		c4iw_put_ep(&ep->com);
 	}
 	CTR2(KTR_IW_CXGBE, "%s:pccE %p", __func__, ep);
@@ -587,6 +695,14 @@ init_sock(struct c4iw_ep_common *epc)
 	struct socket *so = epc->so;
 	int on = 1;
 
+	mutex_lock(&epc->so_mutex);
+	if ((so == NULL) || (so->so_count == 0)) {
+		mutex_unlock(&epc->so_mutex);
+		CTR5(KTR_IW_CXGBE, "%s:iso1 so %p, ep %p, state %s, tid %d",
+			__func__, so, epc, states[epc->state],
+			((struct c4iw_ep *)epc)->hwtid);
+		return;
+	}
 	SOCK_LOCK(so);
 	soupcall_set(so, SO_RCV, c4iw_so_upcall, epc);
 	so->so_state |= SS_NBIO;
@@ -602,6 +718,7 @@ init_sock(struct c4iw_ep_common *epc)
 		log(LOG_ERR, "%s: can't set TCP_NODELAY on so %p (%d)\n",
 		    __func__, so, rc);
 	}
+	mutex_unlock(&epc->so_mutex);
 }
 
 static void
@@ -643,14 +760,20 @@ static void
 process_connected(struct c4iw_ep *ep)
 {
 
-	if ((ep->com.so->so_state & SS_ISCONNECTED) && !ep->com.so->so_error)
-		send_mpa_req(ep);
+	if ((ep->com.so->so_state & SS_ISCONNECTED) && !ep->com.so->so_error) {
+		if (send_mpa_req(ep))
+			goto err;
+	}
 	else {
 		connect_reply_upcall(ep, -ep->com.so->so_error);
-		close_socket(&ep->com, 0);
-		state_set(&ep->com, DEAD);
-		c4iw_put_ep(&ep->com);
+		goto err;
 	}
+	return;
+err:
+	close_socket(&ep->com, 0);
+	state_set(&ep->com, DEAD);
+	c4iw_put_ep(&ep->com);
+	return;
 }
 
 void
@@ -660,6 +783,7 @@ process_newconn(struct iw_cm_id *parent_
 	struct sockaddr_in *local;
 	struct sockaddr_in *remote;
 	struct c4iw_ep *parent_ep = parent_cm_id->provider_data;
+	int ret = 0;
 
 	if (!child_so) {
 		CTR4(KTR_IW_CXGBE,
@@ -703,7 +827,14 @@ process_newconn(struct iw_cm_id *parent_
 	START_EP_TIMER(child_ep);
 
 	/* maybe the request has already been queued up on the socket... */
-	process_mpa_request(child_ep);
+	ret = process_mpa_request(child_ep);
+	if (ret == 2)
+		/* ABORT */
+		c4iw_ep_disconnect(child_ep, 1, GFP_KERNEL);
+	else if (ret == 1)
+		/* CLOSE */
+		c4iw_ep_disconnect(child_ep, 0, GFP_KERNEL);
+
 	return;
 }
 
@@ -762,7 +893,12 @@ process_socket_event(struct c4iw_ep *ep)
 	/* peer close */
 	if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && state <= CLOSING) {
 		process_peer_close(ep);
-		return;
+		/*
+		 * check whether socket disconnect event is pending before
+		 * returning. Fallthrough if yes.
+		 */
+		if (!(so->so_state & SS_ISDISCONNECTED))
+			return;
 	}
 
 	/* close complete */
@@ -777,11 +913,6 @@ process_socket_event(struct c4iw_ep *ep)
 
 SYSCTL_NODE(_hw, OID_AUTO, iw_cxgbe, CTLFLAG_RD, 0, "iw_cxgbe driver parameters");
 
-int db_delay_usecs = 1;
-TUNABLE_INT("hw.iw_cxgbe.db_delay_usecs", &db_delay_usecs);
-SYSCTL_INT(_hw_iw_cxgbe, OID_AUTO, db_delay_usecs, CTLFLAG_RW, &db_delay_usecs, 0,
-		"Usecs to delay awaiting db fifo to drain");
-
 static int dack_mode = 0;
 TUNABLE_INT("hw.iw_cxgbe.dack_mode", &dack_mode);
 SYSCTL_INT(_hw_iw_cxgbe, OID_AUTO, dack_mode, CTLFLAG_RW, &dack_mode, 0,
@@ -852,11 +983,6 @@ TUNABLE_INT("hw.iw_cxgbe.snd_win", &snd_
 SYSCTL_INT(_hw_iw_cxgbe, OID_AUTO, snd_win, CTLFLAG_RW, &snd_win, 0,
 		"TCP send window in bytes (default = 128KB)");
 
-int db_fc_threshold = 2000;
-TUNABLE_INT("hw.iw_cxgbe.db_fc_threshold", &db_fc_threshold);
-SYSCTL_INT(_hw_iw_cxgbe, OID_AUTO, db_fc_threshold, CTLFLAG_RW, &db_fc_threshold, 0,
-		"QP count/threshold that triggers automatic");
-
 static void
 start_ep_timer(struct c4iw_ep *ep)
 {
@@ -926,6 +1052,7 @@ alloc_ep(int size, gfp_t gfp)
 
 	kref_init(&epc->kref);
 	mutex_init(&epc->mutex);
+	mutex_init(&epc->so_mutex);
 	c4iw_init_wr_wait(&epc->wr_wait);
 
 	return (epc);
@@ -963,7 +1090,7 @@ static void release_ep_resources(struct 
 	CTR2(KTR_IW_CXGBE, "%s:rerE %p", __func__, ep);
 }
 
-static void
+static int
 send_mpa_req(struct c4iw_ep *ep)
 {
 	int mpalen;
@@ -971,7 +1098,7 @@ send_mpa_req(struct c4iw_ep *ep)
 	struct mpa_v2_conn_params mpa_v2_params;
 	struct mbuf *m;
 	char mpa_rev_to_use = mpa_rev;
-	int err;
+	int err = 0;
 
 	if (ep->retry_with_mpa_v1)
 		mpa_rev_to_use = 1;
@@ -981,9 +1108,10 @@ send_mpa_req(struct c4iw_ep *ep)
 
 	mpa = malloc(mpalen, M_CXGBE, M_NOWAIT);
 	if (mpa == NULL) {
-failed:
-		connect_reply_upcall(ep, -ENOMEM);
-		return;
+		err = -ENOMEM;
+		CTR3(KTR_IW_CXGBE, "%s:smr1 ep: %p , error: %d",
+				__func__, ep, err);
+		goto err;
 	}
 
 	memset(mpa, 0, mpalen);
@@ -1035,20 +1163,32 @@ failed:
 
 	m = m_getm(NULL, mpalen, M_NOWAIT, MT_DATA);
 	if (m == NULL) {
+		err = -ENOMEM;
+		CTR3(KTR_IW_CXGBE, "%s:smr2 ep: %p , error: %d",
+				__func__, ep, err);
 		free(mpa, M_CXGBE);
-		goto failed;
+		goto err;
 	}
 	m_copyback(m, 0, mpalen, (void *)mpa);
 	free(mpa, M_CXGBE);
 
-	err = sosend(ep->com.so, NULL, NULL, m, NULL, MSG_DONTWAIT,
-	    ep->com.thread);
-	if (err)
-		goto failed;
+	err = -sosend(ep->com.so, NULL, NULL, m, NULL, MSG_DONTWAIT,
+			ep->com.thread);
+	if (err) {
+		CTR3(KTR_IW_CXGBE, "%s:smr3 ep: %p , error: %d",
+				__func__, ep, err);
+		goto err;
+	}
 
 	START_EP_TIMER(ep);
 	state_set(&ep->com, MPA_REQ_SENT);
 	ep->mpa_attr.initiator = 1;
+	CTR3(KTR_IW_CXGBE, "%s:smrE %p, error: %d", __func__, ep, err);
+	return 0;
+err:
+	connect_reply_upcall(ep, err);
+	CTR3(KTR_IW_CXGBE, "%s:smrE %p, error: %d", __func__, ep, err);
+	return err;
 }
 
 static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen)
@@ -1299,10 +1439,11 @@ static void connect_reply_upcall(struct 
 {
 	struct iw_cm_event event;
 
-	CTR3(KTR_IW_CXGBE, "%s:cruB %p", __func__, ep, status);
+	CTR3(KTR_IW_CXGBE, "%s:cruB %p, status: %d", __func__, ep, status);
 	memset(&event, 0, sizeof(event));
 	event.event = IW_CM_EVENT_CONNECT_REPLY;
-	event.status = (status ==-ECONNABORTED)?-ECONNRESET: status;
+	event.status = ((status == -ECONNABORTED) || (status == -EPIPE)) ?
+					-ECONNRESET : status;
 	event.local_addr = ep->com.local_addr;
 	event.remote_addr = ep->com.remote_addr;
 
@@ -1652,6 +1793,7 @@ static int process_mpa_reply(struct c4iw
 
 		CTR2(KTR_IW_CXGBE, "%s:pmrl %p", __func__, ep);
 		printf("%s set_tcpinfo error\n", __func__);
+		err = -ECONNRESET;
 		goto err;
 	}
 
@@ -1917,32 +2059,31 @@ int c4iw_reject_cr(struct iw_cm_id *cm_i
 	int err;
 	struct c4iw_ep *ep = to_ep(cm_id);
 	CTR2(KTR_IW_CXGBE, "%s:crcB %p", __func__, ep);
-	int disconnect = 0;
+	int abort = 0;
 
-	if (state_read(&ep->com) == DEAD) {
+	if ((state_read(&ep->com) == DEAD) ||
+			(state_read(&ep->com) != MPA_REQ_RCVD)) {
 
 		CTR2(KTR_IW_CXGBE, "%s:crc1 %p", __func__, ep);
 		c4iw_put_ep(&ep->com);
 		return -ECONNRESET;
 	}
 	set_bit(ULP_REJECT, &ep->com.history);
-	BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);
 
 	if (mpa_rev == 0) {
 
 		CTR2(KTR_IW_CXGBE, "%s:crc2 %p", __func__, ep);
-		disconnect = 2;
+		abort = 1;
 	}
 	else {
 
 		CTR2(KTR_IW_CXGBE, "%s:crc3 %p", __func__, ep);
-		err = send_mpa_reject(ep, pdata, pdata_len);
-		err = soshutdown(ep->com.so, 3);
+		abort = send_mpa_reject(ep, pdata, pdata_len);
 	}
+	stop_ep_timer(ep);
+	err = c4iw_ep_disconnect(ep, abort != 0, GFP_KERNEL);
 	c4iw_put_ep(&ep->com);
-	if (disconnect)
-		err = c4iw_ep_disconnect(ep, disconnect == 2, GFP_KERNEL);
-	CTR2(KTR_IW_CXGBE, "%s:crc4 %p", __func__, ep);
+	CTR3(KTR_IW_CXGBE, "%s:crc4 %p, err: %d", __func__, ep, err);
 	return 0;
 }
 

Modified: stable/10/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
==============================================================================
--- stable/10/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h	Fri Dec  2 23:05:14 2016	(r309449)
+++ stable/10/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h	Sat Dec  3 00:18:38 2016	(r309450)
@@ -131,10 +131,6 @@ struct c4iw_stats {
 	struct c4iw_stat stag;
 	struct c4iw_stat pbl;
 	struct c4iw_stat rqt;
-	u64  db_full;
-	u64  db_empty;
-	u64  db_drop;
-	u64  db_state_transitions;
 };
 
 struct c4iw_rdev {
@@ -207,12 +203,6 @@ c4iw_wait_for_reply(struct c4iw_rdev *rd
 	return (wr_waitp->ret);
 }
 
-enum db_state {
-	NORMAL = 0,
-	FLOW_CONTROL = 1,
-	RECOVERY = 2
-};
-
 struct c4iw_dev {
 	struct ib_device ibdev;
 	struct c4iw_rdev rdev;
@@ -222,8 +212,6 @@ struct c4iw_dev {
 	struct idr mmidr;
 	spinlock_t lock;
 	struct dentry *debugfs_root;
-	enum db_state db_state;
-	int qpcnt;
 };
 
 static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
@@ -766,6 +754,7 @@ struct c4iw_ep_common {
         int rpl_done;
         struct thread *thread;
         struct socket *so;
+	struct mutex so_mutex;
 };
 
 struct c4iw_listen_ep {

Modified: stable/10/sys/dev/cxgbe/iw_cxgbe/qp.c
==============================================================================
--- stable/10/sys/dev/cxgbe/iw_cxgbe/qp.c	Fri Dec  2 23:05:14 2016	(r309449)
+++ stable/10/sys/dev/cxgbe/iw_cxgbe/qp.c	Sat Dec  3 00:18:38 2016	(r309450)
@@ -63,8 +63,6 @@ struct rss_header;
 #include "iw_cxgbe.h"
 #include "user.h"
 
-extern int db_delay_usecs;
-extern int db_fc_threshold;
 static void creds(struct toepcb *toep, size_t wrsize);
 
 
@@ -688,8 +686,8 @@ int c4iw_post_send(struct ib_qp *ibqp, s
 		t4_sq_produce(&qhp->wq, len16);
 		idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
 	}
-	if (t4_wq_db_enabled(&qhp->wq))
-		t4_ring_sq_db(&qhp->wq, idx);
+
+	t4_ring_sq_db(&qhp->wq, idx);
 	spin_unlock_irqrestore(&qhp->lock, flag);
 	return err;
 }
@@ -750,8 +748,8 @@ int c4iw_post_receive(struct ib_qp *ibqp
 		wr = wr->next;
 		num_wrs--;
 	}
-	if (t4_wq_db_enabled(&qhp->wq))
-		t4_ring_rq_db(&qhp->wq, idx);
+
+	t4_ring_rq_db(&qhp->wq, idx);
 	spin_unlock_irqrestore(&qhp->lock, flag);
 	return err;
 }
@@ -1391,14 +1389,6 @@ out:
 	return ret;
 }
 
-static int enable_qp_db(int id, void *p, void *data)
-{
-	struct c4iw_qp *qp = p;
-
-	t4_enable_wq_db(&qp->wq);
-	return 0;
-}
-
 int c4iw_destroy_qp(struct ib_qp *ib_qp)
 {
 	struct c4iw_dev *rhp;
@@ -1419,13 +1409,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
 
 	spin_lock_irq(&rhp->lock);
 	remove_handle_nolock(rhp, &rhp->qpidr, qhp->wq.sq.qid);
-	rhp->qpcnt--;
-	BUG_ON(rhp->qpcnt < 0);
-	if (rhp->qpcnt <= db_fc_threshold && rhp->db_state == FLOW_CONTROL) {
-		rhp->rdev.stats.db_state_transitions++;
-		rhp->db_state = NORMAL;
-		idr_for_each(&rhp->qpidr, enable_qp_db, NULL);
-	}
 	spin_unlock_irq(&rhp->lock);
 	atomic_dec(&qhp->refcnt);
 	wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
@@ -1441,14 +1424,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
 	return 0;
 }
 
-static int disable_qp_db(int id, void *p, void *data)
-{
-	struct c4iw_qp *qp = p;
-
-	t4_disable_wq_db(&qp->wq);
-	return 0;
-}
-
 struct ib_qp *
 c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
     struct ib_udata *udata)
@@ -1538,13 +1513,6 @@ c4iw_create_qp(struct ib_pd *pd, struct 
 	atomic_set(&qhp->refcnt, 1);
 
 	spin_lock_irq(&rhp->lock);
-	if (rhp->db_state != NORMAL)
-		t4_disable_wq_db(&qhp->wq);
-	if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) {
-		rhp->rdev.stats.db_state_transitions++;
-		rhp->db_state = FLOW_CONTROL;
-		idr_for_each(&rhp->qpidr, disable_qp_db, NULL);
-	}
 	ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
 	spin_unlock_irq(&rhp->lock);
 	if (ret)
@@ -1678,15 +1646,6 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp
 			 C4IW_QP_ATTR_ENABLE_RDMA_WRITE |
 			 C4IW_QP_ATTR_ENABLE_RDMA_BIND) : 0;
 
-	/*
-	 * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for
-	 * ringing the queue db when we're in DB_FULL mode.
-	 */
-	attrs.sq_db_inc = attr->sq_psn;
-	attrs.rq_db_inc = attr->rq_psn;
-	mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0;
-	mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0;
-
 	return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0);
 }
 

Modified: stable/10/sys/dev/cxgbe/iw_cxgbe/t4.h
==============================================================================
--- stable/10/sys/dev/cxgbe/iw_cxgbe/t4.h	Fri Dec  2 23:05:14 2016	(r309449)
+++ stable/10/sys/dev/cxgbe/iw_cxgbe/t4.h	Sat Dec  3 00:18:38 2016	(r309450)
@@ -453,21 +453,6 @@ static inline void t4_set_wq_in_error(st
 	wq->rq.queue[wq->rq.size].status.qp_err = 1;
 }
 
-static inline void t4_disable_wq_db(struct t4_wq *wq)
-{
-	wq->rq.queue[wq->rq.size].status.db_off = 1;
-}
-
-static inline void t4_enable_wq_db(struct t4_wq *wq)
-{
-	wq->rq.queue[wq->rq.size].status.db_off = 0;
-}
-
-static inline int t4_wq_db_enabled(struct t4_wq *wq)
-{
-	return !wq->rq.queue[wq->rq.size].status.db_off;
-}
-
 struct t4_cq {
 	struct t4_cqe *queue;
 	bus_addr_t dma_addr;


More information about the svn-src-all mailing list