PERFORCE change 129611 for review

Kip Macy kmacy at FreeBSD.org
Mon Nov 26 22:36:38 PST 2007


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

Change 129611 by kmacy at kmacy:storage:toestack on 2007/11/27 06:36:32

	make locking a bit more consistent
	fix socket buffer accounting in t3_push_frames by only skipping the last buffer
	if sndptroff is not zero

Affected files ...

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

Differences ...

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

@@ -170,10 +170,13 @@
 send_or_defer(struct socket *so, struct tcpcb *tp, struct mbuf *m, int through_l2t)
 {
 	struct toepcb *toep = tp->t_toe;
+
 	
-	if (__predict_false(tp->t_state == TCPS_SYN_SENT))
+	if (__predict_false(tp->t_state == TCPS_SYN_SENT)) {
+		INP_LOCK(tp->t_inpcb);
 		mbufq_tail(&toep->out_of_order_queue, m);  // defer
-	else if (through_l2t)
+		INP_UNLOCK(tp->t_inpcb);
+	} else if (through_l2t)
 		l2t_send(T3C_DEV(so), m, toep->tp_l2t);  // send through L2T
 	else
 		cxgb_ofld_send(T3C_DEV(so), m);          // send directly
@@ -207,11 +210,12 @@
 	struct toepcb *toep = tp->t_toe;
 	struct tx_data_wr *req;
 
+	INP_LOCK_ASSERT(tp->t_inpcb);
+
 	req = mtod(m, struct tx_data_wr *);
 	m->m_len = sizeof(*req);
 	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
 	req->wr_lo = htonl(V_WR_TID(toep->tp_tid));
-	req->sndseq = htonl(tp->snd_nxt);
 	/* len includes the length of any HW ULP additions */
 	req->len = htonl(len);
 	req->param = htonl(V_TX_PORT(toep->tp_l2t->smt_idx));
@@ -220,7 +224,7 @@
 	                   V_TX_URG(/* skb_urgent(skb) */ 0 ) |
 	                   V_TX_SHOVE((!(tp->t_flags & TF_MORETOCOME) &&
 				   (tail ? 0 : 1))));
-
+	req->sndseq = htonl(tp->snd_nxt);
 	if (__predict_false((toep->tp_flags & TP_DATASENT) == 0)) {
 		req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT | 
 				    V_TX_CPU_IDX(toep->tp_qset));
@@ -259,16 +263,18 @@
 		return (0);
 	}
 
+	INP_LOCK_ASSERT(tp->t_inpcb);
+	
 	SOCKBUF_LOCK(&so->so_snd);
 	
 	d = TOM_DATA(TOE_DEV(so));
 	cdev = d->cdev;
 	last = tail = so->so_snd.sb_sndptr ? so->so_snd.sb_sndptr : so->so_snd.sb_mb;
 	total_bytes = 0;
-	printf("tail=%p snd.cc=%d tp_last=%p\n", tail, so->so_snd.sb_cc,
-		toep->tp_m_last);
+	DPRINTF("wr_avail=%d tail=%p snd.cc=%d tp_last=%p\n",
+	    toep->tp_wr_avail, tail, so->so_snd.sb_cc, toep->tp_m_last);
 
-	if (last && toep->tp_m_last == last) {
+	if (last && toep->tp_m_last == last  && so->so_snd.sb_sndptroff != 0) {
 		KASSERT(tail, ("sbdrop error"));
 		last = tail = tail->m_next;
 	}
@@ -279,16 +285,15 @@
 		return (0);		
 	}
 			
+	toep->tp_m_last = NULL;
 	while (toep->tp_wr_avail && (tail != NULL)) {
-
-		
 		count = bytes = 0;
 		if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) {
 			SOCKBUF_UNLOCK(&so->so_snd);
 			return (0);
 		}
-		
-		while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail) && (tail != NULL) && (count < TX_MAX_SEGS)) {
+		while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail)
+		    && (tail != NULL) && (count < TX_MAX_SEGS)) {
 			bytes += tail->m_len;
 			count++;
 			last = tail;
@@ -360,8 +365,6 @@
 	return (total_bytes);
 }
 
