PERFORCE change 118703 for review
Kip Macy
kmacy at FreeBSD.org
Tue Apr 24 04:55:40 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118703
Change 118703 by kmacy at 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);
More information about the p4-projects
mailing list