summaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-12-22 23:01:51 +0000
committerVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-12-22 23:01:51 +0000
commitc4c3bb304d83ac868f23a7c1c31cc4b060dcc44b (patch)
treeb11244df3e3103da4ae2ba08b6f99eaae26ddd67 /sys/net/if.c
parent6dd7af2da3089a0572e061725ed379e1eaa937bb (diff)
Always allocate per-CPU statistics counters for network interface
descriptor. We have the mess in network interface statistics. Only pseudo drivers do per-CPU counters allocation, all other network devices use the old `if_data'. The network stack partially uses per-CPU counters and partially use `if_data', but the protection is inconsistent: some times counters accessed with exclusive netlock, some times with shared netlock, some times with kernel lock, but without netlock, some times with another locks. To make network interfaces statistics more consistent, always allocate per-CPU counters at interface attachment time and use it instead of `if_data'. At this step only move counters allocation to the if_attach() internals. The `if_data' removal will be performed with the following diffs to make review and tests easier. ok bluhm
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c58
1 files changed, 19 insertions, 39 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 89c164fdd3a..f205a6799f2 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.711 2023/11/11 14:24:03 bluhm Exp $ */
+/* $OpenBSD: if.c,v 1.712 2023/12/22 23:01:50 mvs Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -645,6 +645,8 @@ if_attach_common(struct ifnet *ifp)
"%s: if_qstart not set with MPSAFE set", ifp->if_xname);
}
+ ifp->if_counters = counters_alloc(ifc_ncounters);
+
if_idxmap_alloc(ifp);
ifq_init(&ifp->if_snd, ifp, 0);
@@ -1250,8 +1252,7 @@ if_detach(struct ifnet *ifp)
/* Announce that the interface is gone. */
rtm_ifannounce(ifp, IFAN_DEPARTURE);
- if (ifp->if_counters != NULL)
- if_counters_free(ifp);
+ counters_free(ifp->if_counters, ifc_ncounters);
for (i = 0; i < ifp->if_nifqs; i++)
ifq_destroy(ifp->if_ifqs[i]);
@@ -2771,48 +2772,27 @@ ifconf(caddr_t data)
}
void
-if_counters_alloc(struct ifnet *ifp)
-{
- KASSERT(ifp->if_counters == NULL);
-
- ifp->if_counters = counters_alloc(ifc_ncounters);
-}
-
-void
-if_counters_free(struct ifnet *ifp)
-{
- KASSERT(ifp->if_counters != NULL);
-
- counters_free(ifp->if_counters, ifc_ncounters);
- ifp->if_counters = NULL;
-}
-
-void
if_getdata(struct ifnet *ifp, struct if_data *data)
{
+ uint64_t counters[ifc_ncounters];
unsigned int i;
*data = ifp->if_data;
- if (ifp->if_counters != NULL) {
- uint64_t counters[ifc_ncounters];
-
- counters_read(ifp->if_counters, counters, nitems(counters),
- NULL);
-
- data->ifi_ipackets += counters[ifc_ipackets];
- data->ifi_ierrors += counters[ifc_ierrors];
- data->ifi_opackets += counters[ifc_opackets];
- data->ifi_oerrors += counters[ifc_oerrors];
- data->ifi_collisions += counters[ifc_collisions];
- data->ifi_ibytes += counters[ifc_ibytes];
- data->ifi_obytes += counters[ifc_obytes];
- data->ifi_imcasts += counters[ifc_imcasts];
- data->ifi_omcasts += counters[ifc_omcasts];
- data->ifi_iqdrops += counters[ifc_iqdrops];
- data->ifi_oqdrops += counters[ifc_oqdrops];
- data->ifi_noproto += counters[ifc_noproto];
- }
+ counters_read(ifp->if_counters, counters, nitems(counters), NULL);
+
+ data->ifi_ipackets += counters[ifc_ipackets];
+ data->ifi_ierrors += counters[ifc_ierrors];
+ data->ifi_opackets += counters[ifc_opackets];
+ data->ifi_oerrors += counters[ifc_oerrors];
+ data->ifi_collisions += counters[ifc_collisions];
+ data->ifi_ibytes += counters[ifc_ibytes];
+ data->ifi_obytes += counters[ifc_obytes];
+ data->ifi_imcasts += counters[ifc_imcasts];
+ data->ifi_omcasts += counters[ifc_omcasts];
+ data->ifi_iqdrops += counters[ifc_iqdrops];
+ data->ifi_oqdrops += counters[ifc_oqdrops];
+ data->ifi_noproto += counters[ifc_noproto];
for (i = 0; i < ifp->if_nifqs; i++) {
struct ifqueue *ifq = ifp->if_ifqs[i];