-
-
 /*
  * Close a connection by sending a CPL_CLOSE_CON_REQ message.  Cannot fail
  * under any circumstances.  We take the easy way out and always queue the
@@ -475,6 +478,8 @@
 	if (!((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1) ||
 		(tp->t_state == TCPS_FIN_WAIT_2)))
 		return;
+	INP_LOCK_ASSERT(tp->t_inpcb);
+	
 	so = tp->t_inpcb->inp_socket;
 	SOCKBUF_LOCK(&so->so_rcv);
 	read = toep->tp_enqueued_bytes - so->so_rcv.sb_cc;
@@ -764,7 +769,7 @@
 {
 	struct toepcb *toep = sototoep(so);
 	toepcb_hold(toep);
-	
+
 	cxgb_insert_tid(d->cdev, d->client, toep, tid);
 }
 
@@ -843,6 +848,7 @@
 	if (!cdev)
 		return;
 
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	toep->tp_qset = 0;
 	t3_release_ddp_resources(so);
 
@@ -945,8 +951,9 @@
 {
 	struct tcpcb *tp = sototcpcb(so);
 	struct t3c_data *td = T3C_DATA(TOM_DATA(dev)->cdev);
+
+	SOCK_LOCK_ASSERT(so);
 	
-
 	printf("initializing offload socket\n");
 	so->so_rcv.sb_flags |= SB_TOE;
 	so->so_snd.sb_flags |= SB_TOE;
@@ -1070,7 +1077,8 @@
 fail_act_open(struct socket *so, int errno)
 {
 	struct tcpcb *tp = sototcpcb(so);
-	
+
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	t3_release_offload_resources(so);
 	tcp_drop(tp, errno);
 	
@@ -1193,18 +1201,23 @@
 	e = t3_l2t_get(d->cdev, dst, egress_ifp);
 	if (!e)
 		goto free_tid;
-	    
+
+	INP_LOCK_ASSERT(inp);
 	m = m_gethdr(MT_DATA, M_WAITOK);
 	
 #if 0	
 	m->m_toe.mt_toepcb = tp->t_toe;
 	set_arp_failure_handler((struct mbuf *)m, act_open_req_arp_failure);
-#endif	
+#endif
+	SOCK_LOCK(so);
+	
 	init_offload_socket(so, tdev, atid, e, dst, toep);
 	
 	install_offload_ops(so);
 	
 	mk_act_open_req(so, m, atid, e);
+	SOCK_UNLOCK(so);
+	
 	soisconnecting(so);
 	toep = tp->t_toe;
 	m_set_toep(m, tp->t_toe);
@@ -1239,9 +1252,9 @@
 	int mode = CPL_ABORT_SEND_RST;
 	struct mbuf *m;
 	
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	if (__predict_false((toep->tp_flags & TP_ABORT_SHUTDOWN) || !TOE_DEV(so)))
 		return;
-
 	toep->tp_flags |= (TP_ABORT_RPL_PENDING|TP_ABORT_SHUTDOWN);
 	
 	/* Purge the send queue so we don't send anything after an abort. */
@@ -1260,6 +1273,7 @@
 	req->rsvd0 = htonl(tp->snd_nxt);
 	req->rsvd1 = !(toep->tp_flags & TP_DATASENT);
 	req->cmd = mode;
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	if (tp->t_state == TCPS_SYN_SENT)
 		mbufq_tail(&toep->out_of_order_queue, m);	// defer
 	else
@@ -1440,21 +1454,7 @@
 #endif
 	SOCKBUF_LOCK(&so->so_rcv);
 	if (sb_notify(&so->so_rcv))
-		printf("rx_data so=%p flags=0x%x len=%d\n", so, so->so_rcv.sb_flags, m->m_pkthdr.len);
-	if (m->m_pkthdr.len == 80) {
-		int i;
-		uint64_t *data;
-
-		data = mtod(m, uint64_t *);
-		printf("80 byte packet:\n");
-		for (i = 0; i < 10; i++, data++) {
-			uint8_t *dp = (uint8_t *)data;
-			
-			printf("%02x%02x%02x%02x%02x%02x%02x%02x\n",
-			    dp[0],dp[1],dp[2],dp[3],dp[4],dp[5],dp[6],dp[7]);
-		}
-	}
-	
+		DPRINTF("rx_data so=%p flags=0x%x len=%d\n", so, so->so_rcv.sb_flags, m->m_pkthdr.len);
 	
 	sbappendstream_locked(&so->so_rcv, m);
 	INP_UNLOCK(tp->t_inpcb);
@@ -1695,6 +1695,7 @@
 {
 	struct tcpcb *tp = sototcpcb(so);
 
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	/*
 	 * Bump rcv_nxt for the peer FIN.  We don't do this at the time we
 	 * process peer_close because we don't want to carry the peer FIN in
@@ -1709,7 +1710,6 @@
 	tcp_twstart(tp);
 }
 
-
 /*
  * Handle a peer FIN.
  */
@@ -1741,6 +1741,8 @@
 	sk->sk_shutdown |= RCV_SHUTDOWN;
 	sock_set_flag(so, SOCK_DONE);
 #endif
+	INP_INFO_WLOCK(&tcbinfo);
+	INP_LOCK(tp->t_inpcb);
 	if (TCPS_HAVERCVDFIN(tp->t_state) == 0) 
 		socantrcvmore(so);
 	switch (tp->t_state) {
@@ -1765,11 +1767,7 @@
 		 */
 		t3_release_offload_resources(so);
 		if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
-			INP_INFO_WLOCK(&tcbinfo);
-			INP_LOCK(tp->t_inpcb);
 			tcp_close(tp);
-			INP_INFO_WUNLOCK(&tcbinfo);
-			INP_UNLOCK(tp->t_inpcb);					
 		} else
 			enter_timewait(so);
 		break;
@@ -1778,6 +1776,8 @@
 		       "%s: TID %u received PEER_CLOSE in bad state %d\n",
 		       TOE_DEV(so)->name, toep->tp_tid, tp->t_state);
 	}
