From 56b61ca27ace61b1f30aaeb54138d8114df56d00 Mon Sep 17 00:00:00 2001
From: Gleb Smirnoff <glebius@FreeBSD.org>
Date: Fri, 19 Sep 2014 09:01:19 +0000
Subject: [PATCH] Remove ifq_drops from struct ifqueue. Now queue drops are
 accounted in struct ifnet if_oqdrops.

Some netgraph modules used ifqueue w/o ifnet. Accounting of queue drops
is simply removed from them. There were no API to read this statistic.

Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
---
 share/man/man9/altq.9                                |  1 -
 sys/contrib/altq/altq/if_altq.h                      |  1 -
 sys/dev/ce/if_ce.c                                   |  1 -
 sys/dev/cp/if_cp.c                                   |  1 -
 sys/dev/ctau/if_ct.c                                 |  1 -
 sys/dev/cx/if_cx.c                                   |  1 -
 sys/dev/cxgb/cxgb_main.c                             |  2 +-
 sys/dev/lmc/if_lmc.c                                 |  1 +
 sys/dev/mxge/if_mxge.c                               |  2 +-
 sys/net/if.c                                         |  2 +-
 sys/net/if_debug.c                                   |  1 -
 sys/net/if_epair.c                                   |  2 +-
 sys/net/if_mib.c                                     |  3 ++-
 sys/net/ifq.h                                        | 10 ++++------
 sys/net/rtsock.c                                     |  6 ------
 sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c |  2 --
 sys/netgraph/bluetooth/drivers/h4/ng_h4.c            |  1 -
 sys/netgraph/ng_device.c                             |  1 -
 sys/netgraph/ng_iface.c                              |  5 +----
 sys/netgraph/ng_tty.c                                |  1 -
 sys/netpfil/pf/if_pflog.c                            |  1 -
 sys/netpfil/pf/if_pfsync.c                           |  2 +-
 22 files changed, 13 insertions(+), 35 deletions(-)

diff --git a/share/man/man9/altq.9 b/share/man/man9/altq.9
index fd9440420a98..e718027a5107 100644
--- a/share/man/man9/altq.9
+++ b/share/man/man9/altq.9
@@ -256,7 +256,6 @@ still work with
     struct mbuf *ifq_tail;             |    struct mbuf *ifq_tail;
     int          ifq_len;              |    int          ifq_len;
     int          ifq_maxlen;           |    int          ifq_maxlen;
-    int          ifq_drops;            |    int          ifq_drops;
  };                                    |    /* driver queue fields */
                                        |    ......
                                        |    /* altq related fields */
