PERFORCE change 126786 for review
Kip Macy
kmacy at FreeBSD.org
Mon Sep 24 13:35:12 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126786
Change 126786 by kmacy at kmacy_home:ethng on 2007/09/24 20:34:58
remove use of sendq list for queue management
coalescing using the list doesn't help with performance but adds complexity
Affected files ...
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#19 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#19 edit
Differences ...
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#19 (text+ko) ====
@@ -281,6 +281,7 @@
*/
struct mbuf_head cleanq;
struct mbuf_ring txq_mr;
+ struct mbuf *immpkt;
uint32_t txq_drops;
uint32_t txq_skipped;
uint32_t txq_coalesced;
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#19 (text+ko) ====
@@ -103,7 +103,7 @@
SYSCTL_UINT(_hw_cxgb, OID_AUTO, sleep_ticks, CTLFLAG_RDTUN, &sleep_ticks, 0,
"ticks to sleep between checking pcpu queues");
-int cxgb_txq_mbuf_ring_size = 8192;
+int cxgb_txq_mbuf_ring_size = 2048;
TUNABLE_INT("hw.cxgb.txq_mr_size", &cxgb_txq_mbuf_ring_size);
SYSCTL_UINT(_hw_cxgb, OID_AUTO, txq_mr_size, CTLFLAG_RDTUN, &cxgb_txq_mbuf_ring_size, 0,
"size of per-queue mbuf ring");
@@ -118,7 +118,6 @@
{
struct sge_txq *txq;
struct mbuf_ring *mr;
- struct mbuf_head *mbq;
int prod, cons, mask;
int err = 0;
@@ -129,9 +128,6 @@
txq = &qs->txq[TXQ_ETH];
DPRINTF("enqueueing packet to cpuid=%d\n", qs->qs_cpuid);
-
- mbq = &txq->sendq;
-
mr = &txq->txq_mr;
mtx_lock(&mr->mr_lock);
cons = mr->mr_cons;
@@ -179,23 +175,29 @@
struct mbuf *m;
struct sge_qset *qs;
int count, size, coalesced;
- struct mbuf_head *mbq;
+ struct mbuf_ring *mr;
- mbq = &txq->sendq;
+ mr = &txq->txq_mr;
coalesced = count = size = 0;
qs = txq_to_qset(txq, TXQ_ETH);
if (qs->qs_flags & QS_EXITING)
return (0);
- for (m = mbufq_dequeue(mbq); m != NULL; m = mbufq_dequeue(mbq)) {
+ if (txq->immpkt != NULL) {
+ m_vec[0] = txq->immpkt;
+ txq->immpkt = NULL;
+ return (1);
+ }
+
+ for (m = mbuf_ring_dequeue(mr); m != NULL; m = mbuf_ring_dequeue(mr)) {
size += m->m_pkthdr.len;
m_vec[count++] = m;
if (count == TX_WR_COUNT_MAX || cxgb_pcpu_tx_coalesce == 0)
break;
- m = mbufq_peek(mbq);
+ m = mbuf_ring_peek(mr);
/*
* We can't coalesce TSO packets or past 11K
*/
@@ -337,44 +339,6 @@
return (cookie);
}
-static inline int
-cxgb_pcpu_pkt_coalesce(struct sge_txq *txq, struct mbuf *imm)
-{
- int prod, cons, mask, err;
- struct mbuf_head *mbq;
- struct mbuf_ring *mr;
- struct mbuf **ring, *m;
-
- mbq = &txq->sendq;
- mr = &txq->txq_mr;
- ring = mr->mr_ring;
- mask = mr->mr_size - 1;
- err = 0;
- /*
- * Arbitrary threshold at which to apply backpressure
- */
- if (mbufq_len(mbq) > cxgb_txq_mbuf_ring_size) {
- if (imm) {
- m_freem(imm);
- txq->txq_drops++;
- }
- return (ENOBUFS);
- }
-
- cons = mr->mr_cons;
- prod = mr->mr_prod;
- while (cons != prod) {
- m = ring[cons];
- cons = (cons + 1) & mask;
- mbufq_tail(mbq, m);
- }
- mr->mr_cons = cons;
- if (imm)
- mbufq_tail(mbq, imm);
-
- return (err);
-}
-
static void
cxgb_pcpu_free(struct sge_qset *qs)
{
@@ -383,13 +347,12 @@
while ((m = mbufq_dequeue(&txq->sendq)) != NULL)
m_freem(m);
- cxgb_pcpu_pkt_coalesce(txq, NULL);
- while ((m = mbufq_dequeue(&txq->sendq)) != NULL)
+ while ((m = mbuf_ring_dequeue(&txq->txq_mr)) != NULL)
m_freem(m);
}
static int
-cxgb_pcpu_reclaim_tx(struct sge_txq *txq, struct mbuf_head *mbq)
+cxgb_pcpu_reclaim_tx(struct sge_txq *txq)
{
int reclaimable;
struct sge_qset *qs = txq_to_qset(txq, TXQ_ETH);
@@ -414,7 +377,7 @@
}
static int
-cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush, struct mbuf_head *mbq)
+cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush)
{
int i, err, initerr, flush, reclaimed, stopped;
struct port_info *pi;
@@ -433,7 +396,12 @@
initerr = ENXIO;
else {
txq = &qs->txq[TXQ_ETH];
- initerr = cxgb_pcpu_pkt_coalesce(txq, immpkt);
+
+ if (!mbuf_ring_empty(&txq->txq_mr)) {
+ initerr = cxgb_pcpu_enqueue_packet_(qs, immpkt);
+ } else
+ txq->immpkt = immpkt;
+
immpkt = NULL;
}
if (initerr && initerr != ENOBUFS) {
@@ -453,17 +421,17 @@
qs->qs_cpuid, curcpu, desc_reclaimable(txq),
txq, txq->cidx, txq->pidx);
}
- reclaimed = cxgb_pcpu_reclaim_tx(txq, mbq);
+ reclaimed = cxgb_pcpu_reclaim_tx(txq);
if (cxgb_debug)
printf("reclaimed=%d\n", reclaimed);
}
stopped = isset(&qs->txq_stopped, TXQ_ETH);
- flush = (!mbufq_empty(&txq->sendq) && !stopped);
+ flush = ((!mbuf_ring_empty(&txq->txq_mr) && !stopped) || txq->immpkt);
max_desc = tx_flush ? 0xffffff : TX_START_MAX_DESC;
err = flush ? cxgb_tx_common(qs->port->ifp, qs, max_desc) : ENOSPC;
-
- if ((tx_flush && flush && err == 0) && !mbufq_empty(&txq->sendq)) {
+
+ if ((tx_flush && flush && err == 0) && !mbuf_ring_empty(&txq->txq_mr)) {
#if 0
struct thread *td = curthread;
thread_lock(td);
@@ -490,8 +458,6 @@
struct port_info *pi;
struct sge_qset *qs;
struct sge_txq *txq = NULL /* gcc is dumb */;
- struct mbuf_head mbq;
- struct mbuf *m;
pi = ifp->if_softc;
qs = NULL;
@@ -507,12 +473,11 @@
txq = &qs->txq[TXQ_ETH];
- mbufq_init(&mbq);
if (mtx_trylock(&txq->lock)) {
txq->flags |= TXQ_TRANSMITTING;
- err = cxgb_pcpu_start_(qs, immpkt, FALSE, &mbq);
+ err = cxgb_pcpu_start_(qs, immpkt, FALSE);
txq->flags &= ~TXQ_TRANSMITTING;
- resid = (mbufq_len(&txq->sendq) > 128) || (desc_reclaimable(txq) > 128);
+ resid = (mbuf_ring_count(&txq->txq_mr) > 64) || (desc_reclaimable(txq) > 64);
mtx_unlock(&txq->lock);
} else if (immpkt)
err = cxgb_pcpu_enqueue_packet_(qs, immpkt);
@@ -520,21 +485,6 @@
if (resid && (txq->flags & TXQ_TRANSMITTING) == 0)
wakeup(qs);
- critical_enter();
- /*
- * Are we on a cpu with a service thread?
- */
- if (curcpu < SGE_QSETS) {
- qs = &pi->adapter->sge.qs[curcpu];
- txq = &qs->txq[TXQ_ETH];
- mbufq_append(&txq->cleanq, &mbq);
- critical_exit();
- } else {
- critical_exit();
- while ((m = mbufq_dequeue(&mbq)) != NULL)
- m_freem(m);
- }
-
return ((err == ENOSPC) ? 0 : err);
}
@@ -545,9 +495,7 @@
struct sge_qset *qs;
struct mbuf *m, *head, *tail, *lhead, *ltail;
int calc_cookie, qidx, i;
- struct mbuf_head mbq;
- mbufq_init(&mbq);
IFQ_LOCK(&ifp->if_snd);
IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
head = tail = m;
@@ -584,7 +532,7 @@
* Assume one-to-one mapping of qset to CPU for now XXX
*/
- (void)cxgb_pcpu_start_(qs, NULL, TRUE, &mbq);
+ (void)cxgb_pcpu_start_(qs, NULL, TRUE);
/*
* XXX multiple packets
*/
@@ -599,8 +547,6 @@
struct thread *td;
struct adapter *sc = qs->port->adapter;
struct sge_txq *txq = &qs->txq[TXQ_ETH];
- struct mbuf_head mbq;
- struct mbuf *m;
int err = 0;
@@ -616,18 +562,15 @@
printf("bound to %d running on %d\n", qs->qs_cpuid, curcpu);
for (;;) {
- mbufq_init(&mbq);
-
if (qs->qs_flags & QS_EXITING)
break;
if ((qs->port->ifp->if_drv_flags && IFF_DRV_RUNNING) == 0)
goto done;
-
if (mtx_trylock(&txq->lock)) {
txq->flags |= TXQ_TRANSMITTING;
- err = cxgb_pcpu_start_(qs, NULL, TRUE, &mbq);
+ err = cxgb_pcpu_start_(qs, NULL, TRUE);
txq->flags &= ~TXQ_TRANSMITTING;
mtx_unlock(&txq->lock);
} else
@@ -643,9 +586,7 @@
mtx_unlock(&qs->rspq.lock);
}
- if ((!mbufq_empty(&txq->sendq) ||
- (txq->txq_mr.mr_cons != txq->txq_mr.mr_prod)) &&
- err == 0) {
+ if ((!mbuf_ring_empty(&txq->txq_mr)) && err == 0) {
if (cxgb_debug)
printf("head=%p cons=%d prod=%d\n",
txq->sendq.head, txq->txq_mr.mr_cons,
@@ -653,13 +594,6 @@
continue;
}
done:
- critical_enter();
- mbufq_append(&mbq, &txq->cleanq);
- mbufq_init(&txq->cleanq);
- critical_exit();
- while ((m = mbufq_dequeue(&mbq)) != NULL)
- m_freem(m);
-
tsleep(qs, 1, "cxgbidle", sleep_ticks);
}
More information about the p4-projects
mailing list