+	INP_INFO_WUNLOCK(&tcbinfo);
+	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);
@@ -1831,16 +1831,14 @@
 	if (!is_t3a(TOE_DEV(so)) && (toep->tp_flags & TP_ABORT_RPL_PENDING))
 		goto out;
 	
+	INP_INFO_WLOCK(&tcbinfo);
+	INP_LOCK(inp);
 	switch (tp->t_state) {
 	case TCPS_CLOSING:              /* see FIN_WAIT2 case in do_peer_fin */
 		t3_release_offload_resources(so);
 		if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
-			INP_INFO_WLOCK(&tcbinfo);
-			INP_LOCK(inp);
 			tp = tcp_close(tp);
-			INP_INFO_WUNLOCK(&tcbinfo);
-			if (tp)
-				INP_UNLOCK(inp);
+
 		} else
 			enter_timewait(so);
 		break;
@@ -1851,13 +1849,7 @@
 		 * late, this close_con_rpl is the actual last message.
 		 */
 		t3_release_offload_resources(so);
-		INP_INFO_WLOCK(&tcbinfo);
-		INP_LOCK(inp);
 		tp = tcp_close(tp);
-		INP_INFO_WUNLOCK(&tcbinfo);
-		if (tp)
-			INP_UNLOCK(inp);
-
 		break;
 	case TCPS_FIN_WAIT_1:
 #ifdef notyet
@@ -1885,6 +1877,9 @@
 		       TOE_DEV(so)->name, toep->tp_tid,
 		       tp->t_state);
 	}
+	INP_INFO_WUNLOCK(&tcbinfo);
+	if (tp)
+		INP_UNLOCK(inp);
 out:
 	m_free(m);
 }
@@ -1922,7 +1917,8 @@
 		  "process_abort_rpl: GTS rpl pending %d",
 		  sock_flag(sk, ABORT_RPL_PENDING));
 #endif
-
+	INP_LOCK_ASSERT(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;
@@ -1968,7 +1964,6 @@
 	}
 
 	toep = (struct toepcb *)ctx;
-	so = toeptoso(toep);
 	
         /*
 	 * Sometimes we've already closed the socket, e.g., a post-close
@@ -1977,9 +1972,10 @@
 	 * but FW turns the ABORT_REQ into a regular one and so we get
 	 * ABORT_RPL_RSS with status 0 and no socket.  Only on T3A.
 	 */
-	if (!so)
+	if (!toep)
 		goto discard;
 	
+	so = toeptoso(toep);
 	toepcb_hold(toep);
 	process_abort_rpl(so, m);
 	toepcb_release(toep);
@@ -2161,7 +2157,8 @@
 	const struct cpl_abort_req_rss *req = cplhdr(m);
 	struct tcpcb *tp = sototcpcb(so);
 	struct toepcb *toep = tp->t_toe;
-	
+
+	INP_LOCK_ASSERT(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);
@@ -2745,6 +2742,8 @@
 	const struct t3c_data *td = T3C_DATA(T3C_DEV(so));
 	struct tcpcb *tp = sototcpcb(so);
 	struct toepcb *toep = tp->t_toe;
+
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	
 	toep->tp_mss_clamp = td->mtus[G_TCPOPT_MSS(opt)] - 40;
 	tp->t_flags         |= G_TCPOPT_TSTAMP(opt) ? TF_RCVD_TSTMP : 0;
@@ -2884,6 +2883,7 @@
 	}
 	
 	tp = sototcpcb(so);
+	INP_LOCK(tp->t_inpcb);
 	so->so_snd.sb_flags |= SB_TOE;
 	so->so_rcv.sb_flags |= SB_TOE;
 	toep->tp_tp = tp;
@@ -2906,7 +2906,7 @@
 	     
 	make_established(so, ntohl(req->snd_isn), ntohs(req->tcp_opt));
 	INP_INFO_WUNLOCK(&tcbinfo);
-	
+	INP_UNLOCK(tp->t_inpcb);
 	soisconnected(so);
 	
 #ifdef notyet
@@ -2954,6 +2954,7 @@
 
 	printf("fixup_and_send_ofo\n");
 	
+	INP_LOCK_ASSERT(tp->t_inpcb);
 	while ((m = mbufq_dequeue(&toep->out_of_order_queue)) != NULL) {
 		/*
 		 * A variety of messages can be waiting but the fields we'll
@@ -3192,9 +3193,7 @@
 static void
 t3_reset_listen_child(struct socket *child)
 {
-	SOCK_LOCK(child);
 	t3_send_reset(child);
-	SOCK_UNLOCK(child);
 }
 
 /*


More information about the p4-projects mailing list