diff --git a/sys/contrib/altq/altq/if_altq.h b/sys/contrib/altq/altq/if_altq.h
index 9524c45177b3..7c4d1c2795cd 100644
--- a/sys/contrib/altq/altq/if_altq.h
+++ b/sys/contrib/altq/altq/if_altq.h
@@ -50,7 +50,6 @@ struct	ifaltq {
 	struct	mbuf *ifq_tail;
 	int	ifq_len;
 	int	ifq_maxlen;
-	int	ifq_drops;
 #ifdef __FreeBSD__
 	struct	mtx ifq_mtx;
 #endif
diff --git a/sys/dev/ce/if_ce.c b/sys/dev/ce/if_ce.c
index 6c5b7bb21a18..36c4ba47d98b 100644
--- a/sys/dev/ce/if_ce.c
+++ b/sys/dev/ce/if_ce.c
@@ -2408,7 +2408,6 @@ static int ng_ce_rcvdata (hook_p hook, struct mbuf *m, meta_p meta)
 #if __FreeBSD_version >= 500000
 	IF_LOCK (q);
 	if (_IF_QFULL (q)) {
-		_IF_DROP (q);
 		IF_UNLOCK (q);
 		CE_UNLOCK (bd);
 		splx (s);
diff --git a/sys/dev/cp/if_cp.c b/sys/dev/cp/if_cp.c
index 59f06a9cd232..ca6aaf40a038 100644
--- a/sys/dev/cp/if_cp.c
+++ b/sys/dev/cp/if_cp.c
@@ -2141,7 +2141,6 @@ static int ng_cp_rcvdata (hook_p hook, item_p item)
 	CP_LOCK (bd);
 	IF_LOCK (q);
 	if (_IF_QFULL (q)) {
-		_IF_DROP (q);
 		IF_UNLOCK (q);
 		CP_UNLOCK (bd);
 		splx (s);
diff --git a/sys/dev/ctau/if_ct.c b/sys/dev/ctau/if_ct.c
index 5041f7e68d81..5cf20ddf55e2 100644
--- a/sys/dev/ctau/if_ct.c
+++ b/sys/dev/ctau/if_ct.c
@@ -2083,7 +2083,6 @@ static int ng_ct_rcvdata (hook_p hook, item_p item)
 	CT_LOCK (bd);
 	IF_LOCK (q);
 	if (_IF_QFULL (q)) {
-		_IF_DROP (q);
 		IF_UNLOCK (q);
 		CT_UNLOCK (bd);
 		splx (s);
diff --git a/sys/dev/cx/if_cx.c b/sys/dev/cx/if_cx.c
index 5ec4b8e9aaf9..eecab5fadc4d 100644
--- a/sys/dev/cx/if_cx.c
+++ b/sys/dev/cx/if_cx.c
@@ -2421,7 +2421,6 @@ static int ng_cx_rcvdata (hook_p hook, item_p item)
 	CX_LOCK (bd);
 	IF_LOCK (q);
 	if (_IF_QFULL (q)) {
-		_IF_DROP (q);
 		IF_UNLOCK (q);
 		CX_UNLOCK (bd);
 		splx (s);
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 30001293b2bb..7488553680ae 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -2357,7 +2357,7 @@ cxgb_tick_handler(void *arg, int count)
 		drops = 0;
 		for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; j++)
 			drops += sc->sge.qs[j].txq[TXQ_ETH].txq_mr->br_drops;
-		ifp->if_snd.ifq_drops = drops;
+		ifp->if_oqdrops = drops;
 
 		ifp->if_oerrors =
 		    mstats->tx_excess_collisions +
diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c
index 766fdae392ab..f7cdac5ef6fb 100644
--- a/sys/dev/lmc/if_lmc.c
+++ b/sys/dev/lmc/if_lmc.c
@@ -4635,6 +4635,7 @@ lmc_raw_output(struct ifnet *ifp, struct mbuf *m,
     {
     m_freem(m);
     sc->status.cntrs.odiscards++;
+    ifp->if_oqdrops++;
     if (DRIVER_DEBUG)
       printf("%s: lmc_raw_output: IFQ_ENQUEUE() failed; error %d\n",
        NAME_UNIT, error);
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index e6cdf234407b..0dec649b3994 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -4069,7 +4069,7 @@ mxge_update_stats(mxge_softc_t *sc)
 #ifdef IFNET_BUF_RING
 	sc->ifp->if_obytes = obytes;
 	sc->ifp->if_omcasts = omcasts;
-	sc->ifp->if_snd.ifq_drops = odrops;
+	sc->ifp->if_oqdrops = odrops;
 #endif
 	sc->ifp->if_oerrors = oerrors;
 	return pkts;
diff --git a/sys/net/if.c b/sys/net/if.c
index 0f33726e5d6e..1b41b7e56155 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -3521,8 +3521,8 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
 
 	IF_LOCK(ifq);
 	if (_IF_QFULL(ifq)) {
-		_IF_DROP(ifq);
 		IF_UNLOCK(ifq);
+		ifp->if_oqdrops++;
 		m_freem(m);
 		return (0);
 	}
diff --git a/sys/net/if_debug.c b/sys/net/if_debug.c
index e731937462c9..1d198eb925f2 100644
--- a/sys/net/if_debug.c
+++ b/sys/net/if_debug.c
@@ -79,7 +79,6 @@ if_show_ifnet(struct ifnet *ifp)
 	IF_DB_PRINTF("%p", if_snd.ifq_tail);
 	IF_DB_PRINTF("%d", if_snd.ifq_len);
 	IF_DB_PRINTF("%d", if_snd.ifq_maxlen);
-	IF_DB_PRINTF("%d", if_snd.ifq_drops);
 	IF_DB_PRINTF("%p", if_snd.ifq_drv_head);
 	IF_DB_PRINTF("%p", if_snd.ifq_drv_tail);
 	IF_DB_PRINTF("%d", if_snd.ifq_drv_len);
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 3c5c94ed3e81..fd1120c41ff0 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -517,7 +517,7 @@ epair_transmit_locked(struct ifnet *ifp, struct mbuf *m)
 	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
 		ALTQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
 		if (error)
-			ifp->if_snd.ifq_drops++;
+			ifp->if_oqdrops++;
 		IF_UNLOCK(&ifp->if_snd);
 		if (!error) {
 			ifp->if_obytes += len;
diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c
index 3c90235aa043..b6d245a7aa8f 100644
--- a/sys/net/if_mib.c
+++ b/sys/net/if_mib.c
@@ -105,7 +105,8 @@ sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */
 		ifmd.ifmd_flags = ifp->if_flags | ifp->if_drv_flags;
 		ifmd.ifmd_snd_len = ifp->if_snd.ifq_len;
 		ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen;
-		ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops;
+		ifmd.ifmd_snd_drops =
+		    ifp->if_get_counter(ifp, IFCOUNTER_OQDROPS);
 
 		error = SYSCTL_OUT(req, &ifmd, sizeof ifmd);
 		if (error)
diff --git a/sys/net/ifq.h b/sys/net/ifq.h
index cf0c5066fea1..b787ea1cfa81 100644
--- a/sys/net/ifq.h
+++ b/sys/net/ifq.h
@@ -53,7 +53,6 @@ struct	ifqueue {
 	struct	mbuf *ifq_tail;
 	int	ifq_len;
 	int	ifq_maxlen;
-	int	ifq_drops;
 	struct	mtx ifq_mtx;
 };
 
@@ -68,7 +67,6 @@ struct	ifqueue {
 #define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
 #define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
 #define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
-#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
 #define	_IF_QLEN(ifq)		((ifq)->ifq_len)
 
 #define	_IF_ENQUEUE(ifq, m) do { 				\
@@ -171,8 +169,6 @@ do {									\
 			(err) = 0;					\
 		}							\
 	}								\
-	if (err)							\
-		(ifq)->ifq_drops++;					\
 	IF_UNLOCK(ifq);							\
 } while (0)
 
@@ -234,7 +230,6 @@ do {									\
 #define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
 #define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
 #define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
-#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
 #define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
 
 /*
@@ -255,7 +250,8 @@ do {									\
 			(ifp)->if_omcasts++;				\
 		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
 			if_start(ifp);					\
-	}								\
+	} else								\
+		ifp->if_oqdrops++;					\
 } while (0)
 
 #define	IFQ_HANDOFF(ifp, m, err)					\
@@ -321,6 +317,8 @@ drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
 #ifdef ALTQ
 	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
 		IFQ_ENQUEUE(&ifp->if_snd, m, error);
+		if (error)
+			ifp->if_oqdrops++;
 		return (error);
 	}
 #endif
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index a4d8148be3ce..6fcbbc6ec431 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1577,9 +1577,6 @@ sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
 
 	if_data_copy(ifp, ifd);
 
-	/* Some drivers still use ifqueue(9), add its stats. */
-	ifd->ifi_oqdrops += ifp->if_snd.ifq_drops;
-
 	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
 }
 
@@ -1612,9 +1609,6 @@ sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
 
 	if_data_copy(ifp, ifd);
 
-	/* Some drivers still use ifqueue(9), add its stats. */
-	ifd->ifi_oqdrops += ifp->if_snd.ifq_drops;
-
 	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
 }
 
diff --git a/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c b/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
index f2930abcdb02..9b174bb4c34e 100644
--- a/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
+++ b/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
@@ -560,7 +560,6 @@ ng_bt3c_rcvdata(hook_p hook, item_p item)
 		NG_BT3C_ERR(sc->dev,
 "Outgoing queue is full. Dropping mbuf, len=%d\n", m->m_pkthdr.len);
 
-		_IF_DROP(&sc->outq);
 		NG_BT3C_STAT_OERROR(sc->stat);
 
 		NG_FREE_M(m);
@@ -939,7 +938,6 @@ bt3c_receive(bt3c_softc_p sc)
 				NG_BT3C_ERR(sc->dev,
 "Incoming queue is full. Dropping mbuf, len=%d\n", sc->m->m_pkthdr.len);
 
-				_IF_DROP(&sc->inq);
 				NG_BT3C_STAT_IERROR(sc->stat);
 
 				NG_FREE_M(sc->m);
diff --git a/sys/netgraph/bluetooth/drivers/h4/ng_h4.c b/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
index 97cee2ed29ad..5cb0386b0ba6 100644
--- a/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
+++ b/sys/netgraph/bluetooth/drivers/h4/ng_h4.c
@@ -798,7 +798,6 @@ ng_h4_rcvdata(hook_p hook, item_p item)
 			NG_NODE_NAME(sc->node), m->m_pkthdr.len);
 
 		NG_H4_STAT_OERROR(sc->stat);
-		_IF_DROP(&sc->outq);
 
 		NG_H4_UNLOCK(sc);
 
diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c
index 723fbca8379e..cb40e69a9ae2 100644
--- a/sys/netgraph/ng_device.c
+++ b/sys/netgraph/ng_device.c
@@ -270,7 +270,6 @@ ng_device_rcvdata(hook_p hook, item_p item)
 
 	IF_LOCK(&priv->readq);
 	if (_IF_QFULL(&priv->readq)) {
-		_IF_DROP(&priv->readq);
 		IF_UNLOCK(&priv->readq);
 		NG_FREE_M(m);
 		return (ENOBUFS);
diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c
index ea83b9773e37..7326d3e42381 100644
--- a/sys/netgraph/ng_iface.c
+++ b/sys/netgraph/ng_iface.c
@@ -393,10 +393,7 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m,
 	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
 		M_PREPEND(m, sizeof(sa_family_t), M_NOWAIT);
 		if (m == NULL) {
-			IFQ_LOCK(&ifp->if_snd);
-			IFQ_INC_DROPS(&ifp->if_snd);
-			IFQ_UNLOCK(&ifp->if_snd);
-			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+			if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
 			return (ENOBUFS);
 		}
 		*(sa_family_t *)m->m_data = af;
diff --git a/sys/netgraph/ng_tty.c b/sys/netgraph/ng_tty.c
index 35e17344825f..5e794a8a577f 100644
--- a/sys/netgraph/ng_tty.c
+++ b/sys/netgraph/ng_tty.c
@@ -327,7 +327,6 @@ ngt_rcvdata(hook_p hook, item_p item)
 
 	IF_LOCK(&sc->outq);
 	if (_IF_QFULL(&sc->outq)) {
-		_IF_DROP(&sc->outq);
 		IF_UNLOCK(&sc->outq);
 		NG_FREE_M(m);
 		return (ENOBUFS);
diff --git a/sys/netpfil/pf/if_pflog.c b/sys/netpfil/pf/if_pflog.c
index 30e345724bb0..34c7ed13c17e 100644
--- a/sys/netpfil/pf/if_pflog.c
+++ b/sys/netpfil/pf/if_pflog.c
@@ -159,7 +159,6 @@ pflogstart(struct ifnet *ifp)
 
 	for (;;) {
 		IF_LOCK(&ifp->if_snd);
-		_IF_DROP(&ifp->if_snd);
 		_IF_DEQUEUE(&ifp->if_snd, m);
 		IF_UNLOCK(&ifp->if_snd);
 
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index ffefbc4a883c..24f33cc4dad3 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -1640,7 +1640,7 @@ pfsync_sendout(int schedswi)
 		_IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
 	else {
 		m_freem(m);
-		sc->sc_ifp->if_snd.ifq_drops++;
+		sc->sc_ifp->if_oqdrops++;
 	}
 	if (schedswi)
 		swi_sched(V_pfsync_swi_cookie, 0);