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 struct {
30 uint64_t pkts;
31 uint64_t bytes;
32 };
33 rte_int128_t pkts_bytes;
34 };
35
36 /**
37 * Update packets and bytes counters atomically in assumption that
38 * the counter is written on one core only.
39 */
40 static inline void
sfc_pkts_bytes_add(union sfc_pkts_bytes * st,uint64_t pkts,uint64_t bytes)41 sfc_pkts_bytes_add(union sfc_pkts_bytes *st, uint64_t pkts, uint64_t bytes)
42 {
43 #if SFC_SW_STATS_ATOMIC
44 union sfc_pkts_bytes result;
45
46 /* Stats are written on single core only, so just load values */
47 result.pkts = st->pkts + pkts;
48 result.bytes = st->bytes + bytes;
49
50 /*
51 * Store the result atomically to guarantee that the reader
52 * core sees both counter updates together.
53 */
54 __atomic_store_n(&st->pkts_bytes.int128, result.pkts_bytes.int128,
55 __ATOMIC_RELAXED);
56 #else
57 st->pkts += pkts;
58 st->bytes += bytes;
59 #endif
60 }
61
62 /**
63 * Get an atomic copy of a packets and bytes counters.
64 */
65 static inline void
sfc_pkts_bytes_get(const union sfc_pkts_bytes * st,union sfc_pkts_bytes * result)66 sfc_pkts_bytes_get(const union sfc_pkts_bytes *st, union sfc_pkts_bytes *result)
67 {
68 #if SFC_SW_STATS_ATOMIC
69 result->pkts_bytes.int128 = __atomic_load_n(&st->pkts_bytes.int128,
70 __ATOMIC_RELAXED);
71 #else
72 *result = *st;
73 #endif
74 }
75
76 #ifdef __cplusplus
77 }
78 #endif
79 #endif /* _SFC_STATS_H */
80