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>