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