PERFORCE change 130462 for review

Kip Macy kmacy at FreeBSD.org
Fri Dec 7 21:23:58 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=130462

Change 130462 by kmacy at kmacy:storage:toestack on 2007/12/08 05:23:03

	various locking fixes
	handle abort in SYN_RCVD state

Affected files ...

.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#29 edit

Differences ...

==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#29 (text+ko) ====

@@ -488,9 +488,11 @@
 	toep->tp_copied_seq += read;
 	toep->tp_enqueued_bytes -= read;
 	credits = toep->tp_copied_seq - toep->tp_rcv_wup;
-	DPRINTF("copied_seq=%u rcv_wup=%u credits=%u\n",
-	    toep->tp_copied_seq, toep->tp_rcv_wup, credits);
-	SOCKBUF_UNLOCK(&so->so_rcv);	
+	SOCKBUF_UNLOCK(&so->so_rcv);
+
+	if (credits > so->so_rcv.sb_mbmax)
+	    printf("copied_seq=%u rcv_wup=%u credits=%u\n",
+		toep->tp_copied_seq, toep->tp_rcv_wup, credits);
 	/*
 	 * XXX this won't accurately reflect credit return - we need
 	 * to look at the difference between the amount that has been 
@@ -534,7 +536,7 @@
 {
 	struct socket *so;
 	
-	printf("cxgb_toe_disconnect\n");
+	DPRINTF("cxgb_toe_disconnect\n");
 
 	so = tp->t_inpcb->inp_socket;
 	close_conn(so);
@@ -879,7 +881,7 @@
 		__skb_queue_purge(&tp->out_of_order_queue);
 #endif		
 	} else {                                          // we have TID
-		cxgb_remove_tid(cdev, (void *)so, tid);
+		cxgb_remove_tid(cdev, toep, tid);
 		toepcb_release(toep);
 	}
 #if 0
@@ -975,7 +977,10 @@
 	toep->tp_delack_mode = 0;
 	
 	toep->tp_mtu_idx = select_mss(td, tp, dst->rt_ifp->if_mtu);
-	
+	/*
+	 * XXX broken
+	 * 
+	 */
 	tp->rcv_wnd = select_rcv_wnd(so);
         toep->tp_ulp_mode = TOM_TUNABLE(dev, ddp) && !(so->so_options & SO_NO_DDP) &&
 		       tp->rcv_wnd >= MIN_DDP_RCV_WIN ? ULP_MODE_TCPDDP : 0;
@@ -1161,6 +1166,7 @@
  * check SOCK_DEAD or sk->sk_sock.  Or maybe generate the error here but don't
  * free the atid.  Hmm.
  */
+#ifdef notyet
 static void
 act_open_req_arp_failure(struct t3cdev *dev, struct mbuf *m)
 {
@@ -1178,7 +1184,7 @@
 	}
 	INP_UNLOCK(inp);
 }
-
+#endif
 /*
  * Send an active open request.
  */
@@ -1460,10 +1466,17 @@
 	SOCKBUF_LOCK(&so->so_rcv);
 	if (sb_notify(&so->so_rcv))
 		DPRINTF("rx_data so=%p flags=0x%x len=%d\n", so, so->so_rcv.sb_flags, m->m_pkthdr.len);
+
+	sbappend_locked(&so->so_rcv, m);
+	KASSERT(so->so_rcv.sb_cc < so->so_rcv.sb_mbmax,
+
+	    ("so=%p, data contents exceed mbmax, sb_cc=%d sb_mbmax=%d",
+		so, so->so_rcv.sb_cc, so->so_rcv.sb_mbmax));
 	
-	sbappendstream_locked(&so->so_rcv, m);
 	INP_UNLOCK(tp->t_inpcb);
-
+	DPRINTF("sb_cc=%d sb_mbcnt=%d\n",
+	    so->so_rcv.sb_cc, so->so_rcv.sb_mbcnt);
+	    
 	if (__predict_true((so->so_state & SS_NOFDREF) == 0))
 		sorwakeup_locked(so);
 	else
