xref: /OK3568_Linux_fs/kernel/Documentation/networking/gen_stats.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun===============================================
4*4882a593SmuzhiyunGeneric networking statistics for netlink users
5*4882a593Smuzhiyun===============================================
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunStatistic counters are grouped into structs:
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun==================== ===================== =====================
10*4882a593SmuzhiyunStruct               TLV type              Description
11*4882a593Smuzhiyun==================== ===================== =====================
12*4882a593Smuzhiyungnet_stats_basic     TCA_STATS_BASIC       Basic statistics
13*4882a593Smuzhiyungnet_stats_rate_est  TCA_STATS_RATE_EST    Rate estimator
14*4882a593Smuzhiyungnet_stats_queue     TCA_STATS_QUEUE       Queue statistics
15*4882a593Smuzhiyunnone                 TCA_STATS_APP         Application specific
16*4882a593Smuzhiyun==================== ===================== =====================
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunCollecting:
20*4882a593Smuzhiyun-----------
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunDeclare the statistic structs you need::
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun	struct mystruct {
25*4882a593Smuzhiyun		struct gnet_stats_basic	bstats;
26*4882a593Smuzhiyun		struct gnet_stats_queue	qstats;
27*4882a593Smuzhiyun		...
28*4882a593Smuzhiyun	};
29*4882a593Smuzhiyun
30*4882a593SmuzhiyunUpdate statistics, in dequeue() methods only, (while owning qdisc->running)::
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun	mystruct->tstats.packet++;
33*4882a593Smuzhiyun	mystruct->qstats.backlog += skb->pkt_len;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunExport to userspace (Dump):
37*4882a593Smuzhiyun---------------------------
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun::
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun    my_dumping_routine(struct sk_buff *skb, ...)
42*4882a593Smuzhiyun    {
43*4882a593Smuzhiyun	    struct gnet_dump dump;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun	    if (gnet_stats_start_copy(skb, TCA_STATS2, &mystruct->lock, &dump,
46*4882a593Smuzhiyun				    TCA_PAD) < 0)
47*4882a593Smuzhiyun		    goto rtattr_failure;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun	    if (gnet_stats_copy_basic(&dump, &mystruct->bstats) < 0 ||
50*4882a593Smuzhiyun		gnet_stats_copy_queue(&dump, &mystruct->qstats) < 0 ||
51*4882a593Smuzhiyun		    gnet_stats_copy_app(&dump, &xstats, sizeof(xstats)) < 0)
52*4882a593Smuzhiyun		    goto rtattr_failure;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun	    if (gnet_stats_finish_copy(&dump) < 0)
55*4882a593Smuzhiyun		    goto rtattr_failure;
56*4882a593Smuzhiyun	    ...
57*4882a593Smuzhiyun    }
58*4882a593Smuzhiyun
59*4882a593SmuzhiyunTCA_STATS/TCA_XSTATS backward compatibility:
60*4882a593Smuzhiyun--------------------------------------------
61*4882a593Smuzhiyun
62*4882a593SmuzhiyunPrior users of struct tc_stats and xstats can maintain backward
63*4882a593Smuzhiyuncompatibility by calling the compat wrappers to keep providing the
64*4882a593Smuzhiyunexisting TLV types::
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun    my_dumping_routine(struct sk_buff *skb, ...)
67*4882a593Smuzhiyun    {
68*4882a593Smuzhiyun	if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
69*4882a593Smuzhiyun					TCA_XSTATS, &mystruct->lock, &dump,
70*4882a593Smuzhiyun					TCA_PAD) < 0)
71*4882a593Smuzhiyun		    goto rtattr_failure;
72*4882a593Smuzhiyun	    ...
73*4882a593Smuzhiyun    }
74*4882a593Smuzhiyun
75*4882a593SmuzhiyunA struct tc_stats will be filled out during gnet_stats_copy_* calls
76*4882a593Smuzhiyunand appended to the skb. TCA_XSTATS is provided if gnet_stats_copy_app
77*4882a593Smuzhiyunwas called.
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunLocking:
81*4882a593Smuzhiyun--------
82*4882a593Smuzhiyun
83*4882a593SmuzhiyunLocks are taken before writing and released once all statistics have
84*4882a593Smuzhiyunbeen written. Locks are always released in case of an error. You
85*4882a593Smuzhiyunare responsible for making sure that the lock is initialized.
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun
88*4882a593SmuzhiyunRate Estimator:
89*4882a593Smuzhiyun---------------
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun0) Prepare an estimator attribute. Most likely this would be in user
92*4882a593Smuzhiyun   space. The value of this TLV should contain a tc_estimator structure.
93*4882a593Smuzhiyun   As usual, such a TLV needs to be 32 bit aligned and therefore the
94*4882a593Smuzhiyun   length needs to be appropriately set, etc. The estimator interval
95*4882a593Smuzhiyun   and ewma log need to be converted to the appropriate values.
96*4882a593Smuzhiyun   tc_estimator.c::tc_setup_estimator() is advisable to be used as the
97*4882a593Smuzhiyun   conversion routine. It does a few clever things. It takes a time
98*4882a593Smuzhiyun   interval in microsecs, a time constant also in microsecs and a struct
99*4882a593Smuzhiyun   tc_estimator to  be populated. The returned tc_estimator can be
100*4882a593Smuzhiyun   transported to the kernel.  Transfer such a structure in a TLV of type
101*4882a593Smuzhiyun   TCA_RATE to your code in the kernel.
102*4882a593Smuzhiyun
103*4882a593SmuzhiyunIn the kernel when setting up:
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun1) make sure you have basic stats and rate stats setup first.
106*4882a593Smuzhiyun2) make sure you have initialized stats lock that is used to setup such
107*4882a593Smuzhiyun   stats.
108*4882a593Smuzhiyun3) Now initialize a new estimator::
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun    int ret = gen_new_estimator(my_basicstats,my_rate_est_stats,
111*4882a593Smuzhiyun	mystats_lock, attr_with_tcestimator_struct);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun    if ret == 0
114*4882a593Smuzhiyun	success
115*4882a593Smuzhiyun    else
116*4882a593Smuzhiyun	failed
117*4882a593Smuzhiyun
118*4882a593SmuzhiyunFrom now on, every time you dump my_rate_est_stats it will contain
119*4882a593Smuzhiyunup-to-date info.
120*4882a593Smuzhiyun
121*4882a593SmuzhiyunOnce you are done, call gen_kill_estimator(my_basicstats,
122*4882a593Smuzhiyunmy_rate_est_stats) Make sure that my_basicstats and my_rate_est_stats
123*4882a593Smuzhiyunare still valid (i.e still exist) at the time of making this call.
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun
126*4882a593SmuzhiyunAuthors:
127*4882a593Smuzhiyun--------
128*4882a593Smuzhiyun- Thomas Graf <tgraf@suug.ch>
129*4882a593Smuzhiyun- Jamal Hadi Salim <hadi@cyberus.ca>
130