BpfNetworkStats: use atomic for ifindex cache when possible

Test: TreeHugger
Flag: EXEMPT BUGFIX
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ibc24f079711c36a8bc6ff850fc5b07fb6546b3ae
This commit is contained in:
Maciej Żenczykowski 2025-09-13 03:21:47 -07:00
commit a22d4e1061

View file

@ -50,23 +50,38 @@ const BpfMapRO<uint32_t, StatsValue>& getIfaceStatsMap() {
return ifaceStatsMap; return ifaceStatsMap;
} }
#ifndef __riscv static constexpr unsigned cacheSize = 1024; // see 'iface_index_name_map' bpf map size
#ifndef __ILP32__
#if !defined(__ILP32__) && !defined(__riscv)
static_assert(std::atomic<IfaceValue>::is_always_lock_free, static_assert(std::atomic<IfaceValue>::is_always_lock_free,
"Error: 16-byte IfaceValue is not lock-free on this platform!"); "Error: 16-byte IfaceValue is not lock-free on this platform!");
#endif #define CACHE_IS_ATOMIC
static std::atomic<IfaceValue> cache[cacheSize];
#else
static IfaceValue cache[cacheSize];
#endif #endif
static constexpr unsigned cacheSize = 1024; // see 'iface_index_name_map' bpf map size
static IfaceValue cache[cacheSize];
static inline const IfaceValue& updateCache(unsigned i, const IfaceValue &v) { static inline const IfaceValue& updateCache(unsigned i, const IfaceValue &v) {
if (i < cacheSize) cache[i] = v; if (i < cacheSize) {
#ifdef CACHE_IS_ATOMIC
cache[i].store(v, std::memory_order_relaxed);
#else
cache[i] = v;
#endif
}
return v; return v;
} }
Result<IfaceValue> ifindex2name(const uint32_t ifindex) { Result<IfaceValue> ifindex2name(const uint32_t ifindex) {
if (ifindex < cacheSize && cache[ifindex].name[0]) return cache[ifindex]; if (ifindex < cacheSize) {
#ifdef CACHE_IS_ATOMIC
IfaceValue c = cache[ifindex].load(std::memory_order_relaxed);
#else
IfaceValue c = cache[ifindex];
#endif
if (c.name[0]) return c;
}
Result<IfaceValue> v = getIfaceIndexNameMap().readValue(ifindex); Result<IfaceValue> v = getIfaceIndexNameMap().readValue(ifindex);
if (v.ok()) return updateCache(ifindex, v.value()); if (v.ok()) return updateCache(ifindex, v.value());