From owner-svn-src-head@FreeBSD.ORG  Wed Apr 20 23:20:00 2011
Return-Path: <owner-svn-src-head@FreeBSD.ORG>
Delivered-To: svn-src-head@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 9AAED106564A;
	Wed, 20 Apr 2011 23:20:00 +0000 (UTC) (envelope-from np@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c])
	by mx1.freebsd.org (Postfix) with ESMTP id 7DBFB8FC16;
	Wed, 20 Apr 2011 23:20:00 +0000 (UTC)
Received: from svn.freebsd.org (localhost [127.0.0.1])
	by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p3KNK0PT070583;
	Wed, 20 Apr 2011 23:20:00 GMT (envelope-from np@svn.freebsd.org)
Received: (from np@localhost)
	by svn.freebsd.org (8.14.3/8.14.3/Submit) id p3KNK0r8070581;
	Wed, 20 Apr 2011 23:20:00 GMT (envelope-from np@svn.freebsd.org)
Message-Id: <201104202320.p3KNK0r8070581@svn.freebsd.org>
From: Navdeep Parhar <np@FreeBSD.org>
Date: Wed, 20 Apr 2011 23:20:00 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
	svn-src-head@freebsd.org
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cc: 
Subject: svn commit: r220905 - head/sys/dev/cxgbe
X-BeenThere: svn-src-head@freebsd.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: SVN commit messages for the src tree for head/-current
	<svn-src-head.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-head>,
	<mailto:svn-src-head-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-head>
List-Post: <mailto:svn-src-head@freebsd.org>
List-Help: <mailto:svn-src-head-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-head>,
	<mailto:svn-src-head-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Wed, 20 Apr 2011 23:20:00 -0000

Author: np
Date: Wed Apr 20 23:20:00 2011
New Revision: 220905
URL: http://svn.freebsd.org/changeset/base/220905

Log:
  Ring the freelist doorbell from within refill_fl.  While here, fix a bug
  that could have allowed the hardware pidx to reach the cidx even though
  the freelist isn't empty.  (Haven't actually seen this but it was there
  waiting to happen..)
  
  MFC after:	1 week

Modified:
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Wed Apr 20 23:17:17 2011	(r220904)
+++ head/sys/dev/cxgbe/t4_sge.c	Wed Apr 20 23:20:00 2011	(r220905)
@@ -114,7 +114,7 @@ static void oneseg_dma_callback(void *, 
 static inline bool is_new_response(const struct sge_iq *, struct rsp_ctrl **);
 static inline void iq_next(struct sge_iq *);
 static inline void ring_fl_db(struct adapter *, struct sge_fl *);
-static void refill_fl(struct sge_fl *, int);
+static void refill_fl(struct adapter *, struct sge_fl *, int, int);
 static int alloc_fl_sdesc(struct sge_fl *);
 static void free_fl_sdesc(struct sge_fl *);
 static int alloc_tx_maps(struct sge_txq *);
@@ -763,9 +763,7 @@ t4_eth_rx(void *arg)
 		FL_LOCK(fl);
 		fl->needed += i;
 		if (fl->needed >= 32)
-			refill_fl(fl, 64);
-		if (fl->pending >= 32)
-			ring_fl_db(sc, fl);
+			refill_fl(sc, fl, 64, 32);
 		FL_UNLOCK(fl);
 
 nextdesc:	ndescs++;
@@ -793,9 +791,7 @@ nextdesc:	ndescs++;
 
 	FL_LOCK(fl);
 	if (fl->needed >= 32)
-		refill_fl(fl, 128);
-	if (fl->pending >= 8)
-		ring_fl_db(sc, fl);
+		refill_fl(sc, fl, 128, 8);
 	FL_UNLOCK(fl);
 }
 
@@ -1179,7 +1175,7 @@ alloc_iq_fl(struct port_info *pi, struct
 			    rc);
 			return (rc);
 		}
-		fl->needed = fl->cap - 1; /* one less to avoid cidx = pidx */
+		fl->needed = fl->cap;
 
 		c.iqns_to_fl0congen =
 		    htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE));
@@ -1222,9 +1218,7 @@ alloc_iq_fl(struct port_info *pi, struct
 		sc->sge.eqmap[cntxt_id] = (void *)fl;
 
 		FL_LOCK(fl);
-		refill_fl(fl, -1);
-		if (fl->pending >= 8)
-			ring_fl_db(sc, fl);
+		refill_fl(sc, fl, -1, 8);
 		FL_UNLOCK(fl);
 	}
 
@@ -1692,24 +1686,31 @@ iq_next(struct sge_iq *iq)
 	}
 }
 
+#define FL_HW_IDX(x) ((x) >> 3)
 static inline void
 ring_fl_db(struct adapter *sc, struct sge_fl *fl)
 {
 	int ndesc = fl->pending / 8;
 
-	/* Caller responsible for ensuring there's something useful to do */
-	KASSERT(ndesc > 0, ("%s called with no useful work to do.", __func__));
+	if (FL_HW_IDX(fl->pidx) == FL_HW_IDX(fl->cidx))
+		ndesc--;	/* hold back one credit */
+
+	if (ndesc <= 0)
+		return;		/* nothing to do */
 
 	wmb();
 
 	t4_write_reg(sc, MYPF_REG(A_SGE_PF_KDOORBELL), F_DBPRIO |
 	    V_QID(fl->cntxt_id) | V_PIDX(ndesc));
-
-	fl->pending &= 7;
+	fl->pending -= ndesc * 8;
 }
 
+/*
+ * Fill up the freelist by upto nbufs and ring its doorbell if the number of
+ * buffers ready to be handed to the hardware >= dbthresh.
+ */
 static void
-refill_fl(struct sge_fl *fl, int nbufs)
+refill_fl(struct adapter *sc, struct sge_fl *fl, int nbufs, int dbthresh)
 {
 	__be64 *d = &fl->desc[fl->pidx];
 	struct fl_sdesc *sd = &fl->sdesc[fl->pidx];
@@ -1800,6 +1801,9 @@ recycled:
 			d = fl->desc;
 		}
 	}
+
+	if (fl->pending >= dbthresh)
+		ring_fl_db(sc, fl);
 }
 
 static int