Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Oct 2013 06:50:56 -0400
From:      Randall Stewart <rrs@lakerest.net>
To:        net@freebsd.org
Subject:   MQ Patch.
Message-ID:  <40948D79-E890-4360-A3F2-BEC34A389C7E@lakerest.net>

next in thread | raw e-mail | index | archive | help

--Apple-Mail=_49C5FDEE-E4BA-44F6-8F6A-342853C67ED4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=windows-1252

Hi:

As discussed at vBSDcon with andre/emaste and gnn, I am sending
this patch out to all of you ;-)

I have previously sent it to gnn, andre, jhb, rwatson, and several other
of the usual suspects (as gnn put it) and received dead silence.

What does this patch do?

Well it add the ability to do multi-queue at the driver level. Basically
any driver that uses the new interface gets under it N queues (default
is 8) for each physical transmit ring it has. The driver picks up=20
its queue 0 first, then queue 1 .. up to the max.

This allows you to prioritize packets. Also in here is the start of some
work I will be doing for AQM.. think either Pi or Codel ;-)

Right now thats pretty simple and just (in a few drivers) as the ability
to limit the amount of data on the ring=85 which can help reduce buffer
bloat. That needs to be refined into a lot more.

This work is donated by Adara Networks and has been discussed in several
of the past vendor summits.

I plan on committing this before the IETF unless I hear major =
objections.

Please have a look ;-)

Best wishes

R


--Apple-Mail=_49C5FDEE-E4BA-44F6-8F6A-342853C67ED4
Content-Disposition: attachment;
	filename=patch_mq.txt
Content-Type: text/plain;
	x-unix-mode=0644;
	name="patch_mq.txt"
Content-Transfer-Encoding: quoted-printable

Index: sys/conf/files
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/conf/files	(revision 257322)
+++ sys/conf/files	(working copy)
@@ -3062,6 +3062,7 @@ net/bridgestp.c			optional bridge =
| if_bridge
 net/flowtable.c			optional flowtable inet | =
flowtable inet6
 net/ieee8023ad_lacp.c		optional lagg
 net/if.c			standard
+net/drbr.c			standard
 net/if_arcsubr.c		optional arcnet
 net/if_atmsubr.c		optional atm
 net/if_bridge.c			optional bridge inet | if_bridge =
