1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 #ifndef _SFC_STATS_H 11 #define _SFC_STATS_H 12 13 #include <stdint.h> 14 15 #include <rte_atomic.h> 16 17 #include "sfc_tweak.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /** 24 * 64-bit packets and bytes counters covered by 128-bit integer 25 * in order to do atomic updates to guarantee consistency if 26 * required. 27 */ 28 union sfc_pkts_bytes { 29 RTE_STD_C11 30 struct { 31 uint64_t pkts; 32 uint64_t bytes; 33 }; 34 rte_int128_t pkts_bytes; 35 }; 36 37 /** 38 * Update packets and bytes counters atomically in assumption that 39 * the counter is written on one core only. 40 */ 41 static inline void 42 sfc_pkts_bytes_add(union sfc_pkts_bytes *st, uint64_t pkts, uint64_t bytes) 43 { 44 #if SFC_SW_STATS_ATOMIC 45 union sfc_pkts_bytes result; 46 47 /* Stats are written on single core only, so just load values */ 48 result.pkts = st->pkts + pkts; 49 result.bytes = st->bytes + bytes; 50 51 /* 52 * Store the result atomically to guarantee that the reader 53 * core sees both counter updates together. 54 */ 55 __atomic_store_n(&st->pkts_bytes.int128, result.pkts_bytes.int128, 56 __ATOMIC_RELAXED); 57 #else 58 st->pkts += pkts; 59 st->bytes += bytes; 60 #endif 61 } 62 63 /** 64 * Get an atomic copy of a packets and bytes counters. 65 */ 66 static inline void 67 sfc_pkts_bytes_get(const union sfc_pkts_bytes *st, union sfc_pkts_bytes *result) 68 { 69 #if SFC_SW_STATS_ATOMIC 70 result->pkts_bytes.int128 = __atomic_load_n(&st->pkts_bytes.int128, 71 __ATOMIC_RELAXED); 72 #else 73 *result = *st; 74 #endif 75 } 76 77 #ifdef __cplusplus 78 } 79 #endif 80 #endif /* _SFC_STATS_H */ 81