PERFORCE change 125462 for review
Kip Macy
kmacy at FreeBSD.org
Mon Aug 20 15:02:13 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125462
Change 125462 by kmacy at kmacy_home:ethng on 2007/08/20 22:02:11
- track number of descriptors skipped and number of mbufs freed
- bump txq_drops when coalesce fails due to queue overflow
- only print debug statement on 10th iteration in reclaim
- fix leak caused by acting as if more were reclaimed per iteration than were in fact
- TX_START_MAX_DESC appears to be optimally set to 2^5
- don't call bus_dmamap_destroy when freeing corresponding mbuf
Affected files ...
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#10 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#11 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#4 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#13 edit
Differences ...
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#10 (text+ko) ====
@@ -272,6 +272,8 @@
struct mbuf_head sendq;
struct mbuf_ring txq_mr;
uint32_t txq_drops;
+ uint32_t txq_skipped;
+ unsigned long txq_frees;
struct mtx lock;
#define TXQ_NAME_LEN 32
char lockbuf[TXQ_NAME_LEN];
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#11 (text+ko) ====
@@ -349,8 +349,10 @@
* Arbitrary threshold at which to apply backpressure
*/
if (mbufq_len(mbq) > cxgb_txq_mbuf_ring_size) {
- if (imm)
+ if (imm) {
m_freem_vec(imm);
+ txq->txq_drops++;
+ }
*complete = 1;
return (ENOBUFS);
}
@@ -388,72 +390,72 @@
static int
cxgb_pcpu_reclaim_tx(struct sge_txq *txq)
{
- int reclaimable, reclaimed, i, j, n;
+ int reclaimable, reclaimed, freed, i, j, n;
struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
struct sge_qset *qs = txq_to_qset(txq, TXQ_ETH);
KASSERT(qs->qs_cpuid == curcpu, ("cpu qset mismatch cpuid=%d curcpu=%d",
qs->qs_cpuid, curcpu));
- reclaimed = j = 0;
- reclaimable = desc_reclaimable(txq);
+ freed = reclaimed = j = 0;
+ reclaimable = min(desc_reclaimable(txq), TX_CLEAN_MAX_DESC);
while (reclaimable > 0) {
- n = t3_free_tx_desc(txq, min(reclaimable, TX_CLEAN_MAX_DESC), m_vec);
+ n = t3_free_tx_desc(txq, reclaimable, m_vec);
- reclaimed += min(reclaimable, TX_CLEAN_MAX_DESC);
+ reclaimed += reclaimable;
- if (j > 5 || cxgb_debug)
+ if (j > 10 || cxgb_debug)
printf("n=%d reclaimable=%d txq->processed=%d txq->cleaned=%d txq->in_use=%d\n",
n, reclaimable, txq->processed, txq->cleaned, txq->in_use);
- for (i = 0; i < n; i++)
+ for (i = 0; i < n; i++)
m_freem_vec(m_vec[i]);
+ freed += n;
j++;
txq->cleaned += reclaimable;
txq->in_use -= reclaimable;
if (isset(&qs->txq_stopped, TXQ_ETH))
clrbit(&qs->txq_stopped, TXQ_ETH);
- reclaimable = desc_reclaimable(txq);
+ reclaimable = min(desc_reclaimable(txq), TX_CLEAN_MAX_DESC);
}
+ txq->txq_frees += freed;
return (reclaimed);
}
static int
cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush)
{
- int i, err, flush, complete, reclaimed, stopped;
+ int i, err, initerr, flush, complete, reclaimed, stopped;
struct port_info *pi;
struct sge_txq *txq;
adapter_t *sc;
uint32_t max_desc;
pi = qs->port;
- err = 0;
+ initerr = err = i = reclaimed = 0;
sc = pi->adapter;
- i = reclaimed = 0;
retry:
if (!pi->link_config.link_ok)
- err = ENXIO;
+ initerr = ENXIO;
else if (qs->qs_flags & QS_EXITING)
- err = ENXIO;
+ initerr = ENXIO;
else {
txq = &qs->txq[TXQ_ETH];
- cxgb_pcpu_pkt_coalesce(txq, immpkt, &complete);
+ initerr = cxgb_pcpu_pkt_coalesce(txq, immpkt, &complete);
immpkt = NULL;
}
- if (err) {
+ if (initerr && initerr != ENOBUFS) {
if (cxgb_debug)
printf("cxgb link down\n");
if (immpkt)
m_freem_vec(immpkt);
- return (err);
+ return (initerr);
}
-
- if (desc_reclaimable(txq) > 0) {
+ if ((tx_flush && (desc_reclaimable(txq) > 0)) || (desc_reclaimable(txq) > (TX_ETH_Q_SIZE>>1))) {
int reclaimed = 0;
if (cxgb_debug) {
@@ -488,6 +490,8 @@
goto retry;
}
+ err = (initerr != 0) ? initerr : err;
+
return (err);
}
@@ -495,15 +499,14 @@
cxgb_pcpu_start(struct ifnet *ifp, struct mbuf *immpkt)
{
uint32_t cookie;
- int err, qidx, locked;
+ int err, qidx, locked, resid;
struct port_info *pi;
struct sge_qset *qs;
struct sge_txq *txq = NULL /* gcc is dumb */;
-
pi = ifp->if_softc;
qs = NULL;
- err = cookie = locked = 0;
+ resid = err = cookie = locked = 0;
if (immpkt && (immpkt->m_pkthdr.rss_hash != 0)) {
cookie = immpkt->m_pkthdr.rss_hash;
@@ -516,11 +519,17 @@
txq = &qs->txq[TXQ_ETH];
if (mtx_trylock(&txq->lock)) {
+ txq->flags |= TXQ_TRANSMITTING;
err = cxgb_pcpu_start_(qs, immpkt, FALSE);
+ txq->flags &= ~TXQ_TRANSMITTING;
+ resid = (mbufq_len(&txq->sendq) > 128) || (desc_reclaimable(txq) > 128);
mtx_unlock(&txq->lock);
} else if (immpkt)
err = cxgb_pcpu_enqueue_packet_(qs, immpkt);
+ if (resid && (txq->flags & TXQ_TRANSMITTING) == 0)
+ wakeup(qs);
+
return ((err == ENOSPC) ? 0 : err);
}
@@ -599,9 +608,14 @@
for (;;) {
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);
+ txq->flags &= ~TXQ_TRANSMITTING;
mtx_unlock(&txq->lock);
} else
err = EINPROGRESS;
@@ -625,6 +639,7 @@
txq->txq_mr.mr_prod);
continue;
}
+ done:
tsleep(qs, 1, "cxgbidle", sleep_ticks);
}
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#4 (text+ko) ====
@@ -117,12 +117,9 @@
#define TX_START_MIN_DESC (TX_MAX_DESC << 2)
-#ifdef IFNET_MULTIQUEUE
-#define TX_START_MAX_DESC (TX_MAX_DESC << 4)
-#else
+
#define TX_START_MAX_DESC (TX_MAX_DESC << 3) /* maximum number of descriptors
* call to start used per */
-#endif
#define TX_CLEAN_MAX_DESC (TX_MAX_DESC << 4) /* maximum tx descriptors
* to clean per iteration */
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#13 (text+ko) ====
@@ -1691,7 +1691,6 @@
if (d->m) {
if (d->flags & TX_SW_DESC_MAPPED) {
bus_dmamap_unload(q->entry_tag, d->map);
- bus_dmamap_destroy(q->entry_tag, d->map);
d->flags &= ~TX_SW_DESC_MAPPED;
}
if (m_get_priority(d->m) == cidx) {
@@ -1701,7 +1700,9 @@
} else {
printf("pri=%d cidx=%d\n", (int)m_get_priority(d->m), cidx);
}
- }
+ } else
+ q->txq_skipped++;
+
++d;
if (++cidx == q->size) {
cidx = 0;
@@ -2830,6 +2831,12 @@
SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "in_use",
CTLFLAG_RD, &txq->in_use,
0, "#tunneled packet slots in use");
+ SYSCTL_ADD_ULONG(ctx, qspoidlist, OID_AUTO, "frees",
+ CTLFLAG_RD, &txq->txq_frees,
+ "#tunneled packets freed");
+ SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "skipped",
+ CTLFLAG_RD, &txq->txq_skipped,
+ 0, "#tunneled packet descriptors skipped");
SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "stopped_flags",
CTLFLAG_RD, &qs->txq_stopped,
0, "tx queues stopped");
More information about the p4-projects
mailing list