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