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