inet
Index: sys/dev/bxe/bxe.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/bxe/bxe.c	(revision 257322)
+++ sys/dev/bxe/bxe.c	(working copy)
@@ -5935,10 +5935,11 @@ bxe_tx_mq_start_locked(struct bxe_softc    *sc,
                        struct bxe_fastpath *fp,
                        struct mbuf         *m)
 {
-    struct buf_ring *tx_br =3D fp->tx_br;
+    struct drbr_ring *tx_br =3D fp->tx_br;
     struct mbuf *next;
     int depth, rc, tx_count;
     uint16_t tx_bd_avail;
+    uint8_t qused;
=20
     rc =3D tx_count =3D 0;
=20
@@ -5955,25 +5956,16 @@ bxe_tx_mq_start_locked(struct bxe_softc    *sc,
=20
     BXE_FP_TX_LOCK_ASSERT(fp);
=20
-    if (m =3D=3D NULL) {
-        /* no new work, check for pending frames */
-        next =3D drbr_dequeue(ifp, tx_br);
-    } else if (drbr_needs_enqueue(ifp, tx_br)) {
-        /* have both new and pending work, maintain packet order */
-        rc =3D drbr_enqueue(ifp, tx_br, m);
-        if (rc !=3D 0) {
-            fp->eth_q_stats.tx_soft_errors++;
-            goto bxe_tx_mq_start_locked_exit;
-        }
-        next =3D drbr_dequeue(ifp, tx_br);
-    } else {
-        /* new work only and nothing pending */
-        next =3D m;
+    if (m !=3D NULL) {
+	    rc =3D drbr_enqueue(ifp, tx_br, m);
+	    if (rc !=3D 0) {
+		    fp->eth_q_stats.tx_soft_errors++;
+		    goto bxe_tx_mq_start_locked_exit;
+	    }
     }
=20
     /* keep adding entries while there are frames to send */
-    while (next !=3D NULL) {
-
+    while ((next =3D drbr_peek(ifp, fp->tx_br, &qused)) !=3D NULL) {
         /* the mbuf now belongs to us */
         fp->eth_q_stats.mbuf_alloc_tx++;
=20
@@ -5985,19 +5977,22 @@ bxe_tx_mq_start_locked(struct bxe_softc    *sc,
         rc =3D bxe_tx_encap(fp, &next);
         if (__predict_false(rc !=3D 0)) {
             fp->eth_q_stats.tx_encap_failures++;
-            if (next !=3D NULL) {
-                /* mark the TX queue as full and save the frame */
-                ifp->if_drv_flags |=3D IFF_DRV_OACTIVE;
-                /* XXX this may reorder the frame */
-                rc =3D drbr_enqueue(ifp, tx_br, next);
-                fp->eth_q_stats.mbuf_alloc_tx--;
-                fp->eth_q_stats.tx_frames_deferred++;
-            }
-
+	    if (next =3D=3D NULL) {
+		    drbr_advance(ifp, fp->tx_br, qused);
+	    } else {
+		    drbr_putback(ifp, fp->tx_br, next, qused);
+		    /*
+		     * Mark the TX queue as full and save
+		     * the frame.
+		     */
+		    ifp->if_drv_flags |=3D IFF_DRV_OACTIVE;
+		    fp->eth_q_stats.mbuf_alloc_tx--;
+		    fp->eth_q_stats.tx_frames_deferred++;
+	    }
             /* stop looking for more work */
             break;
         }
-
+	drbr_advance(ifp, fp->tx_br, qused);
         /* the transmit frame was enqueued successfully */
         tx_count++;
=20
@@ -6078,7 +6073,6 @@ bxe_mq_flush(struct ifnet *ifp)
 {
     struct bxe_softc *sc =3D ifp->if_softc;
     struct bxe_fastpath *fp;
-    struct mbuf *m;
     int i;
=20
     for (i =3D 0; i < sc->num_queues; i++) {
@@ -6093,9 +6087,7 @@ bxe_mq_flush(struct ifnet *ifp)
         if (fp->tx_br !=3D NULL) {
             BLOGD(sc, DBG_LOAD, "Clearing fp[%02d] buf_ring\n", =
fp->index);
             BXE_FP_TX_LOCK(fp);
-            while ((m =3D buf_ring_dequeue_sc(fp->tx_br)) !=3D NULL) {
-                m_freem(m);
-            }
+	    drbr_flush(ifp, fp->tx_br);
             BXE_FP_TX_UNLOCK(fp);
         }
     }
@@ -6496,12 +6488,9 @@ bxe_free_fp_buffers(struct bxe_softc *sc)
=20
 #if __FreeBSD_version >=3D 800000
         if (fp->tx_br !=3D NULL) {
-            struct mbuf *m;
             /* just in case bxe_mq_flush() wasn't called */
-            while ((m =3D buf_ring_dequeue_sc(fp->tx_br)) !=3D NULL) {
-                m_freem(m);
-            }
-            buf_ring_free(fp->tx_br, M_DEVBUF);
+	    drbr_flush(sc->ifnet, fp->tx_br);
+            drbr_free(fp->tx_br, M_DEVBUF);
             fp->tx_br =3D NULL;
         }
 #endif
@@ -6762,8 +6751,7 @@ bxe_alloc_fp_buffers(struct bxe_softc *sc)
         fp =3D &sc->fp[i];
=20
 #if __FreeBSD_version >=3D 800000
-        fp->tx_br =3D buf_ring_alloc(BXE_BR_SIZE, M_DEVBUF,
-                                   M_DONTWAIT, &fp->tx_mtx);
+        fp->tx_br =3D drbr_alloc(M_DEVBUF, M_DONTWAIT, &fp->tx_mtx);
         if (fp->tx_br =3D=3D NULL) {
             BLOGE(sc, "buf_ring alloc fail for fp[%02d]\n", i);
             goto bxe_alloc_fp_buffers_error;
Index: sys/dev/bxe/bxe.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/bxe/bxe.h	(revision 257322)
+++ sys/dev/bxe/bxe.h	(working copy)
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_vlan_var.h>
 #include <net/zlib.h>
 #include <net/bpf.h>
+#include <net/drbr.h>
=20
 #include <netinet/in.h>
 #include <netinet/ip.h>
@@ -734,7 +735,7 @@ struct bxe_fastpath {
=20
 #if __FreeBSD_version >=3D 800000
 #define BXE_BR_SIZE 4096
-    struct buf_ring *tx_br;
+    struct drbr_ring *tx_br;
 #endif
 }; /* struct bxe_fastpath */
=20
Index: sys/dev/cesa/cesa.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cesa/cesa.c	(revision 257322)
+++ sys/dev/cesa/cesa.c	(working copy)
@@ -995,11 +995,17 @@ cesa_attach(device_t dev)
 	sc->sc_dev =3D dev;
=20
 	/* Check if CESA peripheral device has power turned on */
+#if defined(SOC_MV_KIRKWOOD)
+	if (soc_power_ctrl_get(CPU_PM_CTRL_CRYPTO) =3D=3D =
CPU_PM_CTRL_CRYPTO) {
+		device_printf(dev, "not powered on\n");
+		return (ENXIO);
+	}
+#else
 	if (soc_power_ctrl_get(CPU_PM_CTRL_CRYPTO) !=3D =
CPU_PM_CTRL_CRYPTO) {
 		device_printf(dev, "not powered on\n");
 		return (ENXIO);
 	}
-
+#endif
 	soc_id(&d, &r);
=20
 	switch (d) {
Index: sys/dev/cxgb/cxgb_adapter.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgb/cxgb_adapter.h	(revision 257322)
+++ sys/dev/cxgb/cxgb_adapter.h	(working copy)
@@ -252,7 +252,7 @@ struct sge_txq {
 	bus_dma_tag_t   entry_tag;
 	struct mbuf_head sendq;
=20
-	struct buf_ring *txq_mr;
+	struct drbr_ring *txq_mr;
 	struct ifaltq	*txq_ifq;
 	struct callout	txq_timer;
 	struct callout	txq_watchdog;
Index: sys/dev/cxgb/cxgb_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgb/cxgb_main.c	(revision 257322)
+++ sys/dev/cxgb/cxgb_main.c	(working copy)
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
=20
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -2361,7 +2362,7 @@ cxgb_tick_handler(void *arg, int count)
=20
 		drops =3D 0;
 		for (j =3D pi->first_qset; j < pi->first_qset + =
pi->nqsets; j++)
-			drops +=3D =
sc->sge.qs[j].txq[TXQ_ETH].txq_mr->br_drops;
+			drops +=3D =
drbr_get_dropcnt(sc->sge.qs[j].txq[TXQ_ETH].txq_mr);
 		ifp->if_snd.ifq_drops =3D drops;
=20
 		ifp->if_oerrors =3D
Index: sys/dev/cxgb/cxgb_sge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgb/cxgb_sge.c	(revision 257322)
+++ sys/dev/cxgb/cxgb_sge.c	(working copy)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <net/bpf.h>=09
 #include <net/ethernet.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
=20
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -1684,7 +1685,7 @@ cxgb_transmit_locked(struct ifnet *ifp, struct sge
 {
 	struct port_info *pi =3D qs->port;
 	struct sge_txq *txq =3D &qs->txq[TXQ_ETH];
-	struct buf_ring *br =3D txq->txq_mr;
+	struct drbr_ring *br =3D txq->txq_mr;
 	int error, avail;
=20
 	avail =3D txq->size - txq->in_use;
@@ -1980,7 +1981,7 @@ t3_free_qset(adapter_t *sc, struct sge_qset *q)
 =09
 	reclaim_completed_tx(q, 0, TXQ_ETH);
 	if (q->txq[TXQ_ETH].txq_mr !=3D NULL)=20
-		buf_ring_free(q->txq[TXQ_ETH].txq_mr, M_DEVBUF);
+		drbr_free(q->txq[TXQ_ETH].txq_mr, M_DEVBUF);
 	if (q->txq[TXQ_ETH].txq_ifq !=3D NULL) {
 		ifq_delete(q->txq[TXQ_ETH].txq_ifq);
 		free(q->txq[TXQ_ETH].txq_ifq, M_DEVBUF);
@@ -2430,8 +2431,8 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int npo
 	q->port =3D pi;
 	q->adap =3D sc;
=20
-	if ((q->txq[TXQ_ETH].txq_mr =3D =
buf_ring_alloc(cxgb_txq_buf_ring_size,
-	    M_DEVBUF, M_WAITOK, &q->lock)) =3D=3D NULL) {
+	if ((q->txq[TXQ_ETH].txq_mr =3D drbr_alloc(M_DEVBUF, M_WAITOK,=20=

+	    &q->lock)) =3D=3D NULL) {
 		device_printf(sc->dev, "failed to allocate mbuf =
ring\n");
 		goto err;
 	}
@@ -3523,9 +3524,9 @@ t3_add_configured_sysctls(adapter_t *sc)
 			    CTLTYPE_STRING | CTLFLAG_RD, &qs->rspq,
 			    0, t3_dump_rspq, "A", "dump of the response =
queue");
=20
-			SYSCTL_ADD_UQUAD(ctx, txqpoidlist, OID_AUTO, =
"dropped",
+/* RRS FIXME    	SYSCTL_ADD_UQUAD(ctx, txqpoidlist, OID_AUTO, =
"dropped",
 			    CTLFLAG_RD, =
&qs->txq[TXQ_ETH].txq_mr->br_drops,
-			    "#tunneled packets dropped");
+			    "#tunneled packets dropped");*/
 			SYSCTL_ADD_UINT(ctx, txqpoidlist, OID_AUTO, =
"sendqlen",
 			    CTLFLAG_RD, &qs->txq[TXQ_ETH].sendq.qlen,
 			    0, "#tunneled packets waiting to be sent");
Index: sys/dev/cxgbe/adapter.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgbe/adapter.h	(revision 257322)
+++ sys/dev/cxgbe/adapter.h	(working copy)
@@ -419,7 +419,7 @@ struct sge_txq {
=20
 	struct ifnet *ifp;	/* the interface this txq belongs to */
 	bus_dma_tag_t tx_tag;	/* tag for transmit buffers */
-	struct buf_ring *br;	/* tx buffer ring */
+	struct drbr_ring *br;	/* tx buffer ring */
 	struct tx_sdesc *sdesc;	/* KVA of software descriptor ring */
 	struct mbuf *m;		/* held up due to temporary resource =
shortage */
=20
Index: sys/dev/cxgbe/t4_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgbe/t4_main.c	(revision 257322)
+++ sys/dev/cxgbe/t4_main.c	(working copy)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/if_dl.h>
+#include <net/drbr.h>
 #include <net/if_vlan_var.h>
 #if defined(__i386__) || defined(__amd64__)
 #include <vm/vm.h>
@@ -1254,7 +1255,7 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m)
 	struct port_info *pi =3D ifp->if_softc;
 	struct adapter *sc =3D pi->adapter;
 	struct sge_txq *txq =3D &sc->sge.txq[pi->first_txq];
-	struct buf_ring *br;
+	struct drbr_ring *br;
 	int rc;
=20
 	M_ASSERTPKTHDR(m);
@@ -1295,7 +1296,7 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m)
 	 */
=20
 	TXQ_LOCK_ASSERT_OWNED(txq);
-	if (drbr_needs_enqueue(ifp, br) || txq->m) {
+	if (txq->m) {
=20
 		/* Queued for transmission. */
=20
@@ -1321,7 +1322,6 @@ cxgbe_qflush(struct ifnet *ifp)
 	struct port_info *pi =3D ifp->if_softc;
 	struct sge_txq *txq;
 	int i;
-	struct mbuf *m;
=20
 	/* queues do not exist if !PORT_INIT_DONE. */
 	if (pi->flags & PORT_INIT_DONE) {
@@ -1329,8 +1329,7 @@ cxgbe_qflush(struct ifnet *ifp)
 			TXQ_LOCK(txq);
 			m_freem(txq->m);
 			txq->m =3D NULL;
-			while ((m =3D buf_ring_dequeue_sc(txq->br)) !=3D =
NULL)
-				m_freem(m);
+			drbr_flush(ifp, txq->br);
 			TXQ_UNLOCK(txq);
 		}
 	}
@@ -4042,7 +4041,7 @@ cxgbe_tick(void *arg)
=20
 	drops =3D s->tx_drop;
 	for_each_txq(pi, i, txq)
-		drops +=3D txq->br->br_drops;
+		drops +=3D drbr_get_dropcnt(txq->br);
 	ifp->if_snd.ifq_drops =3D drops;
=20
 	ifp->if_oerrors =3D s->tx_error_frames;
@@ -6493,7 +6492,7 @@ sysctl_wcwr_stats(SYSCTL_HANDLER_ARGS)
 static inline void
 txq_start(struct ifnet *ifp, struct sge_txq *txq)
 {
-	struct buf_ring *br;
+	struct drbr_ring *br;
 	struct mbuf *m;
=20
 	TXQ_LOCK_ASSERT_OWNED(txq);
@@ -7509,7 +7508,6 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, cadd
 				txq->txpkt_wrs =3D 0;
 				txq->txpkts_wrs =3D 0;
 				txq->txpkts_pkts =3D 0;
-				txq->br->br_drops =3D 0;
 				txq->no_dmamap =3D 0;
 				txq->no_desc =3D 0;
 			}
Index: sys/dev/cxgbe/t4_sge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/cxgbe/t4_sge.c	(revision 257322)
+++ sys/dev/cxgbe/t4_sge.c	(working copy)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
@@ -1844,9 +1845,10 @@ t4_eth_tx(struct ifnet *ifp, struct sge_txq *txq,
 	struct port_info *pi =3D (void *)ifp->if_softc;
 	struct adapter *sc =3D pi->adapter;
 	struct sge_eq *eq =3D &txq->eq;
-	struct buf_ring *br =3D txq->br;
+	struct drbr_ring *br =3D txq->br;
 	struct mbuf *next;
 	int rc, coalescing, can_reclaim;
+	uint8_t qused;
 	struct txpkts txpkts;
 	struct sgl sgl;
=20
@@ -1873,8 +1875,7 @@ t4_eth_tx(struct ifnet *ifp, struct sge_txq *txq,
=20
 	if (__predict_false(eq->flags & EQ_DOOMED)) {
 		m_freem(m);
-		while ((m =3D buf_ring_dequeue_sc(txq->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, br);
 		return (ENETDOWN);
 	}
=20
@@ -1889,7 +1890,7 @@ t4_eth_tx(struct ifnet *ifp, struct sge_txq *txq,
 		next =3D m->m_nextpkt;
 		m->m_nextpkt =3D NULL;
=20
-		if (next || buf_ring_peek(br))
+		if (next || drbr_peek(ifp, br, &qused))
 			coalescing =3D 1;
=20
 		rc =3D get_pkt_sgl(txq, &m, &sgl, coalescing);
@@ -2936,7 +2937,7 @@ alloc_txq(struct port_info *pi, struct sge_txq *tx
=20
 	txq->sdesc =3D malloc(eq->cap * sizeof(struct tx_sdesc), =
M_CXGBE,
 	    M_ZERO | M_WAITOK);
-	txq->br =3D buf_ring_alloc(eq->qsize, M_CXGBE, M_WAITOK, =
&eq->eq_lock);
+	txq->br =3D drbr_alloc(M_CXGBE, M_WAITOK, &eq->eq_lock);
=20
 	rc =3D bus_dma_tag_create(sc->dmat, 1, 0, BUS_SPACE_MAXADDR,
 	    BUS_SPACE_MAXADDR, NULL, NULL, 64 * 1024, TX_SGL_SEGS,
@@ -2991,8 +2992,8 @@ alloc_txq(struct port_info *pi, struct sge_txq *tx
 	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "txpkts_pkts", =
CTLFLAG_RD,
 	    &txq->txpkts_pkts, "# of frames tx'd using txpkts work =
requests");
=20
-	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "br_drops", =
CTLFLAG_RD,
-	    &txq->br->br_drops, "# of drops in the buf_ring for this =
queue");
+/*	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "br_drops", =
CTLFLAG_RD,
+	&txq->br->br_drops, "# of drops in the buf_ring for this =
queue");*/
 	SYSCTL_ADD_UINT(&pi->ctx, children, OID_AUTO, "no_dmamap", =
CTLFLAG_RD,
 	    &txq->no_dmamap, 0, "# of times txq ran out of DMA maps");
 	SYSCTL_ADD_UINT(&pi->ctx, children, OID_AUTO, "no_desc", =
CTLFLAG_RD,
@@ -3021,7 +3022,7 @@ free_txq(struct port_info *pi, struct sge_txq *txq
 	if (txq->txmaps.maps)
 		t4_free_tx_maps(&txq->txmaps, txq->tx_tag);
=20
-	buf_ring_free(txq->br, M_CXGBE);
+	drbr_free(txq->br, M_CXGBE);
=20
 	if (txq->tx_tag)
 		bus_dma_tag_destroy(txq->tx_tag);
Index: sys/dev/e1000/if_em.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/e1000/if_em.c	(revision 257322)
+++ sys/dev/e1000/if_em.c	(working copy)
@@ -67,6 +67,7 @@
 #include <net/if_arp.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
+#include <net/drbr.h>
=20
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
@@ -273,6 +274,9 @@ static int 	em_is_valid_ether_addr(u8 *);
 static int	em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
 static void	em_add_int_delay_sysctl(struct adapter *, const char *,
 		    const char *, struct em_int_delay_info *, int, int);
+static void 	em_max_bytes(struct ifnet *, uint64_t max);
+static struct drbr_ring *em_get_ring(struct ifnet *ifp, int num);
+static int	em_ring_query(struct ifnet *ifp, struct mbuf *);
 /* Management and WOL Support */
 static void	em_init_manageability(struct adapter *);
 static void	em_release_manageability(struct adapter *);
@@ -897,7 +901,38 @@ em_resume(device_t dev)
 	return bus_generic_resume(dev);
 }
=20
+void
+em_max_bytes(struct ifnet *ifp, uint64_t max)
+{
+	struct adapter	*adapter =3D ifp->if_softc;
+	adapter->ring_bytes_max =3D max;
+}
=20
+struct drbr_ring *
+em_get_ring(struct ifnet *ifp, int num)
+{
+	struct adapter	*adapter =3D ifp->if_softc;
+	struct tx_ring	*txr;
+	if (num >=3D adapter->num_queues) {
+		return (NULL);
+	}
+	if (adapter->tx_rings) {
+		txr =3D &adapter->tx_rings[num];
+		return (txr->br);
+	} else {
+		return (NULL);
+	}
+}
+=20
+int
+em_ring_query(struct ifnet *ifp, struct mbuf *m)
+{
+	struct adapter *adapter =3D ifp->if_softc;
+	struct tx_ring	*txr;
+	txr =3D &adapter->tx_rings[0];
+	return(drbr_is_on_ring(txr->br, m));
+}
+
 #ifdef EM_MULTIQUEUE
 /*********************************************************************
  *  Multiqueue Transmit routines=20
@@ -913,6 +948,7 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ri
 	struct adapter  *adapter =3D txr->adapter;
         struct mbuf     *next;
         int             err =3D 0, enq =3D 0;
+	uint8_t qused;
=20
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=3D=

 	    IFF_DRV_RUNNING || adapter->link_active =3D=3D 0) {
@@ -929,20 +965,26 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ri
 	}=20
=20
 	/* Process the queue */
-	while ((next =3D drbr_peek(ifp, txr->br)) !=3D NULL) {
+	while ((next =3D drbr_peek(ifp, txr->br, &qused)) !=3D NULL) {
 		if ((err =3D em_xmit(txr, &next)) !=3D 0) {
 			if (next =3D=3D NULL)
-				drbr_advance(ifp, txr->br);
+				drbr_advance(ifp, txr->br, qused);
 			else=20
-				drbr_putback(ifp, txr->br, next);
+				drbr_putback(ifp, txr->br, next, qused);
 			break;
 		}
-		drbr_advance(ifp, txr->br);
+		drbr_advance(ifp, txr->br, qused);
+ 		atomic_add_long(&txr->bytes_on_ring,=20
+ 			(uint64_t)next->m_pkthdr.len);
 		enq++;
 		ifp->if_obytes +=3D next->m_pkthdr.len;
 		if (next->m_flags & M_MCAST)
 			ifp->if_omcasts++;
 		ETHER_BPF_MTAP(ifp, next);
+		if (adapter->ring_bytes_max &&=20
+		    (txr->bytes_on_ring >=3D adapter->ring_bytes_max)) {
+			break;
+		}
 		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) =3D=3D 0)
                         break;
 	}
@@ -991,8 +1033,7 @@ em_qflush(struct ifnet *ifp)
=20
 	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
 		EM_TX_LOCK(txr);
-		while ((m =3D buf_ring_dequeue_sc(txr->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, txr->br);
 		EM_TX_UNLOCK(txr);
 	}
 	if_qflush(ifp);
@@ -2984,6 +3025,9 @@ em_setup_interface(device_t dev, struct adapter *a
 	ifp->if_softc =3D adapter;
 	ifp->if_flags =3D IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl =3D em_ioctl;
+	ifp->if_maxbytes =3D em_max_bytes;
+	ifp->if_getdrbr_ring =3D em_get_ring;
+	ifp->if_mbuf_on_ring =3D em_ring_query;
 #ifdef EM_MULTIQUEUE
 	/* Multiqueue stack interface */
 	ifp->if_transmit =3D em_mq_start;
@@ -3222,7 +3266,7 @@ em_allocate_queues(struct adapter *adapter)
         	}
 #if __FreeBSD_version >=3D 800000
 		/* Allocate a buf ring */
-		txr->br =3D buf_ring_alloc(4096, M_DEVBUF,
+		txr->br =3D drbr_alloc(M_DEVBUF,
 		    M_WAITOK, &txr->tx_mtx);
 #endif
 	}
@@ -3272,7 +3316,7 @@ err_tx_desc:
 	free(adapter->rx_rings, M_DEVBUF);
 rx_fail:
 #if __FreeBSD_version >=3D 800000
-	buf_ring_free(txr->br, M_DEVBUF);
+	drbr_free(txr->br, M_DEVBUF);
 #endif
 	free(adapter->tx_rings, M_DEVBUF);
 fail:
@@ -3396,6 +3440,7 @@ em_setup_transmit_ring(struct tx_ring *txr)
=20
 	/* Set number of descriptors available */
 	txr->tx_avail =3D adapter->num_tx_desc;
+	txr->bytes_on_ring =3D 0;
 	txr->queue_status =3D EM_QUEUE_IDLE;
=20
 	/* Clear checksum offload context. */
@@ -3579,7 +3624,7 @@ em_free_transmit_buffers(struct tx_ring *txr)
 	}
 #if __FreeBSD_version >=3D 800000
 	if (txr->br !=3D NULL)
-		buf_ring_free(txr->br, M_DEVBUF);
+		drbr_free(txr->br, M_DEVBUF);
 #endif
 	if (txr->tx_buffers !=3D NULL) {
 		free(txr->tx_buffers, M_DEVBUF);
@@ -3877,6 +3922,8 @@ em_txeof(struct tx_ring *txr)
 			++processed;
=20
 			if (tx_buffer->m_head) {
+				=
atomic_subtract_long(&txr->bytes_on_ring,
+						     =
(u_long)tx_buffer->m_head->m_pkthdr.len);
 				bus_dmamap_sync(txr->txtag,
 				    tx_buffer->map,
 				    BUS_DMASYNC_POSTWRITE);
@@ -5329,7 +5376,7 @@ em_add_hw_stats(struct adapter *adapter)
 		queue_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, =
namebuf,
 					    CTLFLAG_RD, NULL, "Queue =
Name");
 		queue_list =3D SYSCTL_CHILDREN(queue_node);
-
+		drbr_add_sysctl_stats(dev, queue_list, txr->br);
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head",=20=

 				CTLTYPE_UINT | CTLFLAG_RD, adapter,
 				E1000_TDH(txr->me),
Index: sys/dev/e1000/if_em.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/e1000/if_em.h	(revision 257322)
+++ sys/dev/e1000/if_em.h	(working copy)
@@ -298,8 +298,9 @@ struct tx_ring {
 	u8			last_hw_tucso;
 	u8			last_hw_tucss;
 #if __FreeBSD_version >=3D 800000
-	struct buf_ring         *br;
+	struct drbr_ring        *br;
 #endif
+	volatile u_long		bytes_on_ring;
 	/* Interrupt resources */
         bus_dma_tag_t           txtag;
 	void                    *tag;
@@ -346,6 +347,7 @@ struct rx_ring {
 /* Our adapter structure */
 struct adapter {
 	struct ifnet	*ifp;
+	uint64_t	ring_bytes_max;
 	struct e1000_hw	hw;
=20
 	/* FreeBSD operating-system-specific structures. */
Index: sys/dev/e1000/if_igb.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/e1000/if_igb.c	(revision 257322)
+++ sys/dev/e1000/if_igb.c	(working copy)
@@ -72,6 +72,7 @@
 #include <net/if_arp.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
+#include <net/drbr.h>
=20
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
@@ -216,6 +217,9 @@ static void	igb_reset(struct adapter *);
 static int	igb_setup_interface(device_t, struct adapter *);
 static int	igb_allocate_queues(struct adapter *);
 static void	igb_configure_queues(struct adapter *);
+static void 	igb_max_bytes(struct ifnet *, uint64_t max);
+static struct drbr_ring *igb_get_ring(struct ifnet *ifp, int num);
+static int	igb_ring_query(struct ifnet *ifp, struct mbuf *m);
=20
 static int	igb_allocate_transmit_buffers(struct tx_ring *);
 static void	igb_setup_transmit_structures(struct adapter *);
@@ -883,7 +887,43 @@ igb_resume(device_t dev)
 	return bus_generic_resume(dev);
 }
=20
+void
+igb_max_bytes(struct ifnet *ifp, uint64_t max)
+{
+	struct adapter	*adapter =3D ifp->if_softc;
+	adapter->ring_bytes_max =3D max;
=20
+}
+
+struct drbr_ring *
+igb_get_ring(struct ifnet *ifp, int num)
+{
+	struct adapter	*adapter =3D ifp->if_softc;
+	struct tx_ring *txr;
+
+	if (num >=3D adapter->num_queues) {
+		return (NULL);
+	}
+	if (adapter->tx_rings) {
+		txr =3D &adapter->tx_rings[num];
+		return (txr->br);
+	} else {
+		return (NULL);
+	}
+}
+
+int
+igb_ring_query(struct ifnet *ifp, struct mbuf *m)
+{
+	struct adapter *adapter =3D ifp->if_softc;
+	struct tx_ring	*txr;
+	/* For this hack, we only use 0, since adara stuff
+	 * sends out on queue 0 always.
+	 */
+	txr =3D &adapter->tx_rings[0];
+	return(drbr_is_on_ring(txr->br, m));
+}
+
 #ifdef IGB_LEGACY_TX
=20
 /*********************************************************************
@@ -1003,6 +1043,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_r
 	struct adapter  *adapter =3D txr->adapter;
         struct mbuf     *next;
         int             err =3D 0, enq =3D 0;
+	uint8_t		qused;
=20
 	IGB_TX_LOCK_ASSERT(txr);
=20
@@ -1012,11 +1053,11 @@ igb_mq_start_locked(struct ifnet *ifp, struct =
tx_r
=20
=20
 	/* Process the queue */
-	while ((next =3D drbr_peek(ifp, txr->br)) !=3D NULL) {
+	while ((next =3D drbr_peek(ifp, txr->br, &qused)) !=3D NULL) {
 		if ((err =3D igb_xmit(txr, &next)) !=3D 0) {
 			if (next =3D=3D NULL) {
 				/* It was freed, move forward */
-				drbr_advance(ifp, txr->br);
+				drbr_advance(ifp, txr->br, qused);
 			} else {
 				/*=20
 				 * Still have one left, it may not be
@@ -1023,11 +1064,13 @@ igb_mq_start_locked(struct ifnet *ifp, struct =
tx_r
 				 * the same since the transmit function
 				 * may have changed it.
 				 */
-				drbr_putback(ifp, txr->br, next);
+				drbr_putback(ifp, txr->br, next, qused);
 			}
 			break;
 		}
-		drbr_advance(ifp, txr->br);
+		drbr_advance(ifp, txr->br, qused);
+		atomic_add_long(&txr->bytes_on_ring,=20
+			 (u_long)next->m_pkthdr.len);
 		enq++;
 		ifp->if_obytes +=3D next->m_pkthdr.len;
 		if (next->m_flags & M_MCAST)
@@ -1035,6 +1078,11 @@ igb_mq_start_locked(struct ifnet *ifp, struct =
tx_r
 		ETHER_BPF_MTAP(ifp, next);
 		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) =3D=3D 0)
 			break;
+		if (adapter->ring_bytes_max &&=20
+		    (txr->bytes_on_ring >=3D adapter->ring_bytes_max)) {
+			break;
+		}
+
 	}
 	if (enq > 0) {
 		/* Set the watchdog */
@@ -1072,12 +1120,10 @@ igb_qflush(struct ifnet *ifp)
 {
 	struct adapter	*adapter =3D ifp->if_softc;
 	struct tx_ring	*txr =3D adapter->tx_rings;
-	struct mbuf	*m;
=20
 	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
 		IGB_TX_LOCK(txr);
-		while ((m =3D buf_ring_dequeue_sc(txr->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, txr->br);
 		IGB_TX_UNLOCK(txr);
 	}
 	if_qflush(ifp);
@@ -3117,6 +3163,9 @@ igb_setup_interface(device_t dev, struct adapter *
 #ifndef IGB_LEGACY_TX
 	ifp->if_transmit =3D igb_mq_start;
 	ifp->if_qflush =3D igb_qflush;
+	ifp->if_maxbytes =3D igb_max_bytes;
+	ifp->if_getdrbr_ring =3D igb_get_ring;
+	ifp->if_mbuf_on_ring =3D igb_ring_query;
 #else
 	ifp->if_start =3D igb_start;
 	IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1);
@@ -3361,7 +3410,7 @@ igb_allocate_queues(struct adapter *adapter)
         	}
 #ifndef IGB_LEGACY_TX
 		/* Allocate a buf ring */
-		txr->br =3D buf_ring_alloc(igb_buf_ring_size, M_DEVBUF,
+		txr->br =3D drbr_alloc(M_DEVBUF,
 		    M_WAITOK, &txr->tx_mtx);
 #endif
 	}
@@ -3421,7 +3470,7 @@ err_tx_desc:
 	free(adapter->rx_rings, M_DEVBUF);
 rx_fail:
 #ifndef IGB_LEGACY_TX
-	buf_ring_free(txr->br, M_DEVBUF);
+	drbr_free(txr->br, M_DEVBUF);
 #endif
 	free(adapter->tx_rings, M_DEVBUF);
 tx_fail:
@@ -3539,6 +3588,7 @@ igb_setup_transmit_ring(struct tx_ring *txr)
=20
 	/* Set number of descriptors available */
 	txr->tx_avail =3D adapter->num_tx_desc;
+	txr->bytes_on_ring =3D 0;
=20
 	bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -3680,7 +3730,7 @@ igb_free_transmit_buffers(struct tx_ring *txr)
 	}
 #ifndef IGB_LEGACY_TX
 	if (txr->br !=3D NULL)
-		buf_ring_free(txr->br, M_DEVBUF);
+		drbr_free(txr->br, M_DEVBUF);
 #endif
 	if (txr->tx_buffers !=3D NULL) {
 		free(txr->tx_buffers, M_DEVBUF);
@@ -4016,6 +4066,8 @@ igb_txeof(struct tx_ring *txr)
 			if (buf->m_head) {
 				txr->bytes +=3D
 				    buf->m_head->m_pkthdr.len;
+				=
atomic_subtract_long(&txr->bytes_on_ring,
+				    =
(uint64_t)buf->m_head->m_pkthdr.len);
 				bus_dmamap_sync(txr->txtag,
 				    buf->map,
 				    BUS_DMASYNC_POSTWRITE);
@@ -5636,7 +5688,7 @@ igb_add_hw_stats(struct adapter *adapter)
 		queue_node =3D SYSCTL_ADD_NODE(ctx, child, OID_AUTO, =
namebuf,
 					    CTLFLAG_RD, NULL, "Queue =
Name");
 		queue_list =3D SYSCTL_CHILDREN(queue_node);
-
+		drbr_add_sysctl_stats(dev, queue_list, txr->br);
 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, =
"interrupt_rate",=20
 				CTLFLAG_RD, &adapter->queues[i],
 				sizeof(&adapter->queues[i]),
Index: sys/dev/e1000/if_igb.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/e1000/if_igb.h	(revision 257322)
+++ sys/dev/e1000/if_igb.h	(working copy)
@@ -309,12 +309,14 @@ struct tx_ring {
 	    IGB_QUEUE_DEPLETED =3D 8,
 	}			queue_status;
 	u32			txd_cmd;
-	bus_dma_tag_t		txtag;
 	char			mtx_name[16];
 #ifndef IGB_LEGACY_TX
-	struct buf_ring		*br;
+	struct drbr_ring	*br;
 	struct task		txq_task;
 #endif
+	bus_dma_tag_t		txtag;
+	volatile u_long		bytes_on_ring;
+
 	u32			bytes;  /* used for AIM */
 	u32			packets;
 	/* Soft Stats */
@@ -371,17 +373,17 @@ struct adapter {
 	struct device		*dev;
 	struct cdev		*led_dev;
=20
-	struct resource		*pci_mem;
-	struct resource		*msix_mem;
-	int			memrid;
-
+	struct resource *pci_mem;
+	struct resource *msix_mem;
+	uint64_t	ring_bytes_max;
+	int		memrid;
 	/*
 	 * Interrupt resources: this set is
 	 * either used for legacy, or for Link
 	 * when doing MSIX
 	 */
-	void			*tag;
-	struct resource 	*res;
+	void		*tag;
+	struct resource	*res;
=20
 	struct ifmedia		media;
 	struct callout		timer;
Index: sys/dev/fdt/fdt_common.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/fdt/fdt_common.c	(revision 257322)
+++ sys/dev/fdt/fdt_common.c	(working copy)
@@ -183,7 +183,6 @@ fdt_is_compatible(phandle_t node, const char *comp
 		compat +=3D l;
 		len -=3D l;
 	}
-
 	return (rv);
 }
=20
@@ -585,15 +584,18 @@ fdt_get_phyaddr(phandle_t node, device_t dev, int
 	if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
 	    sizeof(phy_handle)) <=3D 0)
 		return (ENXIO);
-
 	phy_node =3D OF_xref_phandle(phy_handle);
+	device_printf(dev, "phy-handle:0x%x phy_ihandle:0x%x =
phy_node:0x%x\n",=20
+		      (uint32_t)phy_handle, (uint32_t)phy_ihandle,
+		      (uint32_t)phy_node);
=20
 	if (OF_getprop(phy_node, "reg", (void *)&phy_reg,
 	    sizeof(phy_reg)) <=3D 0)
 		return (ENXIO);
=20
+	device_printf(dev, "reg:0x%x\n", (uint32_t)phy_reg);
 	*phy_addr =3D fdt32_to_cpu(phy_reg);
-
+	device_printf(dev, "tran to reg:0x%x\n", (uint32_t)*phy_addr);
 	/*
 	 * Search for softc used to communicate with phy.
 	 */
Index: sys/dev/fdt/simplebus.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/fdt/simplebus.c	(revision 257322)
+++ sys/dev/fdt/simplebus.c	(working copy)
@@ -154,6 +154,8 @@ simplebus_probe(device_t dev)
 	return (BUS_PROBE_GENERIC);
 }
=20
+extern uint32_t simp_bus_debug;
+
 static int
 simplebus_attach(device_t dev)
 {
@@ -161,6 +163,7 @@ simplebus_attach(device_t dev)
 	struct simplebus_devinfo *di;
 	struct simplebus_softc *sc;
 	phandle_t dt_node, dt_child;
+	int ret;
=20
 	sc =3D device_get_softc(dev);
=20
@@ -215,13 +218,15 @@ simplebus_attach(device_t dev)
 			free(di, M_SIMPLEBUS);
 			continue;
 		}
-#ifdef DEBUG
+/*#ifdef DEBUG*/
 		device_printf(dev, "added child: %s\n\n", =
di->di_ofw.obd_name);
-#endif
+/*#endif*/
 		device_set_ivars(dev_child, di);
 	}
-
-	return (bus_generic_attach(dev));
+	simp_bus_debug =3D 1;
+	ret =3D bus_generic_attach(dev);
+	simp_bus_debug =3D 0;
+	return (ret);
 }
=20
 static int
Index: sys/dev/ixgbe/ixgbe.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/ixgbe/ixgbe.c	(revision 257322)
+++ sys/dev/ixgbe/ixgbe.c	(working copy)
@@ -845,7 +845,8 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx
 	struct adapter  *adapter =3D txr->adapter;
         struct mbuf     *next;
         int             enqueued =3D 0, err =3D 0;
-
+	uint8_t		qused;
+=09
 	if (((ifp->if_drv_flags & IFF_DRV_RUNNING) =3D=3D 0) ||
 	    adapter->link_active =3D=3D 0)
 		return (ENETDOWN);
@@ -858,18 +859,18 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx
 			if (next !=3D NULL)
 				err =3D drbr_enqueue(ifp, txr->br, =
next);
 #else
-	while ((next =3D drbr_peek(ifp, txr->br)) !=3D NULL) {
+	while ((next =3D drbr_peek(ifp, txr->br, &qused)) !=3D NULL) {
 		if ((err =3D ixgbe_xmit(txr, &next)) !=3D 0) {
 			if (next =3D=3D NULL) {
-				drbr_advance(ifp, txr->br);
+				drbr_advance(ifp, txr->br, qused);
 			} else {
-				drbr_putback(ifp, txr->br, next);
+				drbr_putback(ifp, txr->br, next, qused);
 			}
 #endif
 			break;
 		}
 #if __FreeBSD_version >=3D 901504
-		drbr_advance(ifp, txr->br);
+		drbr_advance(ifp, txr->br, qused);
 #endif
 		enqueued++;
 		/* Send a copy of the frame to the BPF listener */
@@ -917,12 +918,10 @@ ixgbe_qflush(struct ifnet *ifp)
 {
 	struct adapter	*adapter =3D ifp->if_softc;
 	struct tx_ring	*txr =3D adapter->tx_rings;
-	struct mbuf	*m;
=20
 	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
 		IXGBE_TX_LOCK(txr);
-		while ((m =3D buf_ring_dequeue_sc(txr->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, txr->br);
 		IXGBE_TX_UNLOCK(txr);
 	}
 	if_qflush(ifp);
@@ -2891,7 +2890,7 @@ ixgbe_allocate_queues(struct adapter *adapter)
         	}
 #ifndef IXGBE_LEGACY_TX
 		/* Allocate a buf ring */
-		txr->br =3D buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF,
+		txr->br =3D drbr_alloc(M_DEVBUF,
 		    M_WAITOK, &txr->tx_mtx);
 		if (txr->br =3D=3D NULL) {
 			device_printf(dev,
@@ -3253,7 +3252,7 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr)
 	}
 #ifdef IXGBE_LEGACY_TX
 	if (txr->br !=3D NULL)
-		buf_ring_free(txr->br, M_DEVBUF);
+		drbr_free(txr->br, M_DEVBUF);
 #endif
 	if (txr->tx_buffers !=3D NULL) {
 		free(txr->tx_buffers, M_DEVBUF);
Index: sys/dev/ixgbe/ixgbe.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/ixgbe/ixgbe.h	(revision 257322)
+++ sys/dev/ixgbe/ixgbe.h	(working copy)
@@ -58,6 +58,7 @@
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
+#include <net/drbr.h>
=20
 #include <net/bpf.h>
 #include <net/if_types.h>
@@ -313,7 +314,7 @@ struct tx_ring {
 	bus_dma_tag_t		txtag;
 	char			mtx_name[16];
 #ifndef IXGBE_LEGACY_TX
-	struct buf_ring		*br;
+	struct drbr_ring	*br;
 	struct task		txq_task;
 #endif
 #ifdef IXGBE_FDIR
Index: sys/dev/ixgbe/ixv.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/ixgbe/ixv.c	(revision 257322)
+++ sys/dev/ixgbe/ixv.c	(working copy)
@@ -603,6 +603,7 @@ ixv_mq_start_locked(struct ifnet *ifp, struct tx_r
 	struct adapter  *adapter =3D txr->adapter;
         struct mbuf     *next;
         int             enqueued, err =3D 0;
+	uint8_t 	qused;
=20
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=3D=

 	    IFF_DRV_RUNNING || adapter->link_active =3D=3D 0) {
@@ -623,16 +624,16 @@ ixv_mq_start_locked(struct ifnet *ifp, struct tx_r
 		}
 	}
 	/* Process the queue */
-	while ((next =3D drbr_peek(ifp, txr->br)) !=3D NULL) {
+	while ((next =3D drbr_peek(ifp, txr->br, &qused)) !=3D NULL) {
 		if ((err =3D ixv_xmit(txr, &next)) !=3D 0) {
 			if (next =3D=3D NULL) {
-				drbr_advance(ifp, txr->br);
+				drbr_advance(ifp, txr->br, qused);
 			} else {
-				drbr_putback(ifp, txr->br, next);
+				drbr_putback(ifp, txr->br, next, qused);
 			}
 			break;
 		}
-		drbr_advance(ifp, txr->br);
+		drbr_advance(ifp, txr->br, qused);
 		enqueued++;
 		ifp->if_obytes +=3D next->m_pkthdr.len;
 		if (next->m_flags & M_MCAST)
@@ -664,12 +665,10 @@ ixv_qflush(struct ifnet *ifp)
 {
 	struct adapter  *adapter =3D ifp->if_softc;
 	struct tx_ring  *txr =3D adapter->tx_rings;
-	struct mbuf     *m;
=20
 	for (int i =3D 0; i < adapter->num_queues; i++, txr++) {
 		IXV_TX_LOCK(txr);
-		while ((m =3D buf_ring_dequeue_sc(txr->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, txr->br);
 		IXV_TX_UNLOCK(txr);
 	}
 	if_qflush(ifp);
@@ -2053,8 +2052,7 @@ ixv_allocate_queues(struct adapter *adapter)
         	}
 #if __FreeBSD_version >=3D 800000
 		/* Allocate a buf ring */
-		txr->br =3D buf_ring_alloc(IXV_BR_SIZE, M_DEVBUF,
-		    M_WAITOK, &txr->tx_mtx);
+		txr->br =3D drbr_alloc(M_DEVBUF, M_WAITOK, =
&txr->tx_mtx);
 		if (txr->br =3D=3D NULL) {
 			device_printf(dev,
 			    "Critical Failure setting up buf ring\n");
@@ -2355,7 +2353,7 @@ ixv_free_transmit_buffers(struct tx_ring *txr)
 	}
 #if __FreeBSD_version >=3D 800000
 	if (txr->br !=3D NULL)
-		buf_ring_free(txr->br, M_DEVBUF);
+		drbr_free(txr->br, M_DEVBUF);
 #endif
 	if (txr->tx_buffers !=3D NULL) {
 		free(txr->tx_buffers, M_DEVBUF);
Index: sys/dev/ixgbe/ixv.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/ixgbe/ixv.h	(revision 257322)
+++ sys/dev/ixgbe/ixv.h	(working copy)
@@ -61,6 +61,7 @@
 #include <net/bpf.h>
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
=20
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -267,7 +268,7 @@ struct tx_ring {
 	u32			txd_cmd;
 	bus_dma_tag_t		txtag;
 	char			mtx_name[16];
-	struct buf_ring		*br;
+	struct drbr_ring	*br;
 	/* Soft Stats */
 	u32			bytes;
 	u32			packets;
Index: sys/dev/mxge/if_mxge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/mxge/if_mxge.c	(revision 257322)
+++ sys/dev/mxge/if_mxge.c	(working copy)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
 #include <net/zlib.h>
+#include <net/drbr.h>
=20
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -2243,14 +2244,12 @@ mxge_qflush(struct ifnet *ifp)
 {
 	mxge_softc_t *sc =3D ifp->if_softc;
 	mxge_tx_ring_t *tx;
-	struct mbuf *m;
 	int slice;
=20
 	for (slice =3D 0; slice < sc->num_slices; slice++) {
 		tx =3D &sc->ss[slice].tx;
 		mtx_lock(&tx->mtx);
-		while ((m =3D buf_ring_dequeue_sc(tx->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(ifp, tx->br);
 		mtx_unlock(&tx->mtx);
 	}
 	if_qflush(ifp);
@@ -4060,7 +4059,7 @@ mxge_update_stats(mxge_softc_t *sc)
 #ifdef IFNET_BUF_RING
 		obytes +=3D ss->obytes;
 		omcasts +=3D ss->omcasts;
-		odrops +=3D ss->tx.br->br_drops;
+		odrops +=3D drbr_get_dropcnt(ss->tx.br);
 #endif
 		oerrors +=3D ss->oerrors;
 	}
@@ -4436,7 +4435,7 @@ mxge_alloc_slices(mxge_softc_t *sc)
 			 "%s:tx(%d)", device_get_nameunit(sc->dev), i);
 		mtx_init(&ss->tx.mtx, ss->tx.mtx_name, NULL, MTX_DEF);
 #ifdef IFNET_BUF_RING
-		ss->tx.br =3D buf_ring_alloc(2048, M_DEVBUF, M_WAITOK,
+		ss->tx.br =3D drbr_alloc(M_DEVBUF, M_WAITOK,
 					   &ss->tx.mtx);
 #endif
 	}
Index: sys/dev/mxge/if_mxge_var.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/mxge/if_mxge_var.h	(revision 257322)
+++ sys/dev/mxge/if_mxge_var.h	(working copy)
@@ -167,7 +167,7 @@ typedef struct
 {
 	struct mtx mtx;
 #ifdef IFNET_BUF_RING
-	struct buf_ring *br;
+	struct drbr_ring *br;
 #endif
 	volatile mcp_kreq_ether_send_t *lanai;	/* lanai ptr for sendq	=
*/
 	volatile uint32_t *send_go;		/* doorbell for sendq */
Index: sys/dev/oce/oce_hw.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/oce/oce_hw.c	(revision 257322)
+++ sys/dev/oce/oce_hw.c	(working copy)
@@ -360,8 +360,8 @@ oce_hw_shutdown(POCE_SOFTC sc)
 	/* release PCI resources */
 	oce_hw_pci_free(sc);
 	/* free mbox specific resources */
-	LOCK_DESTROY(&sc->bmbx_lock);
-	LOCK_DESTROY(&sc->dev_lock);
+	LOCK_DESTROY_OCE(&sc->bmbx_lock);
+	LOCK_DESTROY_OCE(&sc->dev_lock);
=20
 	oce_dma_free(sc, &sc->bsmbx);
 }
Index: sys/dev/oce/oce_if.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/oce/oce_if.c	(revision 257322)
+++ sys/dev/oce/oce_if.c	(working copy)
@@ -296,8 +296,8 @@ oce_attach(device_t dev)
 	sc->flow_control =3D OCE_DEFAULT_FLOW_CONTROL;
 	sc->promisc	 =3D OCE_DEFAULT_PROMISCUOUS;
=20
-	LOCK_CREATE(&sc->bmbx_lock, "Mailbox_lock");
-	LOCK_CREATE(&sc->dev_lock,  "Device_lock");
+	LOCK_CREATE_OCE(&sc->bmbx_lock, "Mailbox_lock");
+	LOCK_CREATE_OCE(&sc->dev_lock,  "Device_lock");
=20
 	/* initialise the hardware */
 	rc =3D oce_hw_init(sc);
@@ -372,8 +372,8 @@ mbox_free:
 	oce_dma_free(sc, &sc->bsmbx);
 pci_res_free:
 	oce_hw_pci_free(sc);
-	LOCK_DESTROY(&sc->dev_lock);
-	LOCK_DESTROY(&sc->bmbx_lock);
+	LOCK_DESTROY_OCE(&sc->dev_lock);
+	LOCK_DESTROY_OCE(&sc->bmbx_lock);
 	return rc;
=20
 }
@@ -384,9 +384,9 @@ oce_detach(device_t dev)
 {
 	POCE_SOFTC sc =3D device_get_softc(dev);
=20
-	LOCK(&sc->dev_lock);
+	LOCK_OCE(&sc->dev_lock);
 	oce_if_deactivate(sc);
-	UNLOCK(&sc->dev_lock);
+	UNLOCK_OCE(&sc->dev_lock);
=20
 	callout_drain(&sc->timer);
 =09
@@ -447,13 +447,13 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr
 			}
 			device_printf(sc->dev, "Interface Up\n");=09
 		} else {
-			LOCK(&sc->dev_lock);
+			LOCK_OCE(&sc->dev_lock);
=20
 			sc->ifp->if_drv_flags &=3D
 			    ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 			oce_if_deactivate(sc);
=20
-			UNLOCK(&sc->dev_lock);
+			UNLOCK_OCE(&sc->dev_lock);
=20
 			device_printf(sc->dev, "Interface Down\n");
 		}
@@ -543,7 +543,7 @@ oce_init(void *arg)
 {
 	POCE_SOFTC sc =3D arg;
 =09
-	LOCK(&sc->dev_lock);
+	LOCK_OCE(&sc->dev_lock);
=20
 	if (sc->ifp->if_flags & IFF_UP) {
 		oce_if_deactivate(sc);
@@ -550,7 +550,7 @@ oce_init(void *arg)
 		oce_if_activate(sc);
 	}
 =09
-	UNLOCK(&sc->dev_lock);
+	UNLOCK_OCE(&sc->dev_lock);
=20
 }
=20
@@ -571,9 +571,9 @@ oce_multiq_start(struct ifnet *ifp, struct mbuf *m
=20
 	wq =3D sc->wq[queue_index];
=20
-	LOCK(&wq->tx_lock);
+	LOCK_OCE(&wq->tx_lock);
 	status =3D oce_multiq_transmit(ifp, m, wq);
-	UNLOCK(&wq->tx_lock);
+	UNLOCK_OCE(&wq->tx_lock);
=20
 	return status;
=20
@@ -584,12 +584,10 @@ static void
 oce_multiq_flush(struct ifnet *ifp)
 {
 	POCE_SOFTC sc =3D ifp->if_softc;
-	struct mbuf     *m;
 	int i =3D 0;
=20
 	for (i =3D 0; i < sc->nwqs; i++) {
-		while ((m =3D buf_ring_dequeue_sc(sc->wq[i]->br)) !=3D =
NULL)
-			m_freem(m);
+		drbr_flush(ifp, sc->wq[i]->br);
 	}
 	if_qflush(ifp);
 }
@@ -1136,13 +1134,13 @@ oce_tx_task(void *arg, int npending)
 	int rc =3D 0;
=20
 #if __FreeBSD_version >=3D 800000
-	LOCK(&wq->tx_lock);
+	LOCK_OCE(&wq->tx_lock);
 	rc =3D oce_multiq_transmit(ifp, NULL, wq);
 	if (rc) {
 		device_printf(sc->dev,
 				"TX[%d] restart failed\n", =
wq->queue_index);
 	}
-	UNLOCK(&wq->tx_lock);
+	UNLOCK_OCE(&wq->tx_lock);
 #else
 	oce_start(ifp);
 #endif
@@ -1170,9 +1168,9 @@ oce_start(struct ifnet *ifp)
 		if (m =3D=3D NULL)
 			break;
=20
-		LOCK(&sc->wq[def_q]->tx_lock);
+		LOCK_OCE(&sc->wq[def_q]->tx_lock);
 		rc =3D oce_tx(sc, &m, def_q);
-		UNLOCK(&sc->wq[def_q]->tx_lock);
+		UNLOCK_OCE(&sc->wq[def_q]->tx_lock);
 		if (rc) {
 			if (m !=3D NULL) {
 				sc->wq[def_q]->tx_stats.tx_stops ++;
@@ -1247,7 +1245,8 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf
 	POCE_SOFTC sc =3D ifp->if_softc;
 	int status =3D 0, queue_index =3D 0;
 	struct mbuf *next =3D NULL;
-	struct buf_ring *br =3D NULL;
+	struct drbr_ring *br =3D NULL;
+	uint8_t qused;
=20
 	br  =3D wq->br;
 	queue_index =3D wq->queue_index;
@@ -1263,12 +1262,12 @@ oce_multiq_transmit(struct ifnet *ifp, struct =
mbuf
 		if ((status =3D drbr_enqueue(ifp, br, m)) !=3D 0)
 			return status;
 	}=20
-	while ((next =3D drbr_peek(ifp, br)) !=3D NULL) {
+	while ((next =3D drbr_peek(ifp, br, &qused)) !=3D NULL) {
 		if (oce_tx(sc, &next, queue_index)) {
 			if (next =3D=3D NULL) {
-				drbr_advance(ifp, br);
+				drbr_advance(ifp, br, qused);
 			} else {
-				drbr_putback(ifp, br, next);
+				drbr_putback(ifp, br, next, qused);
 				wq->tx_stats.tx_stops ++;
 				ifp->if_drv_flags |=3D IFF_DRV_OACTIVE;
 				status =3D drbr_enqueue(ifp, br, next);
@@ -1275,7 +1274,7 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf
 			} =20
 			break;
 		}
-		drbr_advance(ifp, br);
+		drbr_advance(ifp, br, qused);
 		ifp->if_obytes +=3D next->m_pkthdr.len;
 		if (next->m_flags & M_MCAST)
 			ifp->if_omcasts++;
@@ -2078,13 +2077,13 @@ oce_if_deactivate(POCE_SOFTC sc)
 	   any other lock. So unlock device lock and require after
 	   completing taskqueue_drain.
 	*/
-	UNLOCK(&sc->dev_lock);
+	UNLOCK_OCE(&sc->dev_lock);
 	for (i =3D 0; i < sc->intr_count; i++) {
 		if (sc->intrs[i].tq !=3D NULL) {
 			taskqueue_drain(sc->intrs[i].tq, =
&sc->intrs[i].task);
 		}
 	}
-	LOCK(&sc->dev_lock);
+	LOCK_OCE(&sc->dev_lock);
=20
 	/* Delete RX queue in card with flush param */
 	oce_stop_rx(sc);
Index: sys/dev/oce/oce_if.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/oce/oce_if.h	(revision 257322)
+++ sys/dev/oce/oce_if.h	(working copy)
@@ -70,6 +70,7 @@
 #include <net/if_media.h>
 #include <net/if_vlan_var.h>
 #include <net/if_dl.h>
+#include <net/drbr.h>
=20
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -528,18 +529,18 @@ struct oce_lock {
 };
 #define OCE_LOCK				struct oce_lock
=20
-#define LOCK_CREATE(lock, desc) 		{ \
+#define LOCK_CREATE_OCE(lock, desc) 		{ \
 	strncpy((lock)->name, (desc), MAX_LOCK_DESC_LEN); \
 	(lock)->name[MAX_LOCK_DESC_LEN] =3D '\0'; \
 	mtx_init(&(lock)->mutex, (lock)->name, NULL, MTX_DEF); \
 }
-#define LOCK_DESTROY(lock) 			\
+#define LOCK_DESTROY_OCE(lock) 			\
 		if (mtx_initialized(&(lock)->mutex))\
 			mtx_destroy(&(lock)->mutex)
-#define TRY_LOCK(lock)				=
mtx_trylock(&(lock)->mutex)
-#define LOCK(lock)				mtx_lock(&(lock)->mutex)
-#define LOCKED(lock)				=
mtx_owned(&(lock)->mutex)
-#define UNLOCK(lock)				=
mtx_unlock(&(lock)->mutex)
+#define TRY_LOCK_OCE(lock)			=
mtx_trylock(&(lock)->mutex)
+#define LOCK_OCE(lock)				mtx_lock(&(lock)->mutex)
+#define LOCKED_OCE(lock)			=
mtx_owned(&(lock)->mutex)
+#define UNLOCK_OCE(lock)			=
mtx_unlock(&(lock)->mutex)
=20
 #define	DEFAULT_MQ_MBOX_TIMEOUT			(5 * 1000 * =
1000)
 #define	MBX_READY_TIMEOUT			(1 * 1000 * =
1000)
@@ -702,7 +703,7 @@ struct oce_wq {
 	struct wq_config cfg;
 	int queue_index;
 	struct oce_tx_queue_stats tx_stats;
-	struct buf_ring *br;
+	struct drbr_ring *br;
 	struct task txtask;
 	uint32_t db_offset;
 };
Index: sys/dev/oce/oce_mbox.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/oce/oce_mbox.c	(revision 257322)
+++ sys/dev/oce/oce_mbox.c	(working copy)
@@ -345,7 +345,7 @@ oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx,
 	uint32_t cstatus =3D 0;
 	uint32_t xstatus =3D 0;
=20
-	LOCK(&sc->bmbx_lock);
+	LOCK_OCE(&sc->bmbx_lock);
=20
 	mb =3D OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
 	mb_mbx =3D &mb->mbx;
@@ -387,7 +387,7 @@ oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx,
 		}
 	}
=20
-	UNLOCK(&sc->bmbx_lock);
+	UNLOCK_OCE(&sc->bmbx_lock);
=20
 	return rc;
 }
Index: sys/dev/oce/oce_queue.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/oce/oce_queue.c	(revision 257322)
+++ sys/dev/oce/oce_queue.c	(working copy)
@@ -253,12 +253,11 @@ oce_wq *oce_wq_init(POCE_SOFTC sc, uint32_t q_len,
 		goto free_wq;
=20
=20
-	LOCK_CREATE(&wq->tx_lock, "TX_lock");
+	LOCK_CREATE_OCE(&wq->tx_lock, "TX_lock");
 =09
 #if __FreeBSD_version >=3D 800000
 	/* Allocate buf ring for multiqueue*/
-	wq->br =3D buf_ring_alloc(4096, M_DEVBUF,
-			M_WAITOK, &wq->tx_lock.mutex);
+	wq->br =3D drbr_alloc(M_DEVBUF, M_WAITOK, &wq->tx_lock.mutex);
 	if (!wq->br)
 		goto free_wq;
 #endif
@@ -301,9 +300,9 @@ oce_wq_free(struct oce_wq *wq)
 	if (wq->tag !=3D NULL)
 		bus_dma_tag_destroy(wq->tag);
 	if (wq->br !=3D NULL)
-		buf_ring_free(wq->br, M_DEVBUF);
+		drbr_free(wq->br, M_DEVBUF);
=20
-	LOCK_DESTROY(&wq->tx_lock);
+	LOCK_DESTROY_OCE(&wq->tx_lock);
 	free(wq, M_DEVBUF);
 }
=20
@@ -451,7 +450,7 @@ oce_rq *oce_rq_init(POCE_SOFTC sc,
 	if (!rq->ring)
 		goto free_rq;
=20
-	LOCK_CREATE(&rq->rx_lock, "RX_lock");
+	LOCK_CREATE_OCE(&rq->rx_lock, "RX_lock");
=20
 	return rq;
=20
@@ -493,7 +492,7 @@ oce_rq_free(struct oce_rq *rq)
 	if (rq->tag !=3D NULL)
 		bus_dma_tag_destroy(rq->tag);
=20
-	LOCK_DESTROY(&rq->rx_lock);
+	LOCK_DESTROY_OCE(&rq->rx_lock);
 	free(rq, M_DEVBUF);
 }
=20
Index: sys/dev/virtio/network/if_vtnet.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/virtio/network/if_vtnet.c	(revision 257322)
+++ sys/dev/virtio/network/if_vtnet.c	(working copy)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_types.h>
 #include <net/if_media.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
=20
 #include <net/bpf.h>
=20
@@ -685,7 +686,7 @@ vtnet_init_txq(struct vtnet_softc *sc, int id)
 	txq->vtntx_id =3D id;
=20
 #ifndef VTNET_LEGACY_TX
-	txq->vtntx_br =3D buf_ring_alloc(VTNET_DEFAULT_BUFRING_SIZE, =
M_DEVBUF,
+	txq->vtntx_br =3D drbr_alloc(M_DEVBUF,
 	    M_NOWAIT, &txq->vtntx_mtx);
 	if (txq->vtntx_br =3D=3D NULL)
 		return (ENOMEM);
@@ -749,7 +750,7 @@ vtnet_destroy_txq(struct vtnet_txq *txq)
=20
 #ifndef VTNET_LEGACY_TX
 	if (txq->vtntx_br !=3D NULL) {
-		buf_ring_free(txq->vtntx_br, M_DEVBUF);
+		drbr_free(txq->vtntx_br, M_DEVBUF);
 		txq->vtntx_br =3D NULL;
 	}
 #endif
@@ -2211,9 +2212,10 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, =
s
 {
 	struct vtnet_softc *sc;
 	struct virtqueue *vq;
-	struct buf_ring *br;
+	struct drbr_ring *br;
 	struct ifnet *ifp;
 	int enq, error;
+	uint8_t qnum;
=20
 	sc =3D txq->vtntx_sc;
 	vq =3D txq->vtntx_vq;
@@ -2239,16 +2241,16 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, =
s
=20
 	vtnet_txq_eof(txq);
=20
-	while ((m =3D drbr_peek(ifp, br)) !=3D NULL) {
+	while ((m =3D drbr_peek(ifp, br, &qnum)) !=3D NULL) {
 		error =3D vtnet_txq_encap(txq, &m);
 		if (error) {
 			if (m !=3D NULL)
-				drbr_putback(ifp, br, m);
+				drbr_putback(ifp, br, m, qnum);
 			else
-				drbr_advance(ifp, br);
+				drbr_advance(ifp, br, qnum);
 			break;
 		}
-		drbr_advance(ifp, br);
+		drbr_advance(ifp, br, qnum);
=20
 		enq++;
 		ETHER_BPF_MTAP(ifp, m);
@@ -2458,7 +2460,6 @@ vtnet_qflush(struct ifnet *ifp)
 {
 	struct vtnet_softc *sc;
 	struct vtnet_txq *txq;
-	struct mbuf *m;
 	int i;
=20
 	sc =3D ifp->if_softc;
@@ -2467,8 +2468,7 @@ vtnet_qflush(struct ifnet *ifp)
 		txq =3D &sc->vtnet_txqs[i];
=20
 		VTNET_TXQ_LOCK(txq);
-		while ((m =3D buf_ring_dequeue_sc(txq->vtntx_br)) !=3D =
NULL)
-			m_freem(m);
+		drbr_flush(ifp, txq->vtntx_br);
 		VTNET_TXQ_UNLOCK(txq);
 	}
=20
Index: sys/dev/virtio/network/if_vtnetvar.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/virtio/network/if_vtnetvar.h	(revision 257322)
+++ sys/dev/virtio/network/if_vtnetvar.h	(working copy)
@@ -100,7 +100,7 @@ struct vtnet_txq {
 	struct vtnet_softc	*vtntx_sc;
 	struct virtqueue	*vtntx_vq;
 #ifndef VTNET_LEGACY_TX
-	struct buf_ring		*vtntx_br;
+	struct drbr_ring	*vtntx_br;
 #endif
 	int			 vtntx_id;
 	int			 vtntx_watchdog;
Index: sys/dev/vxge/vxge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/vxge/vxge.c	(revision 257322)
+++ sys/dev/vxge/vxge.c	(working copy)
@@ -31,6 +31,7 @@
 /*$FreeBSD$*/
=20
 #include <dev/vxge/vxge.h>
+#include <net/drbr.h>
=20
 static int vxge_pci_bd_no =3D -1;
 static u32 vxge_drv_copyright =3D 0;
@@ -729,7 +730,6 @@ void
 vxge_mq_qflush(ifnet_t ifp)
 {
 	int i;
-	mbuf_t m_head;
 	vxge_vpath_t *vpath;
=20
 	vxge_dev_t *vdev =3D (vxge_dev_t *) ifp->if_softc;
@@ -740,9 +740,7 @@ vxge_mq_qflush(ifnet_t ifp)
 			continue;
=20
 		VXGE_TX_LOCK(vpath);
-		while ((m_head =3D buf_ring_dequeue_sc(vpath->br)) !=3D =
NULL)
-			vxge_free_packet(m_head);
-
+		drbr_flush(ifp, vpath->br);
 		VXGE_TX_UNLOCK(vpath);
 	}
 	if_qflush(ifp);
@@ -2294,7 +2292,7 @@ vxge_vpath_open(vxge_dev_t *vdev)
 			break;
 		}
 #if __FreeBSD_version >=3D 800000
-		vpath->br =3D buf_ring_alloc(VXGE_DEFAULT_BR_SIZE, =
M_DEVBUF,
+		vpath->br =3D drbr_alloc(M_DEVBUF,
 		    M_WAITOK, &vpath->mtx_tx);
 		if (vpath->br =3D=3D NULL) {
 			err =3D ENOMEM;
@@ -2433,7 +2431,7 @@ vxge_vpath_close(vxge_dev_t *vdev)
=20
 #if __FreeBSD_version >=3D 800000
 		if (vpath->br !=3D NULL)
-			buf_ring_free(vpath->br, M_DEVBUF);
+			drbr_free(vpath->br, M_DEVBUF);
 #endif
 		/* Free LRO memory */
 		if (vpath->lro_enable)
Index: sys/dev/vxge/vxge.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/dev/vxge/vxge.h	(revision 257322)
+++ sys/dev/vxge/vxge.h	(working copy)
@@ -337,7 +337,7 @@ typedef struct _vxge_vpath_t {
 	struct		lro_ctrl lro;
=20
 #if __FreeBSD_version >=3D 800000
-	struct		buf_ring *br;
+	struct		drbr_ring *br;
 #endif
=20
 } vxge_vpath_t;
Index: sys/kern/kern_mbuf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/kern/kern_mbuf.c	(revision 257322)
+++ sys/kern/kern_mbuf.c	(working copy)
@@ -653,7 +653,6 @@ m_pkthdr_init(struct mbuf *m, int how)
 	m->m_pkthdr.flowid =3D 0;
 	m->m_pkthdr.csum_flags =3D 0;
 	m->m_pkthdr.fibnum =3D 0;
-	m->m_pkthdr.cosqos =3D 0;
 	m->m_pkthdr.rsstype =3D 0;
 	m->m_pkthdr.l2hlen =3D 0;
 	m->m_pkthdr.l3hlen =3D 0;
@@ -661,6 +660,7 @@ m_pkthdr_init(struct mbuf *m, int how)
 	m->m_pkthdr.l5hlen =3D 0;
 	m->m_pkthdr.PH_per.sixtyfour[0] =3D 0;
 	m->m_pkthdr.PH_loc.sixtyfour[0] =3D 0;
+	m->m_pkthdr.cosqos =3D 0xff; /*drbr_maxq-1;*/
 #ifdef MAC
 	/* If the label init fails, fail the alloc */
 	error =3D mac_mbuf_init(m, how);
Index: sys/kern/subr_bufring.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/kern/subr_bufring.c	(revision 257322)
+++ sys/kern/subr_bufring.c	(working copy)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/ktr.h>
 #include <sys/buf_ring.h>
+#include <sys/mbuf.h>
=20
=20
 struct buf_ring *
@@ -63,3 +64,317 @@ buf_ring_free(struct buf_ring *br, struct malloc_t
 {
 	free(br, type);
 }
+
+/*
+ * multi-producer safe lock-free ring buffer enqueue
+ *
+ */
+extern uint32_t panic_on_dup_buf;
+
+int
+buf_ring_mbufon(struct buf_ring *br, void *buf)
+{
+	int i;
+	/* We don't count what the driver is peeking at */
+	for (i =3D br->br_cons_head; i !=3D br->br_prod_head;
+	     i =3D ((i + 1) & br->br_cons_mask)) {
+		if(br->br_ring[i] =3D=3D buf) {
+			return(1);
+		}
+	}
+	return(0);
+}
+
+__attribute__((noinline))
+int
+buf_ring_enqueue(struct buf_ring *br, void *buf)
+{
+	uint32_t prod_head, prod_next;
+	uint32_t cons_tail;
+#ifdef DEBUG_BUFRING
+	int i;
+	critical_enter();
+	mb();
+	for (i =3D br->br_cons_head; i !=3D br->br_prod_head;
+	     i =3D ((i + 1) & br->br_cons_mask))
+		if(br->br_ring[i] =3D=3D buf) {
+			if (panic_on_dup_buf)
+				panic("help br:%p buf:%p", br, buf);
+			critical_exit();
+			return(0);
+		}
+#else
+	critical_enter();
+#endif=09
+	do {
+		prod_head =3D br->br_prod_head;
+		cons_tail =3D br->br_cons_tail;
+
+		prod_next =3D (prod_head + 1) & br->br_prod_mask;
+	=09
+		if (prod_next =3D=3D cons_tail) {
+			br->br_drops++;
+			critical_exit();
+			return (ENOBUFS);
+		}
+	} while (!atomic_cmpset_int(&br->br_prod_head, prod_head, =
prod_next));
+#ifdef DEBUG_BUFRING
+	if (br->br_ring[prod_head] !=3D NULL) {
+		printf("Dangling value in enqueue %d br:%p\n",=20
+		       prod_head, br);
+	}
+#endif=09
+	br->br_ring[prod_head] =3D buf;
+
+	/*
+	 * The full memory barrier also avoids that br_prod_tail store
+	 * is reordered before the br_ring[prod_head] is full setup.
+	 */
+	mb();
+
+	/*
+	 * If there are other enqueues in progress
+	 * that preceeded us, we need to wait for them
+	 * to complete=20
+	 */  =20
+	while (br->br_prod_tail !=3D prod_head)
+		cpu_spinwait();
+	br->br_prod_tail =3D prod_next;
+	critical_exit();
+	return (0);
+}
+
+/*
+ * multi-consumer safe dequeue=20
+ *
+ */
+void *
+buf_ring_dequeue_mc(struct buf_ring *br)
+{
+	uint32_t cons_head, cons_next;
+	uint32_t prod_tail;
+	void *buf;
+	int success;
+
+	critical_enter();
+	do {
+		cons_head =3D br->br_cons_head;
+		prod_tail =3D br->br_prod_tail;
+
+		cons_next =3D (cons_head + 1) & br->br_cons_mask;
+	=09
+		if (cons_head =3D=3D prod_tail) {
+			critical_exit();
+			return (NULL);
+		}
+	=09
+		success =3D atomic_cmpset_int(&br->br_cons_head, =
cons_head,
+		    cons_next);
+	} while (success =3D=3D 0);	=09
+
+	buf =3D br->br_ring[cons_head];
+#ifdef DEBUG_BUFRING
+	br->br_ring[cons_head] =3D NULL;
+#endif
+	/*
+	 * The full memory barrier also avoids that br_ring[cons_read]
+	 * load is reordered after br_cons_tail is set.
+	 */
+	mb();
+=09
+	/*
+	 * If there are other dequeues in progress
+	 * that preceeded us, we need to wait for them
+	 * to complete=20
+	 */  =20
+	while (br->br_cons_tail !=3D cons_head)
+		cpu_spinwait();
+
+	br->br_cons_tail =3D cons_next;
+	critical_exit();
+
+	return (buf);
+}
+
+/*
+ * single-consumer dequeue=20
+ * use where dequeue is protected by a lock
+ * e.g. a network driver's tx queue lock
+ */
+void *
+buf_ring_dequeue_sc(struct buf_ring *br)
+{
+	uint32_t cons_head, cons_next, cons_next_next;
+	uint32_t prod_tail;
+	void *buf;
+=09
+	cons_head =3D br->br_cons_head;
+	prod_tail =3D br->br_prod_tail;
+=09
+	cons_next =3D (cons_head + 1) & br->br_cons_mask;
+	cons_next_next =3D (cons_head + 2) & br->br_cons_mask;
+=09
+	if (cons_head =3D=3D prod_tail)=20
+		return (NULL);
+
+#ifdef PREFETCH_DEFINED=09
+	if (cons_next !=3D prod_tail) {	=09
+		prefetch(br->br_ring[cons_next]);
+		if (cons_next_next !=3D prod_tail)=20
+			prefetch(br->br_ring[cons_next_next]);
+	}
+#endif
+	br->br_cons_head =3D cons_next;
+	buf =3D br->br_ring[cons_head];
+
+#ifdef DEBUG_BUFRING
+	br->br_ring[cons_head] =3D NULL;
+#endif
+	br->br_cons_tail =3D cons_next;
+	return (buf);
+}
+
+/*
+ * single-consumer advance after a peek
+ * use where it is protected by a lock
+ * e.g. a network driver's tx queue lock
+ */
+void
+buf_ring_advance_sc(struct buf_ring *br)
+{
+	uint32_t cons_head, cons_next;
+	uint32_t prod_tail;
+=09
+	cons_head =3D br->br_cons_head;
+	prod_tail =3D br->br_prod_tail;
+=09
+	cons_next =3D (cons_head + 1) & br->br_cons_mask;
+	if (cons_head =3D=3D prod_tail)=20
+		return;
+	br->br_cons_head =3D cons_next;
+	br->br_cons_tail =3D cons_next;
+}
+
+void
+buf_ring_advance_mc(struct buf_ring *br)
+{
+	uint32_t cons_head, cons_next;
+	uint32_t prod_tail;
+	int success;
+
+	critical_enter();
+	do {
+		cons_head =3D br->br_cons_head;
+		prod_tail =3D br->br_prod_tail;
+
+		cons_next =3D (cons_head + 1) & br->br_cons_mask;
+	=09
+		if (cons_head =3D=3D prod_tail) {
+			critical_exit();
+			return;
+		}
+	=09
+		success =3D atomic_cmpset_int(&br->br_cons_head, =
cons_head,
+		    cons_next);
+	} while (success =3D=3D 0);	=09
+	/*
+	 * The full memory barrier also avoids that br_ring[cons_read]
+	 * load is reordered after br_cons_tail is set.
+	 */
+	mb();
+=09
+	/*
+	 * If there are other dequeues in progress
+	 * that preceeded us, we need to wait for them
+	 * to complete=20
+	 */  =20
+	while (br->br_cons_tail !=3D cons_head)
+		cpu_spinwait();
+
+	br->br_cons_tail =3D cons_next;
+	critical_exit();
+}
+
+
+/*
+ * Used to return a buffer (most likely already there)
+ * to the top od the ring. The caller should *not*
+ * have used any dequeue to pull it out of the ring
+ * but instead should have used the peek() function.
+ * This is normally used where the transmit queue
+ * of a driver is full, and an mubf must be returned.
+ * Most likely whats in the ring-buffer is what
+ * is being put back (since it was not removed), but
+ * sometimes the lower transmit function may have
+ * done a pullup or other function that will have
+ * changed it. As an optimzation we always put it
+ * back (since jhb says the store is probably cheaper),
+ * if we have to do a multi-queue version we will need
+ * the compare and an atomic.
+ */
+void
+buf_ring_putback_mc(struct buf_ring *br, void *new)
+{
+	KASSERT(br->br_cons_head !=3D br->br_prod_tail,=20
+		("Buf-Ring has none in putback")) ;
+	critical_enter();
+	br->br_ring[br->br_cons_head] =3D new;
+	mb();
+	critical_exit();
+}
+
+void
+buf_ring_putback_sc(struct buf_ring *br, void *new)
+{
+	KASSERT(br->br_cons_head !=3D br->br_prod_tail,=20
+		("Buf-Ring has none in putback")) ;
+	br->br_ring[br->br_cons_head] =3D new;
+}
+
+/*
+ * return a pointer to the first entry in the ring
+ * without modifying it, or NULL if the ring is empty
+ * race-prone if not protected by a lock
+ */
+void *
+buf_ring_peek(struct buf_ring *br)
+{
+	struct mbuf *m;
+#ifdef DEBUG_BUFRING
+	if ((br->br_lock !=3D NULL) && !mtx_owned(br->br_lock)) {
+		printf("br:%p lock not held on single consumer =
dequeue\n",
+		       br);
+	}
+
+#endif=09
+	if (br->br_cons_head =3D=3D br->br_prod_tail)
+		return (NULL);
+	m =3D br->br_ring[br->br_cons_head];
+#ifdef DEBUG_BUFRING
+	br->br_ring[br->br_cons_head] =3D NULL;
+	mb();
+#endif
+	return (m);
+}
+
+int
+buf_ring_full(struct buf_ring *br)
+{
+
+	return (((br->br_prod_head + 1) & br->br_prod_mask) =3D=3D =
br->br_cons_tail);
+}
+
+int
+buf_ring_empty(struct buf_ring *br)
+{
+
+	return (br->br_cons_head =3D=3D br->br_prod_tail);
+}
+
+int
+buf_ring_count(struct buf_ring *br)
+{
+
+	return ((br->br_prod_size + br->br_prod_tail - br->br_cons_tail)
+	    & br->br_prod_mask);
+}
Index: sys/kern/subr_bus.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/kern/subr_bus.c	(revision 257322)
+++ sys/kern/subr_bus.c	(working copy)
@@ -2722,7 +2722,7 @@ device_probe(device_t dev)
 	}
 	return (0);
 }
-
+uint32_t simp_bus_debug=3D0;
 /**
  * @brief Probe a device and attach a driver if possible
  *
@@ -2742,6 +2742,11 @@ device_probe_and_attach(device_t dev)
 		return (error);
=20
 	CURVNET_SET_QUIET(vnet0);
+	if (simp_bus_debug) {
+		printf("%s:Attach for device 0x%x\n",=20
+		       __FUNCTION__,
+		       (uint32_t)dev);
+	}
 	error =3D device_attach(dev);
 	CURVNET_RESTORE();
 	return error;
@@ -2778,12 +2783,20 @@ device_attach(device_t dev)
 			 device_printf(dev, "disabled via hints =
entry\n");
 		return (ENXIO);
 	}
-
+	if (simp_bus_debug) {
+		device_printf(dev, "init its sysctl info\n");
+	}
 	device_sysctl_init(dev);
 	if (!device_is_quiet(dev))
 		device_print_child(dev->parent, dev);
 	attachtime =3D get_cyclecount();
 	dev->state =3D DS_ATTACHING;
+	if (simp_bus_debug) {
+		device_printf(dev, "Calling attach\n");
+	}
+	if (simp_bus_debug) {
+		device_printf(dev, "call the attach\n");
+	}
 	if ((error =3D DEVICE_ATTACH(dev)) !=3D 0) {
 		printf("device_attach: %s%d attach returned %d\n",
 		    dev->driver->name, dev->unit, error);
@@ -2812,6 +2825,9 @@ device_attach(device_t dev)
 	else
 		dev->state =3D DS_ATTACHED;
 	dev->flags &=3D ~DF_DONENOMATCH;
+	if (simp_bus_debug) {
+		device_printf(dev, "finish out...\n");
+	}
 	devadded(dev);
 	return (0);
 }
Index: sys/net/drbr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/net/drbr.c	(revision 0)
+++ sys/net/drbr.c	(working copy)
@@ -0,0 +1,507 @@
+#include <net/drbr.h>
+
+SYSCTL_DECL(_net_link);
+uint32_t drbr_maxq=3DDRBR_MAXQ_DEFAULT;
+
+TUNABLE_INT("net.link.drbr_maxq", &drbr_maxq);
+SYSCTL_NODE(_net, OID_AUTO, drbr, CTLFLAG_RD, 0, "DRBR Parameters");
+SYSCTL_INT(_net_drbr, OID_AUTO, drbr_maxq, CTLFLAG_RDTUN,
+    &drbr_maxq, 0, "max number of priority queues per interface");
+
+uint8_t set_up_drbr_depth=3D0;
+uint32_t drbr_max_priority=3DDRBR_MAXQ_DEFAULT-1;
+uint32_t drbr_queue_depth=3DDRBR_MIN_DEPTH;
+uint32_t panic_on_dup_buf =3D 0;
+uint32_t use_drbr_lock =3D 0;
+
+SYSCTL_INT(_net_drbr, OID_AUTO, drbr_queue_depth, CTLFLAG_RD,
+    &drbr_queue_depth, 0, "Queue length configed via ifqmaxlen");
+
+SYSCTL_INT(_net_drbr, OID_AUTO, drbr_max_priority, CTLFLAG_RD,
+    &drbr_max_priority, 0, "Queue length configed via ifqmaxlen");
+
+SYSCTL_INT(_net_drbr, OID_AUTO, drbr_panicdup, CTLFLAG_RW,
+    &panic_on_dup_buf, 0, "Panic on dup buf into br ring");
+
+SYSCTL_INT(_net_drbr, OID_AUTO, drbr_usemtx, CTLFLAG_RW,
+    &use_drbr_lock, 0, "Use drbr mtx");
+
+struct drbr_ring *
+drbr_alloc(struct malloc_type *type, int flags, struct mtx *tmtx)
+{
+	struct drbr_ring *rng;
+	int i;
+	if (set_up_drbr_depth =3D=3D 0) {
+		drbr_max_priority =3D drbr_maxq-1;
+		set_up_drbr_depth =3D 1;
+		drbr_queue_depth =3D 1 << ((fls(ifqmaxlen)-1));
+		if (drbr_queue_depth < DRBR_MIN_DEPTH) {
+			drbr_queue_depth =3D DRBR_MIN_DEPTH;
+		}
+	}
+	rng =3D (struct drbr_ring *)malloc(sizeof(struct drbr_ring), =
type, flags);
+	if (rng =3D=3D NULL) {
+		return(NULL);
+	}
+	memset(rng, 0, sizeof(struct drbr_ring));
+	DRBR_LOCK_INIT(rng);
+	rng->re =3D (struct drbr_ring_entry *)malloc((sizeof(struct =
drbr_ring_entry)*drbr_maxq),=20
+			 type, flags);
+	if (rng->re =3D=3D NULL) {
+		free(rng, type);
+		return(NULL);
+	}
+	memset(rng->re, 0, (sizeof(struct drbr_ring_entry) * =
drbr_maxq));
+	/* Ok get the queues */
+	for (i=3D0; i<drbr_maxq; i++) {
+		rng->re[i].re_qs =3D buf_ring_alloc(drbr_queue_depth, =
type, flags, tmtx);
+		if (rng->re[i].re_qs =3D=3D NULL) {
+			goto out_err;
+		}
+	}
+	rng->lowq_with_data =3D 0xffffffff;
+	return(rng);
+out_err:
+	for(i=3D0; i<drbr_maxq; i++) {
+		if (rng->re[i].re_qs) {
+			free(rng->re[i].re_qs, type);
+		}
+	}
+	free(rng->re, type);
+	free(rng, type);
+	return (NULL);
+}
+
+#define PRIO_NAME_LEN 32
+void=20
+drbr_add_sysctl_stats(device_t dev, struct sysctl_oid_list *queue_list,=20=

+		      struct drbr_ring *rng)
+{
+	int i;
+	struct sysctl_ctx_list *ctx =3D device_get_sysctl_ctx(dev);
+	struct sysctl_oid *prio_node;
+	struct sysctl_oid_list *prio_list;
+	char namebuf[PRIO_NAME_LEN];
+
+	if (rng =3D=3D NULL)
+		/* TSNH */
+		return;
+	for (i=3D0; i<drbr_maxq; i++) {
+		snprintf(namebuf, PRIO_NAME_LEN, "prio%d", i);
+	=09
+		prio_node =3D SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, =
namebuf,
+					    CTLFLAG_RD, NULL, "Prioity =
Info");
+		prio_list =3D SYSCTL_CHILDREN(prio_node);
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"packets_sent",
+				CTLFLAG_RD, &rng->re[i].re_cnt_sent,
+				"Packets Enqueued");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, "bytes_sent",
+				CTLFLAG_RD, &rng->re[i].re_bytecnt_sent,
+				"Bytes Enqueued");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"dropped_packets",
+				CTLFLAG_RD, &rng->re[i].re_drop_cnt,
+				"Packets Dropped");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"dropped_bytes",
+				CTLFLAG_RD, &rng->re[i].re_bytedrop_cnt,
+				"Bytes Dropped");
+		SYSCTL_ADD_UINT(ctx, prio_list, OID_AUTO, =
"on_queue_now",
+				CTLFLAG_RD, &rng->re[i].re_cnt, 0,
+				"Current Queue Size");
+
+	}
+
+}
+
+u_long
+drbr_get_dropcnt(struct drbr_ring *rng)
+{
+	u_long total;
+	int i;
+
+	total =3D 0;
+	for (i=3D0; i<drbr_maxq; i++) {
+		total +=3D rng->re[i].re_drop_cnt;
+	}
+	return (total);
+}
+
+void=20
+drbr_add_sysctl_stats_nodev(struct sysctl_oid_list *queue_list,=20
+			    struct sysctl_ctx_list *ctx,
+			    struct drbr_ring *rng)
+{
+	int i;
+	struct sysctl_oid *prio_node;
+	struct sysctl_oid_list *prio_list;
+	char namebuf[PRIO_NAME_LEN];
+
+	if (rng =3D=3D NULL)
+		return;
+	for (i=3D0; i<drbr_maxq; i++) {
+		snprintf(namebuf, PRIO_NAME_LEN, "prio%d", i);
+		prio_node =3D SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, =
namebuf,
+					CTLFLAG_RD, NULL, "Prioity =
Info");
+		prio_list =3D SYSCTL_CHILDREN(prio_node);
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"packets_sent",
+				CTLFLAG_RD, &rng->re[i].re_cnt_sent,
+				"Packets Enqueued");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, "bytes_sent",
+				CTLFLAG_RD, &rng->re[i].re_bytecnt_sent,
+				"Bytes Enqueued");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"dropped_packets",
+				CTLFLAG_RD, &rng->re[i].re_drop_cnt,
+				"Packets Dropped");
+		SYSCTL_ADD_QUAD(ctx, prio_list, OID_AUTO, =
"dropped_bytes",
+				CTLFLAG_RD, &rng->re[i].re_bytedrop_cnt,
+				"Bytes Dropped");
+		SYSCTL_ADD_UINT(ctx, prio_list, OID_AUTO, =
"on_queue_now",
+				CTLFLAG_RD, &rng->re[i].re_cnt, 0,
+				"Current Queue Size");
+	}
+}
+
+int
+drbr_enqueue(struct ifnet *ifp, struct drbr_ring *rng, struct mbuf *m)
+{=09
+	int error =3D 0;
+	uint8_t qused;
+	uint64_t bytecnt;
+	int locked =3D 0;
+
+#ifdef ALTQ
+	if ((ifp !=3D NULL) &&=20
+	    (ALTQ_IS_ENABLED(&ifp->if_snd))) {
+		IFQ_ENQUEUE(&ifp->if_snd, m, error);
+		return (error);
+	}
+#endif
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	if (m->m_pkthdr.cosqos >=3D drbr_maxq) {
+		/* Lowest priority queue */
+		qused =3D drbr_maxq - 1;
+	} else {
+		qused =3D m->m_pkthdr.cosqos;
+	}
+	bytecnt =3D m->m_pkthdr.len;
+	error =3D buf_ring_enqueue(rng->re[qused].re_qs, m);
+        if (error) {
+		m_freem(m);
+		atomic_add_long(&rng->re[qused].re_drop_cnt, 1);
+		atomic_add_long(&rng->re[qused].re_bytedrop_cnt, =
bytecnt);
+	} else {
+		if (qused < rng->lowq_with_data) {
+			atomic_clear_int(&rng->lowq_with_data, =
0xffffffff);
+			atomic_set_int(&rng->lowq_with_data, qused);
+		}
+		atomic_add_int(&rng->count_on_queues, 1);
+		atomic_add_int(&rng->re[qused].re_cnt, 1);
+		atomic_add_long(&rng->re[qused].re_cnt_sent, 1);
+		atomic_add_long(&rng->re[qused].re_bytecnt_sent, =
bytecnt);
+	}
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	return (error);
+}
+
+int
+drbr_is_on_ring(struct drbr_ring *rng, struct mbuf *m)
+{
+	int locked =3D 0;
+	int answer =3D 0; /* No its not by default */
+	int i;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	for(i=3D0; i<drbr_maxq;i++) {
+		if (buf_ring_empty(rng->re[i].re_qs))
+			continue;
+		if (buf_ring_mbufon(rng->re[i].re_qs, m)) {
+			answer =3D 1;
+			break;
+		}
+	}=09
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	return(answer);
+}
+
+void
+drbr_putback(struct ifnet *ifp, struct drbr_ring *rng, struct mbuf =
*new, uint8_t qused)
+{
+	/*
+	 * The top of the list needs to be swapped=20
+	 * for this one.
+	 */
+	int locked =3D 0;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	buf_ring_putback_mc(rng->re[qused].re_qs, new);
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+}
+
+struct mbuf *
+drbr_peek(struct ifnet *ifp, struct drbr_ring *rng, uint8_t *qused)
+{
+	int i;
+	int locked =3D 0;
+	struct mbuf *m;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	if (rng->count_on_queues =3D=3D 0) {
+		/* All done now */
+		if (locked) {
+			DRBR_UNLOCK(rng);
+		}
+		return (NULL);
+	}
+	if (rng->lowq_with_data =3D=3D 0xffffffff) {
+		rng->lowq_with_data =3D 0;
+	}
+	for(i=3Drng->lowq_with_data; i<drbr_maxq;i++) {
+		if (buf_ring_empty(rng->re[i].re_qs))
+			continue;
+		rng->lowq_with_data =3D i;
+		break;
+	}
+	if (i >=3D drbr_maxq) {
+		/* Huh? */
+		rng->lowq_with_data =3D 0;
+        	for (i=3Drng->lowq_with_data; i<drbr_maxq;i++) {
+	        	if(buf_ring_empty(rng->re[i].re_qs))
+		        	continue;
+			rng->lowq_with_data =3D i;
+         		break;
+        	}
+		if (i >=3D drbr_maxq) {
+			/* Really huh? */
+			rng->count_on_queues =3D 0;
+			if (locked) {
+				DRBR_UNLOCK(rng);
+			}
+			return (NULL);
+                }
+        }
+	*qused =3D i;
+	m =3D buf_ring_peek(rng->re[i].re_qs);
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	return(m);
+}
+
+static void
+drbr_flush_locked(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	int i;
+	struct mbuf *m;
+	int locked =3D 0;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	if (rng =3D=3D NULL) {
+		return;
+	}
+	for(i=3D0; i<drbr_maxq; i++) {
+		while ((m =3D buf_ring_dequeue_mc(rng->re[i].re_qs)) !=3D =
NULL) {
+			atomic_subtract_long(&rng->re[i].re_cnt_sent, =
1);
+			if (ifp) {
+				ifp->if_oerrors++;
+			}
+			m_freem(m);
+		}
+		rng->re[i].re_cnt =3D 0;
+	}
+	rng->lowq_with_data =3D 0xffffffff;
+	rng->count_on_queues =3D 0;
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+}
+
+void
+drbr_flush(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	drbr_flush_locked(ifp, rng);
+}
+
+void
+drbr_free(struct drbr_ring *rng, struct malloc_type *type)
+{
+	int i;
+	int locked =3D 0;
+	if (rng =3D=3D NULL) {
+		return;
+	}
+	drbr_flush_locked(NULL, rng);
+
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	for(i=3D0; i<drbr_maxq; i++) {
+		if (rng->re[i].re_qs) {
+			buf_ring_free(rng->re[i].re_qs, type);
+		}
+	}
+	DRBR_LOCK_DESTROY(rng);
+	free(rng->re, type);
+	free(rng, type);
+}
+
+struct mbuf *
+drbr_dequeue(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	int i;
+	struct mbuf *m;
+	int locked =3D 0;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	if (rng->count_on_queues =3D=3D 0) {
+		if (locked) {
+			DRBR_UNLOCK(rng);
+		}
+		return (NULL);
+	}
+	if (rng->lowq_with_data =3D=3D 0xffffffff) {
+		rng->lowq_with_data =3D 0;
+	}
+	for(i=3Drng->lowq_with_data; i<drbr_maxq;i++) {
+		if (buf_ring_empty(rng->re[i].re_qs))
+			continue;
+		rng->lowq_with_data =3D i;
+		break;
+	}
+#ifdef INVARIANT
+	if (i >=3D drbr_maxq) {
+		/* Nothing on ring from marker up? */
+		rng->lowq_with_data =3D 0;
+        	for (i=3Drng->lowq_with_data; i<drbr_maxq;i++) {
+	        	if(buf_ring_empty(rng->re[i].re_qs))
+		        	continue;
+			rng->lowq_with_data =3D i;
+         		break;
+        	}
+		if (i >=3D drbr_maxq) {
+			/* Count was off? */
+			rng->count_on_queues =3D 0;
+			if (locked) {
+				DRBR_UNLOCK(rng);
+			}
+			return (NULL);
+                }
+        }
+#else
+	if (i >=3D drbr_maxq) {
+		/* Huh */
+		i =3D 0;
+	}
+#endif
+	m =3D buf_ring_dequeue_mc(rng->re[i].re_qs);
+	if (m) {
+		atomic_subtract_int(&rng->re[i].re_cnt, 1);
+		atomic_subtract_int(&rng->count_on_queues, 1);
+		if (rng->count_on_queues =3D=3D 0) {
+			atomic_set_int(&rng->lowq_with_data, =
0xffffffff);
+		}
+	} else {
+		/* TSNH */
+		rng->re[i].re_cnt =3D 0;
+	}
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	return(m);
+}
+
+void
+drbr_advance(struct ifnet *ifp, struct drbr_ring *rng, uint8_t qused)
+{
+	int locked =3D 0;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	if (rng->count_on_queues =3D=3D 0) {
+		/* Huh? */
+		if (locked) {
+			DRBR_UNLOCK(rng);
+		}
+		return;
+	}
+	atomic_subtract_int(&rng->count_on_queues, 1);
+	if (rng->count_on_queues =3D=3D 0) {
+		atomic_set_int(&rng->lowq_with_data, 0xffffffff);
+	}
+	buf_ring_advance_mc(rng->re[qused].re_qs);
+	atomic_subtract_int(&rng->re[qused].re_cnt, 1);
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+}
+
+struct mbuf *
+drbr_dequeue_cond(struct ifnet *ifp, struct drbr_ring *rng,
+    int (*func) (struct mbuf *, void *), void *arg)=20
+{
+	uint8_t qused;
+	struct mbuf *m;
+	int locked =3D 0;
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	}
+	qused =3D 0;
+	m =3D drbr_peek(ifp, rng, &qused);
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	if (m =3D=3D NULL || func(m, arg) =3D=3D 0) {
+		return (NULL);
+	}
+	if (use_drbr_lock) {
+		DRBR_LOCK(rng);
+		locked =3D 1;
+	} else {
+		locked =3D 0;
+	}
+	atomic_subtract_int(&rng->re[qused].re_cnt, 1);
+	atomic_subtract_int(&rng->count_on_queues, 1);
+	m =3D buf_ring_dequeue_mc(rng->re[qused].re_qs);
+	if (locked) {
+		DRBR_UNLOCK(rng);
+	}
+	return (m);
+}
+
+int
+drbr_empty(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	return (!rng->count_on_queues);
+}
+
+int
+drbr_needs_enqueue(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	return (!(rng->count_on_queues =3D=3D 0));
+}
+
+int
+drbr_inuse(struct ifnet *ifp, struct drbr_ring *rng)
+{
+	return (rng->count_on_queues);
+}

Property changes on: sys/net/drbr.c
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=3D%H
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: sys/net/drbr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/net/drbr.h	(revision 0)
+++ sys/net/drbr.h	(working copy)
@@ -0,0 +1,89 @@
+#ifndef __drbr_h__
+#define __drbr_h__
+#include <sys/param.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#include <sys/buf_ring.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/pcpu.h>
+#include <sys/smp.h>
+#include <sys/bus.h>
+#include <machine/smp.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#endif
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+
+#define DRBR_MAXQ_DEFAULT 8
+#define DRBR_MIN_DEPTH 64	/* Must be power of 2 */
+
+#define USE_LOCK
+
+#ifdef _KERNEL
+extern uint32_t drbr_maxq;
+#endif
+
+struct drbr_ring_entry {
+	struct buf_ring		*re_qs;		/* Ring itself */
+	u_long			re_drop_cnt;	/* Drop count in pkts */
+	u_long			re_bytedrop_cnt;/* Drop count in bytes =
*/
+	u_long			re_cnt_sent;	/* Total sent in pkts */
+	u_long			re_bytecnt_sent;/* Total sent in bytes =
*/
+	uint32_t		re_cnt;		/* Count on ring */
+};
+
+#define DRBR_LOCK_INIT(rng) mtx_init(&(rng)->rng_mtx, "drbr_lock", =
"drbr", MTX_DEF | MTX_DUPOK)
+#define DRBR_LOCK_DESTROY(rng) 	mtx_destroy(&(rng)->rng_mtx)
+#define DRBR_LOCK(rng) 	mtx_lock(&(rng)->rng_mtx)
+#define DRBR_UNLOCK(rng) mtx_unlock(&(rng)->rng_mtx)
+#define DRBR_LOCK_OWNED(rng) mtx_owned(&(rng)->rng_mtx)
+
+struct drbr_ring {
+#ifdef _KERNEL
+	struct mtx 		rng_mtx;
+#endif
+	struct drbr_ring_entry *re;
+	uint32_t		count_on_queues;
+	uint32_t		lowq_with_data;
+};
+
+#ifdef _KERNEL
+struct drbr_ring *
+drbr_alloc(struct malloc_type *type, int flags, struct mtx *tmtx);
+int drbr_enqueue(struct ifnet *ifp, struct drbr_ring *rng, struct mbuf =
*m);
+void drbr_putback(struct ifnet *ifp, struct drbr_ring *rng, struct mbuf =
*new,=20
+	uint8_t qused);
+struct mbuf *drbr_peek(struct ifnet *ifp, struct drbr_ring *rng,
+	uint8_t *qused);
+void drbr_flush(struct ifnet *ifp, struct drbr_ring *rng);
+void drbr_free(struct drbr_ring *rng, struct malloc_type *type);
+struct mbuf *drbr_dequeue(struct ifnet *ifp, struct drbr_ring *rng);
+void drbr_advance(struct ifnet *ifp, struct drbr_ring *rng, uint8_t =
qused);
+struct mbuf *
+drbr_dequeue_cond(struct ifnet *ifp, struct drbr_ring *rng,
+	int (*func) (struct mbuf *, void *), void *arg) ;
+int drbr_empty(struct ifnet *ifp, struct drbr_ring *rng);
+int drbr_needs_enqueue(struct ifnet *ifp, struct drbr_ring *rng);
+int drbr_inuse(struct ifnet *ifp, struct drbr_ring *rng);
+void drbr_add_sysctl_stats(device_t dev, struct sysctl_oid_list =
*queue_list,=20
+      struct drbr_ring *rng);
+void=20
+drbr_add_sysctl_stats_nodev(struct sysctl_oid_list *queue_list,=20
+      struct sysctl_ctx_list *ctx,
+      struct drbr_ring *rng);
+
+int drbr_is_on_ring(struct drbr_ring *rng, struct mbuf *m);
+u_long drbr_get_dropcnt(struct drbr_ring *rng);
+
+#endif
+
+#endif

Property changes on: sys/net/drbr.h
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=3D%H
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: sys/net/if_var.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/net/if_var.h	(revision 257322)
+++ sys/net/if_var.h	(working copy)
@@ -205,7 +205,14 @@ struct ifnet {
 	 */
 	char	if_cspare[3];
 	int	if_ispare[4];
-	void	*if_pspare[8];		/* 1 netmap, 7 TDB */
+	/* Set max bytes on ring - buffer bloat managment */
+	void    (*if_maxbytes)(struct ifnet *, uint64_t maxbytes);
+	/* Get a drbr ring to peak at */
+	struct drbr_ring * (*if_getdrbr_ring)(struct ifnet *, int =
queuenum);
+	/* Is this mbuf on one of your rings? */
+	int    (*if_mbuf_on_ring)(struct ifnet *, struct mbuf *);
+
+	void	*if_pspare[5];		/* 1 netmap, 4 TDB */
 };
=20
 /*
@@ -599,165 +606,7 @@ if_initbaudrate(struct ifnet *ifp, uintmax_t baud)
 	ifp->if_baudrate =3D baud;
 }
=20
-static __inline int
-drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
-{=09
-	int error =3D 0;
-
-#ifdef ALTQ
-	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
-		IFQ_ENQUEUE(&ifp->if_snd, m, error);
-		return (error);
-	}
 #endif
-	error =3D buf_ring_enqueue(br, m);
-	if (error)
-		m_freem(m);
-
-	return (error);
-}
-
-static __inline void
-drbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new)
-{
-	/*
-	 * The top of the list needs to be swapped=20
-	 * for this one.
-	 */
-#ifdef ALTQ
-	if (ifp !=3D NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
-		/*=20
-		 * Peek in altq case dequeued it
-		 * so put it back.
-		 */
-		IFQ_DRV_PREPEND(&ifp->if_snd, new);
-		return;
-	}
-#endif
-	buf_ring_putback_sc(br, new);
-}
-
-static __inline struct mbuf *
-drbr_peek(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	struct mbuf *m;
-	if (ifp !=3D NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
-		/*=20
-		 * Pull it off like a dequeue
-		 * since drbr_advance() does nothing
-		 * for altq and drbr_putback() will
-		 * use the old prepend function.
-		 */
-		IFQ_DEQUEUE(&ifp->if_snd, m);
-		return (m);
-	}
-#endif
-	return(buf_ring_peek(br));
-}
-
-static __inline void
-drbr_flush(struct ifnet *ifp, struct buf_ring *br)
-{
-	struct mbuf *m;
-
-#ifdef ALTQ
-	if (ifp !=3D NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
-		IFQ_PURGE(&ifp->if_snd);
-#endif=09
-	while ((m =3D buf_ring_dequeue_sc(br)) !=3D NULL)
-		m_freem(m);
-}
-
-static __inline void
-drbr_free(struct buf_ring *br, struct malloc_type *type)
-{
-
-	drbr_flush(NULL, br);
-	buf_ring_free(br, type);
-}
-
-static __inline struct mbuf *
-drbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	struct mbuf *m;
-
-	if (ifp !=3D NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {=09
-		IFQ_DEQUEUE(&ifp->if_snd, m);
-		return (m);
-	}
-#endif
-	return (buf_ring_dequeue_sc(br));
-}
-
-static __inline void
-drbr_advance(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	/* Nothing to do here since peek dequeues in altq case */
-	if (ifp !=3D NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
-		return;
-#endif
-	return (buf_ring_advance_sc(br));
-}
-
-
-static __inline struct mbuf *
-drbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
-    int (*func) (struct mbuf *, void *), void *arg)=20
-{
-	struct mbuf *m;
-#ifdef ALTQ
-	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
-		IFQ_LOCK(&ifp->if_snd);
-		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
-		if (m !=3D NULL && func(m, arg) =3D=3D 0) {
-			IFQ_UNLOCK(&ifp->if_snd);
-			return (NULL);
-		}
-		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
-		IFQ_UNLOCK(&ifp->if_snd);
-		return (m);
-	}
-#endif
-	m =3D buf_ring_peek(br);
-	if (m =3D=3D NULL || func(m, arg) =3D=3D 0)
-		return (NULL);
-
-	return (buf_ring_dequeue_sc(br));
-}
-
-static __inline int
-drbr_empty(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	if (ALTQ_IS_ENABLED(&ifp->if_snd))
-		return (IFQ_IS_EMPTY(&ifp->if_snd));
-#endif
-	return (buf_ring_empty(br));
-}
-
-static __inline int
-drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	if (ALTQ_IS_ENABLED(&ifp->if_snd))
-		return (1);
-#endif
-	return (!buf_ring_empty(br));
-}
-
-static __inline int
-drbr_inuse(struct ifnet *ifp, struct buf_ring *br)
-{
-#ifdef ALTQ
-	if (ALTQ_IS_ENABLED(&ifp->if_snd))
-		return (ifp->if_snd.ifq_len);
-#endif
-	return (buf_ring_count(br));
-}
-#endif
 /*
  * 72 was chosen below because it is the size of a TCP/IP
  * header (40) + the minimum mss (32).
Index: sys/netinet/if_ether.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/netinet/if_ether.c	(revision 257322)
+++ sys/netinet/if_ether.c	(working copy)
@@ -283,6 +283,7 @@ arprequest(struct ifnet *ifp, const struct in_addr
 	sa.sa_len =3D 2;
 	m->m_flags |=3D M_BCAST;
 	m_clrprotoflags(m);	/* Avoid confusing lower layers. */
+	m->m_pkthdr.cosqos =3D 0; /* Highest Priority */
 	(*ifp->if_output)(ifp, m, &sa, NULL);
 	ARPSTAT_INC(txrequests);
 }
Index: sys/ofed/drivers/net/mlx4/en_tx.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/ofed/drivers/net/mlx4/en_tx.c	(revision 257322)
+++ sys/ofed/drivers/net/mlx4/en_tx.c	(working copy)
@@ -39,6 +39,7 @@
=20
 #include <net/ethernet.h>
 #include <net/if_vlan_var.h>
+#include <net/drbr.h>
 #include <sys/mbuf.h>
=20
 #include <netinet/in_systm.h>
@@ -78,7 +79,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *pr
 	mtx_init(&ring->comp_lock.m, "mlx4 comp", NULL, MTX_DEF);
=20
 	/* Allocate the buf ring */
-	ring->br =3D buf_ring_alloc(MLX4_EN_DEF_TX_QUEUE_SIZE, M_DEVBUF,
+	ring->br =3D drbr_alloc(M_DEVBUF,
 	    M_WAITOK, &ring->tx_lock.m);
 	if (ring->br =3D=3D NULL) {
 		en_err(priv, "Failed allocating tx_info ring\n");
@@ -155,7 +156,7 @@ err_bounce:
 	kfree(ring->bounce_buf);
 	ring->bounce_buf =3D NULL;
 err_tx:
-	buf_ring_free(ring->br, M_DEVBUF);
+	drbr_free(ring->br, M_DEVBUF);
 	kfree(ring->tx_info);
 	ring->tx_info =3D NULL;
 	return err;
@@ -167,7 +168,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *
 	struct mlx4_en_dev *mdev =3D priv->mdev;
 	en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
=20
-	buf_ring_free(ring->br, M_DEVBUF);
+	drbr_free(ring->br, M_DEVBUF);
 	if (ring->bf_enabled)
 		mlx4_bf_free(mdev->dev, &ring->bf);
 	mlx4_qp_remove(mdev->dev, &ring->qp);
@@ -925,6 +926,7 @@ mlx4_en_transmit_locked(struct ifnet *dev, int tx_
 	struct mlx4_en_tx_ring *ring;
 	struct mbuf *next;
 	int enqueued, err =3D 0;
+	uint8_t queue;
=20
 	ring =3D &priv->tx_ring[tx_ind];
 	if ((dev->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=3D=

@@ -940,16 +942,16 @@ mlx4_en_transmit_locked(struct ifnet *dev, int tx_
 			return (err);
 	}
 	/* Process the queue */
-	while ((next =3D drbr_peek(dev, ring->br)) !=3D NULL) {
+	while ((next =3D drbr_peek(dev, ring->br, &queue)) !=3D NULL) {
 		if ((err =3D mlx4_en_xmit(dev, tx_ind, &next)) !=3D 0) {
 			if (next =3D=3D NULL) {
-				drbr_advance(dev, ring->br);
+				drbr_advance(dev, ring->br, queue);
 			} else {
-				drbr_putback(dev, ring->br, next);
+				drbr_putback(dev, ring->br, next, =
queue);
 			}
 			break;
 		}
-		drbr_advance(dev, ring->br);
+		drbr_advance(dev, ring->br, queue);
 		enqueued++;
 		dev->if_obytes +=3D next->m_pkthdr.len;
 		if (next->m_flags & M_MCAST)
@@ -1027,12 +1029,10 @@ mlx4_en_qflush(struct ifnet *dev)
 {
 	struct mlx4_en_priv *priv =3D netdev_priv(dev);
 	struct mlx4_en_tx_ring *ring =3D priv->tx_ring;
-	struct mbuf *m;
=20
 	for (int i =3D 0; i < priv->tx_ring_num; i++, ring++) {
 		spin_lock(&ring->tx_lock);
-		while ((m =3D buf_ring_dequeue_sc(ring->br)) !=3D NULL)
-			m_freem(m);
+		drbr_flush(dev, ring->br);
 		spin_unlock(&ring->tx_lock);
 	}
 	if_qflush(dev);
Index: sys/ofed/drivers/net/mlx4/mlx4_en.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/ofed/drivers/net/mlx4/mlx4_en.h	(revision 257322)
+++ sys/ofed/drivers/net/mlx4/mlx4_en.h	(working copy)
@@ -285,7 +285,7 @@ struct mlx4_en_tx_ring {
 	void *buf;
 	u16 poll_cnt;
 	int blocked;
-	struct buf_ring *br;
+	struct drbr_ring *br;
 	struct mlx4_en_tx_info *tx_info;
 	u8 *bounce_buf;
 	u32 last_nr_txbb;
Index: sys/sys/buf_ring.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/sys/buf_ring.h	(revision 257322)
+++ sys/sys/buf_ring.h	(working copy)
@@ -61,176 +61,25 @@ struct buf_ring {
  * multi-producer safe lock-free ring buffer enqueue
  *
  */
-static __inline int
-buf_ring_enqueue(struct buf_ring *br, void *buf)
-{
-	uint32_t prod_head, prod_next;
-	uint32_t cons_tail;
-#ifdef DEBUG_BUFRING
-	int i;
-	for (i =3D br->br_cons_head; i !=3D br->br_prod_head;
-	     i =3D ((i + 1) & br->br_cons_mask))
-		if(br->br_ring[i] =3D=3D buf)
-			panic("buf=3D%p already enqueue at %d prod=3D%d =
cons=3D%d",
-			    buf, i, br->br_prod_tail, br->br_cons_tail);
-#endif=09
-	critical_enter();
-	do {
-		prod_head =3D br->br_prod_head;
-		cons_tail =3D br->br_cons_tail;
-
-		prod_next =3D (prod_head + 1) & br->br_prod_mask;
-	=09
-		if (prod_next =3D=3D cons_tail) {
-			br->br_drops++;
-			critical_exit();
-			return (ENOBUFS);
-		}
-	} while (!atomic_cmpset_int(&br->br_prod_head, prod_head, =
prod_next));
-#ifdef DEBUG_BUFRING
-	if (br->br_ring[prod_head] !=3D NULL)
-		panic("dangling value in enqueue");
-#endif=09
-	br->br_ring[prod_head] =3D buf;
-
-	/*
-	 * The full memory barrier also avoids that br_prod_tail store
-	 * is reordered before the br_ring[prod_head] is full setup.
-	 */
-	mb();
-
-	/*
-	 * If there are other enqueues in progress
-	 * that preceeded us, we need to wait for them
-	 * to complete=20
-	 */  =20
-	while (br->br_prod_tail !=3D prod_head)
-		cpu_spinwait();
-	br->br_prod_tail =3D prod_next;
-	critical_exit();
-	return (0);
-}
-
+int buf_ring_enqueue(struct buf_ring *br, void *buf);
 /*
  * multi-consumer safe dequeue=20
  *
  */
-static __inline void *
-buf_ring_dequeue_mc(struct buf_ring *br)
-{
-	uint32_t cons_head, cons_next;
-	uint32_t prod_tail;
-	void *buf;
-	int success;
-
-	critical_enter();
-	do {
-		cons_head =3D br->br_cons_head;
-		prod_tail =3D br->br_prod_tail;
-
-		cons_next =3D (cons_head + 1) & br->br_cons_mask;
-	=09
-		if (cons_head =3D=3D prod_tail) {
-			critical_exit();
-			return (NULL);
-		}
-	=09
-		success =3D atomic_cmpset_int(&br->br_cons_head, =
cons_head,
-		    cons_next);
-	} while (success =3D=3D 0);	=09
-
-	buf =3D br->br_ring[cons_head];
-#ifdef DEBUG_BUFRING
-	br->br_ring[cons_head] =3D NULL;
-#endif
-
-	/*
-	 * The full memory barrier also avoids that br_ring[cons_read]
-	 * load is reordered after br_cons_tail is set.
-	 */
-	mb();
-=09
-	/*
-	 * If there are other dequeues in progress
-	 * that preceeded us, we need to wait for them
-	 * to complete=20
-	 */  =20
-	while (br->br_cons_tail !=3D cons_head)
-		cpu_spinwait();
-
-	br->br_cons_tail =3D cons_next;
-	critical_exit();
-
-	return (buf);
-}
-
+void *buf_ring_dequeue_mc(struct buf_ring *br);
 /*
  * single-consumer dequeue=20
  * use where dequeue is protected by a lock
  * e.g. a network driver's tx queue lock
  */
-static __inline void *
-buf_ring_dequeue_sc(struct buf_ring *br)
-{
-	uint32_t cons_head, cons_next, cons_next_next;
-	uint32_t prod_tail;
-	void *buf;
-=09
-	cons_head =3D br->br_cons_head;
-	prod_tail =3D br->br_prod_tail;
-=09
-	cons_next =3D (cons_head + 1) & br->br_cons_mask;
-	cons_next_next =3D (cons_head + 2) & br->br_cons_mask;
-=09
-	if (cons_head =3D=3D prod_tail)=20
-		return (NULL);
-
-#ifdef PREFETCH_DEFINED=09
-	if (cons_next !=3D prod_tail) {	=09
-		prefetch(br->br_ring[cons_next]);
-		if (cons_next_next !=3D prod_tail)=20
-			prefetch(br->br_ring[cons_next_next]);
-	}
-#endif
-	br->br_cons_head =3D cons_next;
-	buf =3D br->br_ring[cons_head];
-
-#ifdef DEBUG_BUFRING
-	br->br_ring[cons_head] =3D NULL;
-	if (!mtx_owned(br->br_lock))
-		panic("lock not held on single consumer dequeue");
-	if (br->br_cons_tail !=3D cons_head)
-		panic("inconsistent list cons_tail=3D%d cons_head=3D%d",
-		    br->br_cons_tail, cons_head);
-#endif
-	br->br_cons_tail =3D cons_next;
-	return (buf);
-}
-
+void *buf_ring_dequeue_sc(struct buf_ring *br);
 /*
  * single-consumer advance after a peek
  * use where it is protected by a lock
  * e.g. a network driver's tx queue lock
  */
-static __inline void
-buf_ring_advance_sc(struct buf_ring *br)
-{
-	uint32_t cons_head, cons_next;
-	uint32_t prod_tail;
-=09
-	cons_head =3D br->br_cons_head;
-	prod_tail =3D br->br_prod_tail;
-=09
-	cons_next =3D (cons_head + 1) & br->br_cons_mask;
-	if (cons_head =3D=3D prod_tail)=20
-		return;
-	br->br_cons_head =3D cons_next;
-#ifdef DEBUG_BUFRING
-	br->br_ring[cons_head] =3D NULL;
-#endif
-	br->br_cons_tail =3D cons_next;
-}
-
+void buf_ring_advance_sc(struct buf_ring *br);
+void buf_ring_advance_mc(struct buf_ring *br);
 /*
  * Used to return a buffer (most likely already there)
  * to the top od the ring. The caller should *not*
@@ -247,65 +96,27 @@ struct buf_ring {
  * if we have to do a multi-queue version we will need
  * the compare and an atomic.
  */
-static __inline void
-buf_ring_putback_sc(struct buf_ring *br, void *new)
-{
-	KASSERT(br->br_cons_head !=3D br->br_prod_tail,=20
-		("Buf-Ring has none in putback")) ;
-	br->br_ring[br->br_cons_head] =3D new;
-}
-
+void buf_ring_putback_mc(struct buf_ring *br, void *new);
+void buf_ring_putback_sc(struct buf_ring *br, void *new);
 /*
  * return a pointer to the first entry in the ring
  * without modifying it, or NULL if the ring is empty
  * race-prone if not protected by a lock
  */
-static __inline void *
-buf_ring_peek(struct buf_ring *br)
-{
+void *buf_ring_peek(struct buf_ring *br);
=20
-#ifdef DEBUG_BUFRING
-	if ((br->br_lock !=3D NULL) && !mtx_owned(br->br_lock))
-		panic("lock not held on single consumer dequeue");
-#endif=09
-	/*
-	 * I believe it is safe to not have a memory barrier
-	 * here because we control cons and tail is worst case
-	 * a lagging indicator so we worst case we might
-	 * return NULL immediately after a buffer has been enqueued
-	 */
-	if (br->br_cons_head =3D=3D br->br_prod_tail)
-		return (NULL);
-=09
-	return (br->br_ring[br->br_cons_head]);
-}
+int buf_ring_full(struct buf_ring *br);
=20
-static __inline int
-buf_ring_full(struct buf_ring *br)
-{
+int buf_ring_empty(struct buf_ring *br);
=20
-	return (((br->br_prod_head + 1) & br->br_prod_mask) =3D=3D =
br->br_cons_tail);
-}
+int buf_ring_count(struct buf_ring *br);
=20
-static __inline int
-buf_ring_empty(struct buf_ring *br)
-{
-
-	return (br->br_cons_head =3D=3D br->br_prod_tail);
-}
-
-static __inline int
-buf_ring_count(struct buf_ring *br)
-{
-
-	return ((br->br_prod_size + br->br_prod_tail - br->br_cons_tail)
-	    & br->br_prod_mask);
-}
-
 struct buf_ring *buf_ring_alloc(int count, struct malloc_type *type, =
int flags,
     struct mtx *);
+
 void buf_ring_free(struct buf_ring *br, struct malloc_type *type);
=20
+int buf_ring_mbufon(struct buf_ring *br, void *buf);
=20
=20
 #endif
Index: usr.sbin/ofwdump/ofwdump.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- usr.sbin/ofwdump/ofwdump.c	(revision 257322)
+++ usr.sbin/ofwdump/ofwdump.c	(working copy)
@@ -63,6 +63,8 @@ usage(void)
 	exit(EX_USAGE);
 }
=20
+static int query_mode =3D 0;
+
 int
 main(int argc, char *argv[])
 {
@@ -72,10 +74,13 @@ main(int argc, char *argv[])
=20
 	aflag =3D pflag =3D rflag =3D Rflag =3D Sflag =3D 0;
 	Parg =3D NULL;
-	while ((opt =3D getopt(argc, argv, "-aprP:RS")) !=3D -1) {
+	while ((opt =3D getopt(argc, argv, "-aqprP:RS")) !=3D -1) {
 		if (opt =3D=3D '-')
 			break;
 		switch (opt) {
+		case 'q':
+			query_mode =3D 1;
+			break;
 		case 'a':
 			aflag =3D 1;
 			rflag =3D 1;
@@ -209,6 +214,7 @@ ofw_dump_node(int fd, phandle_t n, int level, int
 	static int nblen =3D 0;
 	int plen;
 	phandle_t c;
+	int my_prop =3D 0;
=20
 	if (!(raw || str)) {
 		ofw_indent(level * LVLINDENT);
@@ -218,9 +224,26 @@ ofw_dump_node(int fd, phandle_t n, int level, int
 			printf(": %.*s\n", (int)plen, (char *)nbuf);
 		else
 			putchar('\n');
+		if (query_mode) {
+			char input[100];
+			fprintf(stdout, "Dump properties (y or n)?");
+			fflush(stdout);
+			input[0] =3D 0;
+			fgets(input, sizeof(input), stdin);
+			if (input[0] =3D=3D 'y') {
+				my_prop =3D 1;
+			}
+		}
+	=09
 	}
 	if (prop)
 		ofw_dump_properties(fd, n, level, pmatch, raw, str);
+	if (my_prop) {
+		ofw_dump_properties(fd, n, level, pmatch, raw, str);
+		printf("Exiting\n");
+		exit(0);
+	}
+
 	if (rec) {
 		for (c =3D ofw_child(fd, n); c !=3D 0; c =3D =
ofw_peer(fd, c)) {
 			ofw_dump_node(fd, c, level + 1, rec, prop, =
pmatch,

--Apple-Mail=_49C5FDEE-E4BA-44F6-8F6A-342853C67ED4
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=us-ascii


------------------------------
Randall Stewart
803-317-4952 (cell)


--Apple-Mail=_49C5FDEE-E4BA-44F6-8F6A-342853C67ED4--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?40948D79-E890-4360-A3F2-BEC34A389C7E>