diff options
author | Vitaliy Makkoveev <mvs@cvs.openbsd.org> | 2023-12-22 23:01:51 +0000 |
---|---|---|
committer | Vitaliy Makkoveev <mvs@cvs.openbsd.org> | 2023-12-22 23:01:51 +0000 |
commit | c4c3bb304d83ac868f23a7c1c31cc4b060dcc44b (patch) | |
tree | b11244df3e3103da4ae2ba08b6f99eaae26ddd67 /sys/net/if.c | |
parent | 6dd7af2da3089a0572e061725ed379e1eaa937bb (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.c | 58 |
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]; |