@@ -1725,7 +1738,7 @@
 	struct toepcb *toep = tp->t_toe;
 	int keep = 0, dead = (so->so_state & SS_NOFDREF);
 
-	printf("do_peer_fin state=%d dead=%d\n", tp->t_state, !!dead);
+	DPRINTF("do_peer_fin state=%d dead=%d\n", tp->t_state, !!dead);
 	
 #ifdef T3_TRACE
 	T3_TRACE0(TIDTB(sk),"do_peer_fin:");
@@ -1772,7 +1785,7 @@
 		 */
 		t3_release_offload_resources(so);
 		if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
-			tcp_close(tp);
+			tp = tcp_close(tp);
 		} else
 			enter_timewait(so);
 		break;
@@ -1782,10 +1795,11 @@
 		       TOE_DEV(so)->name, toep->tp_tid, tp->t_state);
 	}
 	INP_INFO_WUNLOCK(&tcbinfo);
-	INP_UNLOCK(tp->t_inpcb);					
+	if (tp)
+		INP_UNLOCK(tp->t_inpcb);					
 
 	if (!dead) {
-		printf("waking up waiters on %p rcv_notify=%d flags=0x%x\n", so, sb_notify(&so->so_rcv), so->so_rcv.sb_flags);
+		DPRINTF("waking up waiters on %p rcv_notify=%d flags=0x%x\n", so, sb_notify(&so->so_rcv), so->so_rcv.sb_flags);
 		
 		sorwakeup(so);
 		sowwakeup(so);
@@ -1825,19 +1839,18 @@
 process_close_con_rpl(struct socket *so, struct mbuf *m)
 {
 	struct tcpcb *tp = sototcpcb(so);
-	struct inpcb *inp = tp->t_inpcb;
 	struct cpl_close_con_rpl *rpl = cplhdr(m);
 	struct toepcb *toep = tp->t_toe;
 
 	tp->snd_una = ntohl(rpl->snd_nxt) - 1;  /* exclude FIN */
 
-	printf("process_close_con_rpl(%p) state=%d dead=%d\n", so, tp->t_state,
+	DPRINTF("process_close_con_rpl(%p) state=%d dead=%d\n", so, tp->t_state,
 	    !!(so->so_state & SS_NOFDREF));
 	if (!is_t3a(TOE_DEV(so)) && (toep->tp_flags & TP_ABORT_RPL_PENDING))
 		goto out;
 	
 	INP_INFO_WLOCK(&tcbinfo);
-	INP_LOCK(inp);
+	INP_LOCK(tp->t_inpcb);
 	switch (tp->t_state) {
 	case TCPS_CLOSING:              /* see FIN_WAIT2 case in do_peer_fin */
 		t3_release_offload_resources(so);
@@ -1884,7 +1897,7 @@
 	}
 	INP_INFO_WUNLOCK(&tcbinfo);
 	if (tp)
-		INP_UNLOCK(inp);
+		INP_UNLOCK(tp->t_inpcb);
 out:
 	m_free(m);
 }
@@ -1922,14 +1935,13 @@
 		  "process_abort_rpl: GTS rpl pending %d",
 		  sock_flag(sk, ABORT_RPL_PENDING));
 #endif
-	INP_LOCK_ASSERT(tp->t_inpcb);
+	INP_LOCK(tp->t_inpcb);
 	
 	if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
 		if (!(toep->tp_flags & TP_ABORT_RPL_RCVD) && !is_t3a(TOE_DEV(so)))
 			toep->tp_flags |= TP_ABORT_RPL_RCVD;
 		else {
 			toep->tp_flags &= ~(TP_ABORT_RPL_RCVD|TP_ABORT_RPL_PENDING);
-			
 			if (!(toep->tp_flags & TP_ABORT_REQ_RCVD) ||
 			    !is_t3a(TOE_DEV(so))) {
 				if (toep->tp_flags & TP_ABORT_REQ_RCVD)
@@ -1937,12 +1949,14 @@
 				INP_INFO_WLOCK(&tcbinfo);
 				INP_LOCK(tp->t_inpcb);
 				t3_release_offload_resources(so);
-				tcp_close(tp);
+				tp = tcp_close(tp);
 				INP_INFO_WUNLOCK(&tcbinfo);
-				INP_UNLOCK(tp->t_inpcb);
 			}
 		}
 	}
