xref: /dpdk/drivers/net/sfc/sfc_stats.h (revision 971d2b57972919527e27ed683032a71864a2eb56)
196fd2bd6SIgor Romanov /* SPDX-License-Identifier: BSD-3-Clause
296fd2bd6SIgor Romanov  *
396fd2bd6SIgor Romanov  * Copyright(c) 2019-2021 Xilinx, Inc.
496fd2bd6SIgor Romanov  * Copyright(c) 2019 Solarflare Communications Inc.
596fd2bd6SIgor Romanov  *
696fd2bd6SIgor Romanov  * This software was jointly developed between OKTET Labs (under contract
796fd2bd6SIgor Romanov  * for Solarflare) and Solarflare Communications, Inc.
896fd2bd6SIgor Romanov  */
996fd2bd6SIgor Romanov 
1096fd2bd6SIgor Romanov #ifndef _SFC_STATS_H
1196fd2bd6SIgor Romanov #define _SFC_STATS_H
1296fd2bd6SIgor Romanov 
1396fd2bd6SIgor Romanov #include <stdint.h>
1496fd2bd6SIgor Romanov 
1596fd2bd6SIgor Romanov #include <rte_atomic.h>
1696fd2bd6SIgor Romanov 
1796fd2bd6SIgor Romanov #include "sfc_tweak.h"
1896fd2bd6SIgor Romanov 
1996fd2bd6SIgor Romanov #ifdef __cplusplus
2096fd2bd6SIgor Romanov extern "C" {
2196fd2bd6SIgor Romanov #endif
2296fd2bd6SIgor Romanov 
2396fd2bd6SIgor Romanov /**
2496fd2bd6SIgor Romanov  * 64-bit packets and bytes counters covered by 128-bit integer
2596fd2bd6SIgor Romanov  * in order to do atomic updates to guarantee consistency if
2696fd2bd6SIgor Romanov  * required.
2796fd2bd6SIgor Romanov  */
2896fd2bd6SIgor Romanov union sfc_pkts_bytes {
2996fd2bd6SIgor Romanov 	struct {
3096fd2bd6SIgor Romanov 		uint64_t		pkts;
3196fd2bd6SIgor Romanov 		uint64_t		bytes;
3296fd2bd6SIgor Romanov 	};
3396fd2bd6SIgor Romanov 	rte_int128_t			pkts_bytes;
3496fd2bd6SIgor Romanov };
3596fd2bd6SIgor Romanov 
3696fd2bd6SIgor Romanov /**
3796fd2bd6SIgor Romanov  * Update packets and bytes counters atomically in assumption that
3896fd2bd6SIgor Romanov  * the counter is written on one core only.
3996fd2bd6SIgor Romanov  */
4096fd2bd6SIgor Romanov static inline void
sfc_pkts_bytes_add(union sfc_pkts_bytes * st,uint64_t pkts,uint64_t bytes)4196fd2bd6SIgor Romanov sfc_pkts_bytes_add(union sfc_pkts_bytes *st, uint64_t pkts, uint64_t bytes)
4296fd2bd6SIgor Romanov {
4396fd2bd6SIgor Romanov #if SFC_SW_STATS_ATOMIC
4496fd2bd6SIgor Romanov 	union sfc_pkts_bytes result;
4596fd2bd6SIgor Romanov 
4696fd2bd6SIgor Romanov 	/* Stats are written on single core only, so just load values */
4796fd2bd6SIgor Romanov 	result.pkts = st->pkts + pkts;
4896fd2bd6SIgor Romanov 	result.bytes = st->bytes + bytes;
4996fd2bd6SIgor Romanov 
5096fd2bd6SIgor Romanov 	/*
5196fd2bd6SIgor Romanov 	 * Store the result atomically to guarantee that the reader
5296fd2bd6SIgor Romanov 	 * core sees both counter updates together.
5396fd2bd6SIgor Romanov 	 */
5496fd2bd6SIgor Romanov 	__atomic_store_n(&st->pkts_bytes.int128, result.pkts_bytes.int128,
55*34f92e82SAndrew Rybchenko 			 __ATOMIC_RELAXED);
5696fd2bd6SIgor Romanov #else
5796fd2bd6SIgor Romanov 	st->pkts += pkts;
5896fd2bd6SIgor Romanov 	st->bytes += bytes;
5996fd2bd6SIgor Romanov #endif
6096fd2bd6SIgor Romanov }
6196fd2bd6SIgor Romanov 
6296fd2bd6SIgor Romanov /**
6396fd2bd6SIgor Romanov  * Get an atomic copy of a packets and bytes counters.
6496fd2bd6SIgor Romanov  */
6596fd2bd6SIgor Romanov static inline void
sfc_pkts_bytes_get(const union sfc_pkts_bytes * st,union sfc_pkts_bytes * result)6696fd2bd6SIgor Romanov sfc_pkts_bytes_get(const union sfc_pkts_bytes *st, union sfc_pkts_bytes *result)
6796fd2bd6SIgor Romanov {
6896fd2bd6SIgor Romanov #if SFC_SW_STATS_ATOMIC
6996fd2bd6SIgor Romanov 	result->pkts_bytes.int128 = __atomic_load_n(&st->pkts_bytes.int128,
70*34f92e82SAndrew Rybchenko 						    __ATOMIC_RELAXED);
7196fd2bd6SIgor Romanov #else
7296fd2bd6SIgor Romanov 	*result = *st;
7396fd2bd6SIgor Romanov #endif
7496fd2bd6SIgor Romanov }
7596fd2bd6SIgor Romanov 
7696fd2bd6SIgor Romanov #ifdef __cplusplus
7796fd2bd6SIgor Romanov }
7896fd2bd6SIgor Romanov #endif
7996fd2bd6SIgor Romanov #endif /* _SFC_STATS_H */
80