average: change to declare precision, not factor
authorJohannes Berg <johannes.berg@intel.com>
Wed, 15 Feb 2017 08:49:26 +0000 (09:49 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 2 Mar 2017 07:32:46 +0000 (08:32 +0100)
Declaring the factor is counter-intuitive, and people are prone
to using small(-ish) values even when that makes no sense.

Change the DECLARE_EWMA() macro to take the fractional precision,
in bits, rather than a factor, and update all users.

While at it, add some more documentation.

Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ralink/rt2x00/rt2x00.h
include/linux/average.h
net/batman-adv/types.h
net/mac80211/ieee80211_i.h
net/mac80211/sta_info.h

index bf95016f442ace0845b23ed9550954cbdc386281..e9d7e2b70085ee9dbe7b38aa34aee9e864d7e6a7 100644 (file)
@@ -51,7 +51,7 @@ module_param(gso, bool, 0444);
  * at once, the weight is chosen so that the EWMA will be insensitive to short-
  * term, transient changes in packet size.
  */
-DECLARE_EWMA(pkt_len, 1, 64)
+DECLARE_EWMA(pkt_len, 0, 64)
 
 /* With mergeable buffers we align buffer address and use the low bits to
  * encode its true size. Buffer size is up to 1 page so we need to align to
index 67fedb61fcc02dd3603658ad769ecbca928ccdaa..979800c6f57fba06bee80be23cbd397327a97af0 100644 (file)
@@ -1252,7 +1252,7 @@ struct ath5k_statistics {
 #define ATH5K_TXQ_LEN_MAX      (ATH_TXBUF / 4)         /* bufs per queue */
 #define ATH5K_TXQ_LEN_LOW      (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
 
-DECLARE_EWMA(beacon_rssi, 1024, 8)
+DECLARE_EWMA(beacon_rssi, 10, 8)
 
 /* Driver state associated with an instance of a device */
 struct ath5k_hw {
index 26869b3bef45ff9d8ed1e7b4701773c8e7b04251..340787894c694aaa45c94cff33f66bead02af3ce 100644 (file)
@@ -257,7 +257,7 @@ struct link_qual {
        int tx_failed;
 };
 
-DECLARE_EWMA(rssi, 1024, 8)
+DECLARE_EWMA(rssi, 10, 8)
 
 /*
  * Antenna settings about the currently active link.
index d04aa58280ded5694bbde3638ec602269635a988..7ddaf340d2ac982bf0e7a3a209017c071e2fa42d 100644 (file)
@@ -1,45 +1,66 @@
 #ifndef _LINUX_AVERAGE_H
 #define _LINUX_AVERAGE_H
 
-/* Exponentially weighted moving average (EWMA) */
+/*
+ * Exponentially weighted moving average (EWMA)
+ *
+ * This implements a fixed-precision EWMA algorithm, with both the
+ * precision and fall-off coefficient determined at compile-time
+ * and built into the generated helper funtions.
+ *
+ * The first argument to the macro is the name that will be used
+ * for the struct and helper functions.
+ *
+ * The second argument, the precision, expresses how many bits are
+ * used for the fractional part of the fixed-precision values.
+ *
+ * The third argument, the weight reciprocal, determines how the
+ * new values will be weighed vs. the old state, new values will
+ * get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
+ * that this parameter must be a power of two for efficiency.
+ */
 
-#define DECLARE_EWMA(name, _factor, _weight)                           \
+#define DECLARE_EWMA(name, _precision, _weight_rcp)                    \
        struct ewma_##name {                                            \
                unsigned long internal;                                 \
        };                                                              \
        static inline void ewma_##name##_init(struct ewma_##name *e)    \
        {                                                               \
-               BUILD_BUG_ON(!__builtin_constant_p(_factor));           \
-               BUILD_BUG_ON(!__builtin_constant_p(_weight));           \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_factor);                   \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_weight);                   \
+               BUILD_BUG_ON(!__builtin_constant_p(_precision));        \
+               BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));       \
+               /*                                                      \
+                * Even if you want to feed it just 0/1 you should have \
+                * some bits for the non-fractional part...             \
+                */                                                     \
+               BUILD_BUG_ON((_precision) > 30);                        \
+               BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);               \
                e->internal = 0;                                        \
        }                                                               \
        static inline unsigned long                                     \
        ewma_##name##_read(struct ewma_##name *e)                       \
        {                                                               \
-               BUILD_BUG_ON(!__builtin_constant_p(_factor));           \
-               BUILD_BUG_ON(!__builtin_constant_p(_weight));           \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_factor);                   \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_weight);                   \
-               return e->internal >> ilog2(_factor);                   \
+               BUILD_BUG_ON(!__builtin_constant_p(_precision));        \
+               BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));       \
+               BUILD_BUG_ON((_precision) > 30);                        \
+               BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);               \
+               return e->internal >> (_precision);                     \
        }                                                               \
        static inline void ewma_##name##_add(struct ewma_##name *e,     \
                                             unsigned long val)         \
        {                                                               \
                unsigned long internal = ACCESS_ONCE(e->internal);      \
-               unsigned long weight = ilog2(_weight);                  \
-               unsigned long factor = ilog2(_factor);                  \
+               unsigned long weight_rcp = ilog2(_weight_rcp);          \
+               unsigned long precision = _precision;                   \
                                                                        \
-               BUILD_BUG_ON(!__builtin_constant_p(_factor));           \
-               BUILD_BUG_ON(!__builtin_constant_p(_weight));           \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_factor);                   \
-               BUILD_BUG_ON_NOT_POWER_OF_2(_weight);                   \
+               BUILD_BUG_ON(!__builtin_constant_p(_precision));        \
+               BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));       \
+               BUILD_BUG_ON((_precision) > 30);                        \
+               BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);               \
                                                                        \
                ACCESS_ONCE(e->internal) = internal ?                   \
-                       (((internal << weight) - internal) +            \
-                               (val << factor)) >> weight :            \
-                       (val << factor);                                \
+                       (((internal << weight_rcp) - internal) +        \
+                               (val << precision)) >> weight_rcp :     \
+                       (val << precision);                             \
        }
 
 #endif /* _LINUX_AVERAGE_H */
index 8f64a5c013454a6eb8f45b04c03389d69ef4e50a..66b25e410a41375e5c70bd7400a5b353bdff4520 100644 (file)
@@ -402,7 +402,7 @@ struct batadv_gw_node {
        struct rcu_head rcu;
 };
 
-DECLARE_EWMA(throughput, 1024, 8)
+DECLARE_EWMA(throughput, 10, 8)
 
 /**
  * struct batadv_hardif_neigh_node_bat_v - B.A.T.M.A.N. V private neighbor
index 159a1a733725069417631f9c6386dc8e49450947..0e718437d080e7258efe75bcba26ce65990671ce 100644 (file)
@@ -428,7 +428,7 @@ struct ieee80211_sta_tx_tspec {
        bool downgraded;
 };
 
-DECLARE_EWMA(beacon_signal, 16, 4)
+DECLARE_EWMA(beacon_signal, 4, 4)
 
 struct ieee80211_if_managed {
        struct timer_list timer;
index 15599c70a38fc9741d31df9a753f313f465ae8a3..e65cda34d2bc000fb7e3738a6235ba5d53b8fde6 100644 (file)
@@ -372,7 +372,7 @@ struct mesh_sta {
        unsigned int fail_avg;
 };
 
-DECLARE_EWMA(signal, 1024, 8)
+DECLARE_EWMA(signal, 10, 8)
 
 struct ieee80211_sta_rx_stats {
        unsigned long packets;