+	if (tp)
+		INP_UNLOCK(tp->t_inpcb);
+
 	m_free(m);
 }
 
@@ -1979,7 +1993,7 @@
 	 */
 	if (!toep)
 		goto discard;
-	
+
 	so = toeptoso(toep);
 	toepcb_hold(toep);
 	process_abort_rpl(so, m);
@@ -2024,6 +2038,8 @@
 
 	rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
 	rpl->wr.wr_lo = htonl(V_WR_TID(tid));
+	m->m_len = m->m_pkthdr.len = sizeof(*rpl);
+	
 	OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
 	rpl->cmd = cmd;
 }
@@ -2079,6 +2095,7 @@
 	cxgb_ofld_send(TOM_DATA(tdev)->cdev, reply_mbuf);
 }
 
+#ifdef notyet
 static void
 cleanup_syn_rcv_conn(struct socket *child, struct socket *parent)
 {
@@ -2093,6 +2110,7 @@
 #endif
 }
 
+
 /*
  * Performs the actual work to abort a SYN_RECV connection.
  */
@@ -2101,8 +2119,7 @@
 {
 	struct tcpcb *parenttp = sototcpcb(parent);
 	struct tcpcb *childtp = sototcpcb(child);
-	struct inpcb *inp = sotoinpcb(child);
-	
+
 	/*
 	 * If the server is still open we clean up the child connection,
 	 * otherwise the server already did the clean up as it was purging
@@ -2111,15 +2128,16 @@
 	if (__predict_false(parenttp->t_state == TCPS_LISTEN)) {
 		cleanup_syn_rcv_conn(child, parent);
 		INP_INFO_WLOCK(&tcbinfo);
-		INP_LOCK(inp);
+		INP_LOCK(childtp->t_inpcb);
 		t3_release_offload_resources(child);
-		tcp_close(childtp);
+		childtp = tcp_close(childtp);
 		INP_INFO_WUNLOCK(&tcbinfo);
-		INP_UNLOCK(inp);
+		if (childtp)
+			INP_UNLOCK(childtp->t_inpcb);
 	}
 }
+#endif
 
-
 /*
  * Handle abort requests for a SYN_RECV connection.  These need extra work
  * because the socket is on its parent's SYN queue.
@@ -2163,11 +2181,11 @@
 	struct tcpcb *tp = sototcpcb(so);
 	struct toepcb *toep = tp->t_toe;
 
-	INP_LOCK_ASSERT(tp->t_inpcb);
+	INP_LOCK(tp->t_inpcb);
 	if ((toep->tp_flags & TP_ABORT_REQ_RCVD) == 0) {
 		toep->tp_flags |= (TP_ABORT_REQ_RCVD|TP_ABORT_SHUTDOWN);
 		m_free(m);
-		return;
+		goto skip;
 	}
 
 	toep->tp_flags &= ~TP_ABORT_REQ_RCVD;
@@ -2193,15 +2211,18 @@
 		 * returns 0 is has taken care of the abort.
 		 */
 		if ((tp->t_state == TCPS_SYN_RECEIVED) && !abort_syn_rcv(so, m))
-			return;
+			goto skip;
 
-		INP_LOCK(tp->t_inpcb);
 		t3_release_offload_resources(so);
-		tcp_close(tp);
-		INP_UNLOCK(tp->t_inpcb);		
+		tp = tcp_close(tp);
 	}
+	if (tp)
+		INP_UNLOCK(tp->t_inpcb);	
+	send_abort_rpl(m, tdev, rst_status);
+	return;
 	
