From 1ad3d7f43d404c95fa692f6e42eba4a8918b043f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 13 Aug 2025 12:46:26 -0700 Subject: [PATCH] BpfNetworkStats: use bulk api on 5.10+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most spots autoconverted, but this one needs special love. Test: TreeHugger Flag: EXEMPT mainline/noop Signed-off-by: Maciej Żenczykowski Change-Id: I40b29d989c5a51082ac8e9ab09b7644eee46d7cb --- .../libs/libnetworkstats/BpfNetworkStats.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp index e314196f1f..93b7bbc425 100644 --- a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp +++ b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp @@ -112,6 +112,23 @@ int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats, // specific iface int64_t unknownIfaceBytesTotal = 0; + + if (isAtLeastKernelVersion(5, 10, 0)) { + // On 5.10+ bulk lookup api returns values for free, so just use forAll(f(K,V)) + auto res = ifaceStatsMap.forAll( + [iface, stats, ifindex2name, &unknownIfaceBytesTotal, &ifaceStatsMap](const uint32_t& key, const StatsValue& value) { + Result ifname = ifindex2name(key); + if (!ifname.ok()) { + maybeLogUnknownIface(key, ifaceStatsMap, key, &unknownIfaceBytesTotal); + return; + } + if (!strcmp(iface, ifname.value().name)) *stats += value; + } + ); + return res.ok() ? 0 : -res.error().code(); + } + + // Before 5.10 we try to avoid doing readValue unless needed auto res = ifaceStatsMap.iterate( [iface, stats, ifindex2name, &unknownIfaceBytesTotal, &ifaceStatsMap](const uint32_t& key) -> Result { Result ifname = ifindex2name(key); @@ -120,7 +137,6 @@ int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats, return {}; } if (!strcmp(iface, ifname.value().name)) { - // TODO: bulk api makes this readValue() inefficient - use forAll(K, V) Result statsEntry = ifaceStatsMap.readValue(key); if (!statsEntry.ok()) return statsEntry.error(); *stats += statsEntry.value();