Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Apr 2007 04:55:39 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 118703 for review
Message-ID:  <200704240455.l3O4td3H058204@repoman.freebsd.org>

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

Change 118703 by kmacy@kmacy_vt-x:opentoe_init on 2007/04/24 04:55:13

	nix 2 more "notyet"s in offload functionality
	bring lro interface a bit closer to the Linux driver

Affected files ...

.. //depot/projects/opentoe/sys/dev/cxgb/cxgb_adapter.h#11 edit
.. //depot/projects/opentoe/sys/dev/cxgb/cxgb_lro.c#4 edit
.. //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#13 edit

Differences ...

==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_adapter.h#11 (text+ko) ====

@@ -92,10 +92,7 @@
 	FW_UPTODATE     = (1 << 4),
 };
 
-/* Max active LRO sessions per queue set */
-#define MAX_LRO_PER_QSET 8
 
-
 #define FL_Q_SIZE	4096
 #define JUMBO_Q_SIZE	512
 #define RSPQ_Q_SIZE	1024
@@ -115,17 +112,23 @@
 	LRO_ACTIVE = (1 << 8),
 };
 
-struct sge_lro_session {
-	struct mbuf *m;
+/* Max concurrent LRO sessions per queue set */
+#define MAX_LRO_SES 8
+
+struct t3_lro_session {
+	struct mbuf *head;
+	struct mbuf *tail;
 	uint32_t seq;
 	uint16_t ip_len;
+	uint16_t vtag;
+	uint8_t npkts;
 };
 
-struct sge_lro {
-	unsigned int enabled;
-	unsigned int num_active;
-	struct sge_lro_session *last_s;
-	struct sge_lro_session s[MAX_LRO_PER_QSET];
+struct lro_state {
+	unsigned short enabled;
+	unsigned short active_idx;
+	unsigned int nactive;
+	struct t3_lro_session sess[MAX_LRO_SES];
 };
 
 #define RX_BUNDLE_SIZE 8
@@ -224,7 +227,7 @@
 struct sge_qset {
 	struct sge_rspq		rspq;
 	struct sge_fl		fl[SGE_RXQ_PER_SET];
-	struct sge_lro          lro;
+	struct lro_state        lro;
 	struct sge_txq		txq[SGE_TXQ_PER_SET];
        	unsigned long           txq_stopped;       /* which Tx queues are stopped */
 	uint64_t                port_stats[SGE_PSTAT_MAX];
@@ -413,7 +416,7 @@
 void t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
     int ethpad, uint32_t rss_hash, uint32_t rss_csum, int lro);
 void t3_rx_eth(struct port_info *p, struct sge_rspq *rq, struct mbuf *m, int ethpad);
-void t3_sge_lro_flush_all(adapter_t *adap, struct sge_qset *qs);
+void t3_lro_flush(adapter_t *adap, struct sge_qset *qs, struct lro_state *state);
 
 void t3_add_sysctls(adapter_t *sc);
 int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,

==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_lro.c#4 (text+ko) ====

@@ -82,51 +82,40 @@
 #endif	  
 
 #define IPH_OFFSET (2 + sizeof (struct cpl_rx_pkt) + ETHER_HDR_LEN)
-#define LRO_SESSION_IDX_HINT_HASH(hash) (hash & (MAX_LRO_PER_QSET - 1))
-#define LRO_IDX_INC(idx) idx = (idx + 1) & (MAX_LRO_PER_QSET - 1)
-
-static __inline struct sge_lro_session *
-lro_session(struct sge_lro *l, int idx)
-{
-	return l->s + idx;
-}
+#define LRO_SESSION_IDX_HINT_HASH(hash) (hash & (MAX_LRO_SES - 1))
+#define LRO_IDX_INC(idx) idx = (idx + 1) & (MAX_LRO_SES - 1)
 
 static __inline int
-lro_match_session(struct sge_lro_session *s, 
-    struct ip *ih, struct tcphdr *th)
+lro_match(struct mbuf *m, struct ip *ih, struct tcphdr *th)
 {
-	struct ip *sih = (struct ip *)(s->m->m_data + IPH_OFFSET);
+	struct ip *sih = (struct ip *)(m->m_data + IPH_OFFSET);
 	struct tcphdr *sth = (struct tcphdr *) (sih + 1);
 
 	/*
-	 * Linux driver doesn't include destination port check --
-	 * need to find out why XXX
+	 * Why don't we check dest ports?
 	 */
 	return (*(uint32_t *)&th->th_sport == *(uint32_t *)&sth->th_sport &&
-	    *(uint32_t *)&th->th_dport == *(uint32_t *)&sth->th_dport &&
 	    ih->ip_src.s_addr == ih->ip_src.s_addr &&
 	    ih->ip_dst.s_addr == sih->ip_dst.s_addr);
 }
 
-static __inline struct sge_lro_session *
-lro_find_session(struct sge_lro *l, int idx, struct ip *ih, struct tcphdr *th)
+static __inline struct t3_lro_session *
+lro_lookup(struct lro_state *l, int idx, struct ip *ih, struct tcphdr *th)
 {
-	struct sge_lro_session *s;
-	int active = 0;
+	struct t3_lro_session *s = NULL;
+	int active = l->nactive;
 
-	while (active < l->num_active) {
-		s = lro_session(l, idx); 
-		if (s->m) {
-			if (lro_match_session(s, ih, th)) {
-				l->last_s = s;
-				return s;
-			}
-			active++;
+	while (active) {
+		s = &l->sess[idx];
+		if (s->head) {
+			if (lro_match(s->head, ih, th)) 
+				break;
+			active--;
 		}
 		LRO_IDX_INC(idx);
 	}
 
-	return NULL;
+	return (s);
 }
 
 static __inline int
@@ -174,7 +163,7 @@
 }
 
 static __inline void
-lro_new_session_init(struct sge_lro_session *s, struct mbuf *m)
+lro_new_session_init(struct t3_lro_session *s, struct mbuf *m)
 {
 	struct ip *ih = (struct ip *)(m->m_data + IPH_OFFSET);
 	struct tcphdr *th = (struct tcphdr *) (ih + 1);
@@ -182,7 +171,7 @@
 
 	DPRINTF("%s(s=%p, m=%p)\n", __FUNCTION__, s, m);
 	
-	s->m = m;
+	s->head = m;
 	
 	MBUF_HEADER_CHECK(m);
 	s->ip_len = ip_len;
@@ -191,10 +180,10 @@
 } 
 
 static void
-lro_flush_session(struct sge_qset *qs, struct sge_lro_session *s, struct mbuf *m)
+lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
 {
-	struct sge_lro *l = &qs->lro;
-	struct mbuf *sm = s->m;
+	struct lro_state *l = &qs->lro;
+	struct mbuf *sm = s->head;
 	struct ip *ih = (struct ip *)(sm->m_data + IPH_OFFSET);
 
 	
@@ -216,33 +205,33 @@
 	t3_rx_eth(qs->port, &qs->rspq, sm, 2);
 	
 	if (m) {
-		s->m = m;
+		s->head = m;
 		lro_new_session_init(s, m);
 	} else {
-		s->m = NULL;
-		l->num_active--;
+		s->head = NULL;
+		l->nactive--;
 	}
 
 	qs->port_stats[SGE_PSTATS_LRO_FLUSHED]++;
 }
 
-static __inline struct sge_lro_session *
+static __inline struct t3_lro_session *
 lro_new_session(struct sge_qset *qs, struct mbuf *m, uint32_t rss_hash)
 {
-	struct sge_lro *l = &qs->lro;
+	struct lro_state *l = &qs->lro;
 	int idx = LRO_SESSION_IDX_HINT_HASH(rss_hash); 
-	struct sge_lro_session *s = lro_session(l, idx);
+	struct t3_lro_session *s = &l->sess[idx];
 
 	DPRINTF("%s(qs=%p,  m=%p, rss_hash=0x%x)\n", __FUNCTION__,
 	    qs, m, rss_hash);
 	
-	if (__predict_true(!s->m))
+	if (__predict_true(!s->head))
 		goto done;
 
-	if (l->num_active > MAX_LRO_PER_QSET)
+	if (l->nactive > MAX_LRO_SES)
 		panic("MAX_LRO_PER_QSET exceeded");
 	
-	if (l->num_active == MAX_LRO_PER_QSET) {
+	if (l->nactive == MAX_LRO_SES) {
 		lro_flush_session(qs, s, m);
 		qs->port_stats[SGE_PSTATS_LRO_X_STREAMS]++;
 		return s;
@@ -250,21 +239,21 @@
 
 	while (1) {
 		LRO_IDX_INC(idx);
-		s = lro_session(l, idx);
-		if (!s->m)
+		s = &l->sess[idx];
+		if (!s->head)
 			break;
 	}
 done:
 	lro_new_session_init(s, m);
-	l->num_active++;
+	l->nactive++;
 
 	return s;
 }
 
 static __inline int
-lro_update_session(struct sge_lro_session *s, struct mbuf *m)
+lro_update_session(struct t3_lro_session *s, struct mbuf *m)
 {
-	struct mbuf *sm = s->m;
+	struct mbuf *sm = s->head;
 	struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(sm->m_data + 2);
 	struct cpl_rx_pkt *ncpl = (struct cpl_rx_pkt *)(m->m_data + 2);
 	struct ip *nih = (struct ip *)(m->m_data + IPH_OFFSET);
@@ -354,7 +343,7 @@
 	struct ether_header *eh = (struct ether_header *)(cpl + 1);
 	struct ip *ih;
 	struct tcphdr *th; 
-	struct sge_lro_session *s = NULL;
+	struct t3_lro_session *s = NULL;
 	struct port_info *pi = qs->port;
 	
 	if (lro == 0)
@@ -369,7 +358,7 @@
 	ih = (struct ip *)(eh + 1);
 	th = (struct tcphdr *)(ih + 1);
 	
-	s = lro_find_session(&qs->lro,
+	s = lro_lookup(&qs->lro,
 	    LRO_SESSION_IDX_HINT_HASH(rss_hash), ih, th);
 	
 	if (__predict_false(!can_lro_tcpsegment(th))) {
@@ -380,7 +369,7 @@
 		if (lro_update_session(s, m)) {
 			lro_flush_session(qs, s, m);
 		}
-		if (__predict_false(s->m->m_pkthdr.len + pi->ifp->if_mtu > 65535)) {
+		if (__predict_false(s->head->m_pkthdr.len + pi->ifp->if_mtu > 65535)) {
 			lro_flush_session(qs, s, NULL);
 		}		
 	}
@@ -398,21 +387,15 @@
 }
 
 void
-t3_sge_lro_flush_all(adapter_t *adap, struct sge_qset *qs)
+t3_lro_flush(adapter_t *adap, struct sge_qset *qs, struct lro_state *state)
 {
-	struct sge_lro *l = &qs->lro;
-	struct sge_lro_session *s = l->last_s; 
-	int active = 0, idx = 0, num_active = l->num_active;
+	unsigned int idx = state->active_idx;
 
-	if (__predict_false(!s))
-		s = lro_session(l, idx);
-
-	while (active < num_active) {
-		if (s->m) {
+	while (state->nactive) {
+		struct t3_lro_session *s = &state->sess[idx];
+		
+		if (s->head) 
 			lro_flush_session(qs, s, NULL);
-			active++;
-		}
 		LRO_IDX_INC(idx);
-		s = lro_session(l, idx);
 	}
 }

==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#13 (text+ko) ====

@@ -2056,11 +2056,11 @@
 static __inline void
 deliver_partial_bundle(struct toedev *tdev,
 			struct sge_rspq *q,
-			struct mbuf *m[], int n)
+			struct mbuf *mbufs[], int n)
 {
 	if (n) {
 		q->offload_bundles++;
-		cxgb_ofld_recv(tdev, m, n);
+		cxgb_ofld_recv(tdev, mbufs, n);
 	}
 }
 
@@ -2069,8 +2069,10 @@
     struct mbuf *m, struct mbuf *rx_gather[],
     unsigned int gather_idx)
 {
-#ifdef notyet
-	if (rq->polling) {
+	rq->offload_pkts++;
+	m->m_pkthdr.header = mtod(m, void *);
+	    
+	if (__predict_false(rq->polling)) {
 		rx_gather[gather_idx++] = m;
 		if (gather_idx == RX_BUNDLE_SIZE) {
 			cxgb_ofld_recv(tdev, rx_gather, RX_BUNDLE_SIZE);
@@ -2078,7 +2080,6 @@
 			rq->offload_bundles++;
 		}
 	} else
-#endif
 		offload_enqueue(rq, m);
 
 	return (gather_idx);
@@ -2274,9 +2275,8 @@
 	int budget_left = budget;
 	unsigned int sleeping = 0;
 	int lro = qs->lro.enabled;
-		
-	static uint8_t pinned[MAXCPU];
-
+	struct mbuf *offload_mbufs[RX_BUNDLE_SIZE];
+	int ngathered = 0;
 #ifdef DEBUG	
 	static int last_holdoff = 0;
 	if (rspq->holdoff_tmr != last_holdoff) {
@@ -2367,7 +2367,8 @@
 				 */
 				m->m_priority = rss_hash;
 				
-				rx_offload(&adap->tdev, rspq, m);
+				ngathered = rx_offload(&adap->tdev, rspq, m,
+				    offload_mbufs, ngathered);
 #endif
 			}
 #ifdef notyet			
@@ -2379,10 +2380,11 @@
 		}
 		--budget_left;
 	}
-	t3_sge_lro_flush_all(adap, qs);
-#ifdef notyet	
-	deliver_partial_bundle(&adap->tdev, rspq);
-#endif
+	
+
+	deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
+	t3_lro_flush(adap, qs, &qs->lro);
+	
 	if (sleeping)
 		check_ring_db(adap, qs, sleeping);
 



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