-	send_abort_rpl(m, tdev, rst_status);
+skip:
+	INP_UNLOCK(tp->t_inpcb);		
 }
 
 /*
@@ -2213,15 +2234,30 @@
 	const struct cpl_abort_req_rss *req = cplhdr(m);
 	struct toepcb *toep = (struct toepcb *)ctx;
 	struct socket *so;
+	struct inpcb *inp;
 	
 	if (is_neg_adv_abort(req->status)) {
 		m_free(m);
 		return (0);
 	}
+
 	printf("aborting tid=%d\n", toep->tp_tid);
 	
-	INP_INFO_WLOCK(&tcbinfo);
 	if (toep->tp_flags & TP_SYN_RCVD) {
+		cxgb_remove_tid(cdev, toep, toep->tp_tid);
+		printf("sending abort rpl\n");
+		
+		send_abort_rpl(m, toep->tp_toedev, CPL_ABORT_NO_RST);
+		printf("sent\n");
+		if (toep->tp_l2t) 
+			l2t_release(L2DATA(cdev), toep->tp_l2t);
+
+		/*
+		 * XXX need to call syncache_chkrst - but we don't
+		 * have a way of doing that yet
+		 */
+		toepcb_release(toep);
+		
 		printf("abort for unestablished connection :-(\n");
 		return (0);
 	}
@@ -2232,14 +2268,17 @@
 	}
 
 	so = toeptoso(toep);
+	inp = sotoinpcb(so);
+	
 	VALIDATE_SOCK(so);
 	toepcb_hold(toep);
+	INP_INFO_WLOCK(&tcbinfo);
 	process_abort_req(so, m, TOE_DEV(so));
 	INP_INFO_WUNLOCK(&tcbinfo);
 	toepcb_release(toep);
 	return (0);
 }
-
+#ifdef notyet
 static void
 pass_open_abort(struct socket *child, struct socket *parent, struct mbuf *m)
 {
@@ -2255,7 +2294,7 @@
 	} else
 		m_free(m);
 }
-
+#endif
 static void
 handle_pass_open_arp_failure(struct socket *so, struct mbuf *m)
 {
@@ -2616,7 +2655,7 @@
 	newtoep->tp_tid = tid;
 	newtoep->tp_toedev = tdev;
 		
-	DPRINTF("inserting tid=%d\n", tid);
+	printf("inserting tid=%d\n", tid);
 	cxgb_insert_tid(cdev, d->client, newtoep, tid);
 
 	if (lctx->ulp_mode) {
@@ -2631,7 +2670,11 @@
 	set_arp_failure_handler(reply_mbuf, pass_accept_rpl_arp_failure);
 
 	DPRINTF("adding request to syn cache\n");
-	
+
+	/*
+	 * XXX workaround for lack of syncache drop
+	 */
+	toepcb_hold(newtoep);
 	syncache_add_accept_req(req, so, newtoep);
 
 	rpl = cplhdr(reply_mbuf);
@@ -2850,7 +2893,7 @@
 	to.to_wscale =  G_TCPOPT_SND_WSCALE(opt);
 	to.to_flags = (mss ? TOF_MSS : 0) | (wsf ? TOF_SCALE : 0) | (ts ? TOF_TS : 0) | (sack ? TOF_SACKPERM : 0);
 
-	printf("syncache expand of %d:%d %d:%d mss:%d wsf:%d ts:%d sack:%d\n",
+	DPRINTF("syncache expand of %d:%d %d:%d mss:%d wsf:%d ts:%d sack:%d\n",
 	    ntohl(req->local_ip), ntohs(req->local_port),
 	    ntohl(req->peer_ip), ntohs(req->peer_port),
 	    mss, wsf, ts, sack);
@@ -2891,6 +2934,11 @@
 		 */
 		UNIMPLEMENTED();
 	}
+
+	/*
+	 * XXX workaround for lack of syncache drop
+	 */
+	toepcb_release(toep);
 	
 	tp = sototcpcb(so);
 	INP_LOCK(tp->t_inpcb);
@@ -2900,6 +2948,7 @@
 	tp->t_toe = toep;
 	reset_wr_list(tp);
 	tp->rcv_wnd = select_rcv_wnd(so);
+	DPRINTF("rcv_wnd=%ld\n", tp->rcv_wnd);
 	install_offload_ops(so);
 	
 	toep->tp_wr_max = toep->tp_wr_avail = TOM_TUNABLE(tdev, max_wrs);


More information about the p4-projects mailing list