162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __NET_GEN_STATS_H
362306a36Sopenharmony_ci#define __NET_GEN_STATS_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/gen_stats.h>
662306a36Sopenharmony_ci#include <linux/socket.h>
762306a36Sopenharmony_ci#include <linux/rtnetlink.h>
862306a36Sopenharmony_ci#include <linux/pkt_sched.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/* Throughput stats.
1162306a36Sopenharmony_ci * Must be initialized beforehand with gnet_stats_basic_sync_init().
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * If no reads can ever occur parallel to writes (e.g. stack-allocated
1462306a36Sopenharmony_ci * bstats), then the internal stat values can be written to and read
1562306a36Sopenharmony_ci * from directly. Otherwise, use _bstats_set/update() for writes and
1662306a36Sopenharmony_ci * gnet_stats_add_basic() for reads.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_cistruct gnet_stats_basic_sync {
1962306a36Sopenharmony_ci	u64_stats_t bytes;
2062306a36Sopenharmony_ci	u64_stats_t packets;
2162306a36Sopenharmony_ci	struct u64_stats_sync syncp;
2262306a36Sopenharmony_ci} __aligned(2 * sizeof(u64));
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct net_rate_estimator;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistruct gnet_dump {
2762306a36Sopenharmony_ci	spinlock_t *      lock;
2862306a36Sopenharmony_ci	struct sk_buff *  skb;
2962306a36Sopenharmony_ci	struct nlattr *   tail;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	/* Backward compatibility */
3262306a36Sopenharmony_ci	int               compat_tc_stats;
3362306a36Sopenharmony_ci	int               compat_xstats;
3462306a36Sopenharmony_ci	int               padattr;
3562306a36Sopenharmony_ci	void *            xstats;
3662306a36Sopenharmony_ci	int               xstats_len;
3762306a36Sopenharmony_ci	struct tc_stats   tc_stats;
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_civoid gnet_stats_basic_sync_init(struct gnet_stats_basic_sync *b);
4162306a36Sopenharmony_ciint gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock,
4262306a36Sopenharmony_ci			  struct gnet_dump *d, int padattr);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciint gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
4562306a36Sopenharmony_ci				 int tc_stats_type, int xstats_type,
4662306a36Sopenharmony_ci				 spinlock_t *lock, struct gnet_dump *d,
4762306a36Sopenharmony_ci				 int padattr);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciint gnet_stats_copy_basic(struct gnet_dump *d,
5062306a36Sopenharmony_ci			  struct gnet_stats_basic_sync __percpu *cpu,
5162306a36Sopenharmony_ci			  struct gnet_stats_basic_sync *b, bool running);
5262306a36Sopenharmony_civoid gnet_stats_add_basic(struct gnet_stats_basic_sync *bstats,
5362306a36Sopenharmony_ci			  struct gnet_stats_basic_sync __percpu *cpu,
5462306a36Sopenharmony_ci			  struct gnet_stats_basic_sync *b, bool running);
5562306a36Sopenharmony_ciint gnet_stats_copy_basic_hw(struct gnet_dump *d,
5662306a36Sopenharmony_ci			     struct gnet_stats_basic_sync __percpu *cpu,
5762306a36Sopenharmony_ci			     struct gnet_stats_basic_sync *b, bool running);
5862306a36Sopenharmony_ciint gnet_stats_copy_rate_est(struct gnet_dump *d,
5962306a36Sopenharmony_ci			     struct net_rate_estimator __rcu **ptr);
6062306a36Sopenharmony_ciint gnet_stats_copy_queue(struct gnet_dump *d,
6162306a36Sopenharmony_ci			  struct gnet_stats_queue __percpu *cpu_q,
6262306a36Sopenharmony_ci			  struct gnet_stats_queue *q, __u32 qlen);
6362306a36Sopenharmony_civoid gnet_stats_add_queue(struct gnet_stats_queue *qstats,
6462306a36Sopenharmony_ci			  const struct gnet_stats_queue __percpu *cpu_q,
6562306a36Sopenharmony_ci			  const struct gnet_stats_queue *q);
6662306a36Sopenharmony_ciint gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ciint gnet_stats_finish_copy(struct gnet_dump *d);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciint gen_new_estimator(struct gnet_stats_basic_sync *bstats,
7162306a36Sopenharmony_ci		      struct gnet_stats_basic_sync __percpu *cpu_bstats,
7262306a36Sopenharmony_ci		      struct net_rate_estimator __rcu **rate_est,
7362306a36Sopenharmony_ci		      spinlock_t *lock,
7462306a36Sopenharmony_ci		      bool running, struct nlattr *opt);
7562306a36Sopenharmony_civoid gen_kill_estimator(struct net_rate_estimator __rcu **ptr);
7662306a36Sopenharmony_ciint gen_replace_estimator(struct gnet_stats_basic_sync *bstats,
7762306a36Sopenharmony_ci			  struct gnet_stats_basic_sync __percpu *cpu_bstats,
7862306a36Sopenharmony_ci			  struct net_rate_estimator __rcu **ptr,
7962306a36Sopenharmony_ci			  spinlock_t *lock,
8062306a36Sopenharmony_ci			  bool running, struct nlattr *opt);
8162306a36Sopenharmony_cibool gen_estimator_active(struct net_rate_estimator __rcu **ptr);
8262306a36Sopenharmony_cibool gen_estimator_read(struct net_rate_estimator __rcu **ptr,
8362306a36Sopenharmony_ci			struct gnet_stats_rate_est64 *sample);
8462306a36Sopenharmony_ci#endif
85