Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Aug 2007 22:02:12 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 125462 for review
Message-ID:  <200708202202.l7KM2Crd002688@repoman.freebsd.org>

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

Change 125462 by kmacy@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");



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