Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Feb 2008 21:04:51 GMT
From:      Steve Wise <swise@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 135281 for review
Message-ID:  <200802122104.m1CL4p98047009@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=135281

Change 135281 by swise@swise:vic10:iwarp on 2008/02/12 21:04:44

	TOE fixes to support RDMA connections.
	
	- t3_push_frames() will create in-line WRs if possible
	- sodisconnecting() at the appropriate spots

Affected files ...

.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#11 edit

Differences ...

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

@@ -292,6 +292,8 @@
 	}
 }
 
+#define IMM_LEN 64 /* XXX - see WR_LEN in the cxgb driver */
+
 int
 t3_push_frames(struct socket *so, int req_completion)
 {
@@ -343,26 +345,49 @@
 			SOCKBUF_UNLOCK(&so->so_snd);
 			return (0);
 		}
-		while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail)
-		    && (tail != NULL) && (count < TX_MAX_SEGS)) {
-			bytes += tail->m_len;
-			count++;
+
+		/*
+		 * If the data in tail fits as in-line, then
+		 * make an immediate data wr.
+		 */
+		if (tail->m_len <= IMM_LEN) {
+			count = 1;
+			bytes = tail->m_len;
 			last = tail;
-			/*
-			 * technically an abuse to be using this for a VA
-			 * but less gross than defining my own structure
-			 * or calling pmap_kextract from here :-|
-			 */
-			segp->ds_addr = (bus_addr_t)tail->m_data;
-			segp->ds_len = tail->m_len;
-			DPRINTF("count=%d wr_needed=%d ds_addr=%p ds_len=%d\n",
-			    count, mbuf_wrs[count], tail->m_data, tail->m_len);
-			
-			segp++;
 			tail = tail->m_next;
+			m_set_sgl(m0, NULL);
+			m_set_sgllen(m0, 0);
+			make_tx_data_wr(so, m0, bytes, tail);
+			m_append(m0, bytes, mtod(last, caddr_t));
+			KASSERT(!m0->m_next, ("bad append"));
+		} else {
+			while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail)
+			    && (tail != NULL) && (count < TX_MAX_SEGS)) {
+				bytes += tail->m_len;
+				count++;
+				last = tail;
+				/*
+				 * technically an abuse to be using this for a VA
+				 * but less gross than defining my own structure
+				 * or calling pmap_kextract from here :-|
+				 */
+				segp->ds_addr = (bus_addr_t)tail->m_data;
+				segp->ds_len = tail->m_len;
+				DPRINTF("count=%d wr_needed=%d ds_addr=%p ds_len=%d\n",
+				    count, mbuf_wrs[count], tail->m_data, tail->m_len);
+				
+				segp++;
+				tail = tail->m_next;
+			}
+			DPRINTF("wr_avail=%d mbuf_wrs[%d]=%d tail=%p\n",
+			    toep->tp_wr_avail, count, mbuf_wrs[count], tail);	
+
+			m_set_sgl(m0, segs);
+			m_set_sgllen(m0, count);
+			make_tx_data_wr(so, m0, bytes, tail);
 		}
-		DPRINTF("wr_avail=%d mbuf_wrs[%d]=%d tail=%p\n",
-		    toep->tp_wr_avail, count, mbuf_wrs[count], tail);	
+		m_set_priority(m0, mkprio(CPL_PRIORITY_DATA, toep));
+
 		if (tail) {
 			so->so_snd.sb_sndptr = tail;
 			toep->tp_m_last = NULL;
@@ -375,20 +400,11 @@
 		total_bytes += bytes;
 		toep->tp_write_seq += bytes;
 
-
 		SOCKBUF_UNLOCK(&so->so_snd);
 		
-		/*
-		 * XXX can drop socket buffer lock here
-		 */
-	
 		toep->tp_wr_avail -= mbuf_wrs[count];
 		toep->tp_wr_unacked += mbuf_wrs[count];
-		
-		make_tx_data_wr(so, m0, bytes, tail);
-		m_set_priority(m0, mkprio(CPL_PRIORITY_DATA, toep));
-		m_set_sgl(m0, segs);
-		m_set_sgllen(m0, count);
+
 		/*
 		 * remember credits used
 		 */
@@ -2331,7 +2347,7 @@
 {
 	struct tcpcb *tp = sototcpcb(so);
 	struct toepcb *toep = tp->t_toe;
-	int keep = 0, dead = (so->so_state & SS_NOFDREF);
+	int keep = 0;
 
 	DPRINTF("do_peer_fin state=%d dead=%d\n", tp->t_state, !!dead);
 	
@@ -2376,8 +2392,10 @@
 		t3_release_offload_resources(toep);
 		if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
 			tp = tcp_close(tp);
-		} else
+		} else {
 			enter_timewait(so);
+			soisdisconnected(so);
+		}
 		break;
 	default:
 		log(LOG_ERR,
@@ -2388,21 +2406,18 @@
 	if (tp)
 		INP_UNLOCK(tp->t_inpcb);					
 
-	if (!dead) {
-		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);
-		wakeup(&so->so_timeo);
+	DPRINTF("waking up waiters on %p rcv_notify=%d flags=0x%x\n", so, sb_notify(&so->so_rcv), so->so_rcv.sb_flags);
+	soisdisconnecting(so);
+
 #ifdef notyet		
-		/* Do not send POLL_HUP for half duplex close. */
-		if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
-		    sk->sk_state == TCP_CLOSE)
-			sk_wake_async(so, 1, POLL_HUP);
-		else
-			sk_wake_async(so, 1, POLL_IN);
+	/* Do not send POLL_HUP for half duplex close. */
+	if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
+	    sk->sk_state == TCP_CLOSE)
+		sk_wake_async(so, 1, POLL_HUP);
+	else
+		sk_wake_async(so, 1, POLL_IN);
 #endif
-	}
+
 out:
 	if (!keep)
 		m_free(m);
@@ -2445,8 +2460,10 @@
 		if (toep->tp_flags & TP_ABORT_RPL_PENDING) {
 			tp = tcp_close(tp);
 
-		} else
+		} else {
 			enter_timewait(so);
+			soisdisconnected(so);
+		}
 		break;
 	case TCPS_LAST_ACK:
 		/*
@@ -2463,14 +2480,7 @@
 #endif
 		soisdisconnecting(so);
 		
-		if ((so->so_state & SS_NOFDREF) == 0) {
-			/*
-			 * Wake up lingering close
-			 */
-			sowwakeup(so);
-			sorwakeup(so);
-			wakeup(&so->so_timeo);
-		} else if ((so->so_options & SO_LINGER) && so->so_linger == 0 &&
+		if ((so->so_options & SO_LINGER) && so->so_linger == 0 &&
 		    (toep->tp_flags & TP_ABORT_SHUTDOWN) == 0) {
 			tp = cxgb_tcp_drop(tp, 0);
 		}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802122104.m1CL4p98047009>