diff options
author | glebius <glebius@FreeBSD.org> | 2012-09-28 18:28:27 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-09-28 18:28:27 +0000 |
commit | 4b29d585cfcde7e84697e4af66a48144fb111e27 (patch) | |
tree | 66a3fa6f2f977c6c8d808397e65fc31995eab050 /sys/net | |
parent | 186eb51daa2f37de906b898ca8e70b4e60e3e0ce (diff) | |
download | FreeBSD-src-4b29d585cfcde7e84697e4af66a48144fb111e27.zip FreeBSD-src-4b29d585cfcde7e84697e4af66a48144fb111e27.tar.gz |
The drbr(9) API appeared to be so unclear, that most drivers in
tree used it incorrectly, which lead to inaccurate overrated
if_obytes accounting. The drbr(9) used to update ifnet stats on
drbr_enqueue(), which is not accurate since enqueuing doesn't
imply successful processing by driver. Dequeuing neither mean
that. Most drivers also called drbr_stats_update() which did
accounting again, leading to doubled if_obytes statistics. And
in case of severe transmitting, when a packet could be several
times enqueued and dequeued it could have been accounted several
times.
o Thus, make drbr(9) API thinner. Now drbr(9) merely chooses between
ALTQ queueing or buf_ring(9) queueing.
- It doesn't touch the buf_ring stats any more.
- It doesn't touch ifnet stats anymore.
- drbr_stats_update() no longer exists.
o buf_ring(9) handles its stats itself:
- It handles br_drops itself.
- br_prod_bytes stats are dropped. Rationale: no one ever
reads them but update of a common counter on every packet
negatively affects performance due to excessive cache
invalidation.
- buf_ring_enqueue_bytes() reduced to buf_ring_enqueue(), since
we no longer account bytes.
o Drivers handle their stats theirselves: if_obytes, if_omcasts.
o mlx4(4), igb(4), em(4), vxge(4), oce(4) and ixv(4) no longer
use drbr_stats_update(), and update ifnet stats theirselves.
o bxe(4) was the most correct driver, it didn't call
drbr_stats_update(), thus it was the only driver accurate under
moderate load. Now it also maintains stats itself.
o ixgbe(4) had already taken stats from hardware, so just
- drop software stats updating.
- take multicast packet count from hardware as well.
o mxge(4) just no longer needs NO_SLOW_STATS define.
o cxgb(4), cxgbe(4) need no change, since they obtain stats
from hardware.
Reviewed by: jfv, gnn
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_var.h | 20 |
1 files changed, 3 insertions, 17 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 01ec2b6..8a1d5cc 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -590,22 +590,10 @@ do { \ } while (0) #ifdef _KERNEL -static __inline void -drbr_stats_update(struct ifnet *ifp, int len, int mflags) -{ -#ifndef NO_SLOW_STATS - ifp->if_obytes += len; - if (mflags & M_MCAST) - ifp->if_omcasts++; -#endif -} - static __inline int drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m) { int error = 0; - int len = m->m_pkthdr.len; - int mflags = m->m_flags; #ifdef ALTQ if (ALTQ_IS_ENABLED(&ifp->if_snd)) { @@ -613,12 +601,10 @@ drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m) return (error); } #endif - if ((error = buf_ring_enqueue_bytes(br, m, len)) == ENOBUFS) { - br->br_drops++; + error = buf_ring_enqueue(br, m); + if (error) m_freem(m); - } else - drbr_stats_update(ifp, len, mflags); - + return (error); } |