svn commit: r207688 - head/sys/dev/cxgb

Navdeep Parhar np at FreeBSD.org
Wed May 5 22:52:07 UTC 2010


Author: np
Date: Wed May  5 22:52:06 2010
New Revision: 207688
URL: http://svn.freebsd.org/changeset/base/207688

Log:
  Don't ring the tx doorbell for every frame when we know more frames
  will follow.  Adjust the freelist and response queue doorbells too.
  
  Discussed with:	kmacy

Modified:
  head/sys/dev/cxgb/cxgb_adapter.h
  head/sys/dev/cxgb/cxgb_sge.c

Modified: head/sys/dev/cxgb/cxgb_adapter.h
==============================================================================
--- head/sys/dev/cxgb/cxgb_adapter.h	Wed May  5 22:29:54 2010	(r207687)
+++ head/sys/dev/cxgb/cxgb_adapter.h	Wed May  5 22:52:06 2010	(r207688)
@@ -204,6 +204,7 @@ struct sge_fl {
 	uint32_t	cidx;
 	uint32_t	pidx;
 	uint32_t	gen;
+	uint32_t	db_pending;
 	bus_addr_t	phys_addr;
 	uint32_t	cntxt_id;
 	uint32_t	empty;
@@ -232,6 +233,7 @@ struct sge_txq {
 	uint32_t	pidx;
 	uint32_t	gen;
 	uint32_t	unacked;
+	uint32_t	db_pending;
 	struct tx_desc	*desc;
 	struct tx_sw_desc *sdesc;
 	uint32_t	token;

Modified: head/sys/dev/cxgb/cxgb_sge.c
==============================================================================
--- head/sys/dev/cxgb/cxgb_sge.c	Wed May  5 22:29:54 2010	(r207687)
+++ head/sys/dev/cxgb/cxgb_sge.c	Wed May  5 22:52:06 2010	(r207688)
@@ -696,7 +696,7 @@ refill_fl(adapter_t *sc, struct sge_fl *
 	struct refill_fl_cb_arg cb_arg;
 	struct mbuf *m;
 	caddr_t cl;
-	int err, count = 0;
+	int err;
 	
 	cb_arg.error = 0;
 	while (n--) {
@@ -754,12 +754,14 @@ refill_fl(adapter_t *sc, struct sge_fl *
 			d = q->desc;
 		}
 		q->credits++;
-		count++;
+		q->db_pending++;
 	}
 
 done:
-	if (count)
+	if (q->db_pending >= 32) {
+		q->db_pending = 0;
 		t3_write_reg(sc, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+	}
 }
 
 
@@ -810,8 +812,10 @@ __refill_fl(adapter_t *adap, struct sge_
 static __inline void
 __refill_fl_lt(adapter_t *adap, struct sge_fl *fl, int max)
 {
-	if ((fl->size - fl->credits) < max)
-		refill_fl(adap, fl, min(max, fl->size - fl->credits));
+	uint32_t reclaimable = fl->size - fl->credits;
+
+	if (reclaimable > 0)
+		refill_fl(adap, fl, min(max, reclaimable));
 }
 
 /**
@@ -1261,7 +1265,7 @@ make_sgl(struct sg_ent *sgp, bus_dma_seg
  *	When GTS is disabled we unconditionally ring the doorbell.
  */
 static __inline void
-check_ring_tx_db(adapter_t *adap, struct sge_txq *q)
+check_ring_tx_db(adapter_t *adap, struct sge_txq *q, int mustring)
 {
 #if USE_GTS
 	clear_bit(TXQ_LAST_PKT_DB, &q->flags);
@@ -1275,9 +1279,12 @@ check_ring_tx_db(adapter_t *adap, struct
 			     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
 	}
 #else
-	wmb();            /* write descriptors before telling HW */
-	t3_write_reg(adap, A_SG_KDOORBELL,
-		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+	if (mustring || ++q->db_pending >= 32) {
+		wmb();            /* write descriptors before telling HW */
+		t3_write_reg(adap, A_SG_KDOORBELL,
+		    F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+		q->db_pending = 0;
+	}
 #endif
 }
 
@@ -1480,7 +1487,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 		wmb();
 		ETHER_BPF_MTAP(pi->ifp, m0);
 		wr_gen2(txd, txqs.gen);
-		check_ring_tx_db(sc, txq);
+		check_ring_tx_db(sc, txq, 0);
 		return (0);		
 	} else if (tso_info) {
 		int eth_type;
@@ -1543,7 +1550,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 			wmb();
 			ETHER_BPF_MTAP(pi->ifp, m0);
 			wr_gen2(txd, txqs.gen);
-			check_ring_tx_db(sc, txq);
+			check_ring_tx_db(sc, txq, 0);
 			m_freem(m0);
 			return (0);
 		}
@@ -1574,7 +1581,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 			wmb();
 			ETHER_BPF_MTAP(pi->ifp, m0);
 			wr_gen2(txd, txqs.gen);
-			check_ring_tx_db(sc, txq);
+			check_ring_tx_db(sc, txq, 0);
 			m_freem(m0);
 			return (0);
 		}
@@ -1593,7 +1600,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 	wr_lo = htonl(V_WR_TID(txq->token));
 	write_wr_hdr_sgl(ndesc, txd, &txqs, txq, sgl, flits,
 	    sgl_flits, wr_hi, wr_lo);
-	check_ring_tx_db(sc, txq);
+	check_ring_tx_db(sc, txq, 0);
 
 	return (0);
 }
@@ -1643,7 +1650,6 @@ cxgb_start_locked(struct sge_qset *qs)
 {
 	struct mbuf *m_head = NULL;
 	struct sge_txq *txq = &qs->txq[TXQ_ETH];
-	int in_use_init = txq->in_use;
 	struct port_info *pi = qs->port;
 	struct ifnet *ifp = pi->ifp;
 
@@ -1655,8 +1661,7 @@ cxgb_start_locked(struct sge_qset *qs)
 		return;
 	}
 	TXQ_LOCK_ASSERT(qs);
-	while ((txq->in_use - in_use_init < TX_START_MAX_DESC) &&
-	    !TXQ_RING_EMPTY(qs) && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+	while (!TXQ_RING_EMPTY(qs) && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
 	    pi->link_config.link_ok) {
 		reclaim_completed_tx(qs, cxgb_tx_reclaim_threshold, TXQ_ETH);
 
@@ -1674,6 +1679,10 @@ cxgb_start_locked(struct sge_qset *qs)
 
 		m_head = NULL;
 	}
+
+	if (txq->db_pending)
+		check_ring_tx_db(pi->adapter, txq, 1);
+
 	if (!TXQ_RING_EMPTY(qs) && callout_pending(&txq->txq_timer) == 0 &&
 	    pi->link_config.link_ok)
 		callout_reset_on(&txq->txq_timer, 1, cxgb_tx_timeout,
@@ -1707,6 +1716,9 @@ cxgb_transmit_locked(struct ifnet *ifp, 
 			    (error = drbr_enqueue(ifp, br, m)) != 0) 
 				return (error);
 		} else {
+			if (txq->db_pending)
+				check_ring_tx_db(pi->adapter, txq, 1);
+
 			/*
 			 * We've bypassed the buf ring so we need to update
 			 * the stats directly
@@ -2354,7 +2366,7 @@ again:	reclaim_completed_tx(qs, 16, TXQ_
 	TXQ_UNLOCK(qs);
 
 	write_ofld_wr(adap, m, q, pidx, gen, ndesc, segs, nsegs);
-	check_ring_tx_db(adap, q);
+	check_ring_tx_db(adap, q, 1);
 	return (0);
 }
 
@@ -3033,7 +3045,7 @@ process_responses(adapter_t *adap, struc
 			r = rspq->desc;
 		}
 
-		if (++rspq->credits >= (rspq->size / 4)) {
+		if (++rspq->credits >= 64) {
 			refill_rspq(adap, rspq, rspq->credits);
 			rspq->credits = 0;
 		}


More information about the svn-src-all mailing list