xref: /dpdk/drivers/net/sfc/sfc_stats.h (revision 971d2b57972919527e27ed683032a71864a2eb56)
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