All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ath5k: Use EWMA factor of 1024 instead of 1000
@ 2010-12-02 10:12 Bruno Randolf
  2010-12-02 10:12 ` [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts Bruno Randolf
  2010-12-02 10:12 ` [PATCH 3/3] nl80211/mac80211: Report signal average Bruno Randolf
  0 siblings, 2 replies; 7+ messages in thread
From: Bruno Randolf @ 2010-12-02 10:12 UTC (permalink / raw)
  To: linville
  Cc: randy.dunlap, br1, peterz, blp, linux-wireless, linux-kernel,
	Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm, kevin.granade,
	johannes

This prepares the only place which uses the EWMA library so far for the
performance improved implementation coming up, which requires factor and
weight to be a power of two.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 drivers/net/wireless/ath/ath5k/base.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a8d380a..25db9eb 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2536,7 +2536,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 	ah->ah_cal_next_full = jiffies;
 	ah->ah_cal_next_ani = jiffies;
 	ah->ah_cal_next_nf = jiffies;
-	ewma_init(&ah->ah_beacon_rssi_avg, 1000, 8);
+	ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
 
 	/*
 	 * Change channels and update the h/w rate map if we're switching;


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts
  2010-12-02 10:12 [PATCH 1/3] ath5k: Use EWMA factor of 1024 instead of 1000 Bruno Randolf
@ 2010-12-02 10:12 ` Bruno Randolf
  2010-12-02 10:20   ` Johannes Berg
  2010-12-02 10:12 ` [PATCH 3/3] nl80211/mac80211: Report signal average Bruno Randolf
  1 sibling, 1 reply; 7+ messages in thread
From: Bruno Randolf @ 2010-12-02 10:12 UTC (permalink / raw)
  To: linville
  Cc: randy.dunlap, br1, peterz, blp, linux-wireless, linux-kernel,
	Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm, kevin.granade,
	johannes

Using bitshifts instead of division and multiplication should improve
performance. That requires weight and factor to be powers of two, but i think
this is something we can live with.

Thanks to Peter Zijlstra for the improved formula!

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 include/linux/average.h |    4 +---
 lib/average.c           |   29 +++++++++++++++++++++--------
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/include/linux/average.h b/include/linux/average.h
index 7706e40..c6028fd 100644
--- a/include/linux/average.h
+++ b/include/linux/average.h
@@ -1,8 +1,6 @@
 #ifndef _LINUX_AVERAGE_H
 #define _LINUX_AVERAGE_H
 
-#include <linux/kernel.h>
-
 /* Exponentially weighted moving average (EWMA) */
 
 /* For more documentation see lib/average.c */
@@ -26,7 +24,7 @@ extern struct ewma *ewma_add(struct ewma *avg, unsigned long val);
  */
 static inline unsigned long ewma_read(const struct ewma *avg)
 {
-	return DIV_ROUND_CLOSEST(avg->internal, avg->factor);
+	return avg->internal >> avg->factor;
 }
 
 #endif /* _LINUX_AVERAGE_H */
diff --git a/lib/average.c b/lib/average.c
index f1d1b46..f438b40 100644
--- a/lib/average.c
+++ b/lib/average.c
@@ -24,18 +24,31 @@
  * ewma_init() - Initialize EWMA parameters
  * @avg: Average structure
  * @factor: Factor to use for the scaled up internal value. The maximum value
- *	of averages can be ULONG_MAX/(factor*weight).
+ *	of averages can be ULONG_MAX/(factor*weight). For performance reasons
+ *	factor has to be a power of 2.
  * @weight: Exponential weight, or decay rate. This defines how fast the
- *	influence of older values decreases. Has to be bigger than 1.
+ *	influence of older values decreases. For performance reasons weight has
+ *	to be a power of 2.
  *
  * Initialize the EWMA parameters for a given struct ewma @avg.
  */
 void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight)
 {
-	WARN_ON(weight <= 1 || factor == 0);
+	int n;
+
+	/* get bitshift for weight */
+	for (n = 0; !(weight & 1); n++)
+		weight = weight >> 1;
+	WARN_ON(weight > 1 || n < 1);
+	avg->weight = n;
+
+	/* get bitshift for factor */
+	for (n = 0; !(factor & 1); n++)
+		factor = factor >> 1;
+	WARN_ON(factor > 1);
+	avg->factor = n;
+
 	avg->internal = 0;
-	avg->weight = weight;
-	avg->factor = factor;
 }
 EXPORT_SYMBOL(ewma_init);
 
@@ -49,9 +62,9 @@ EXPORT_SYMBOL(ewma_init);
 struct ewma *ewma_add(struct ewma *avg, unsigned long val)
 {
 	avg->internal = avg->internal  ?
-		(((avg->internal * (avg->weight - 1)) +
-			(val * avg->factor)) / avg->weight) :
-		(val * avg->factor);
+		(((avg->internal << avg->weight) - avg->internal) +
+			(val << avg->factor)) >> avg->weight :
+		(val << avg->factor);
 	return avg;
 }
 EXPORT_SYMBOL(ewma_add);


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] nl80211/mac80211: Report signal average
  2010-12-02 10:12 [PATCH 1/3] ath5k: Use EWMA factor of 1024 instead of 1000 Bruno Randolf
  2010-12-02 10:12 ` [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts Bruno Randolf
@ 2010-12-02 10:12 ` Bruno Randolf
  2010-12-07 19:06   ` John W. Linville
  1 sibling, 1 reply; 7+ messages in thread
From: Bruno Randolf @ 2010-12-02 10:12 UTC (permalink / raw)
  To: linville
  Cc: randy.dunlap, br1, peterz, blp, linux-wireless, linux-kernel,
	Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm, kevin.granade,
	johannes

Extend nl80211 to report an exponential weighted moving average (EWMA) of the
signal value. Since the signal value usually fluctuates between different
packets, an average can be more useful than the value of the last packet.

This uses the recently added generic EWMA library function.

--
v2:	fix ABI breakage and change factor to be a power of 2.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 include/linux/nl80211.h |    2 ++
 include/net/cfg80211.h  |    4 ++++
 net/mac80211/Kconfig    |    1 +
 net/mac80211/cfg.c      |    3 ++-
 net/mac80211/rx.c       |    1 +
 net/mac80211/sta_info.c |    2 ++
 net/mac80211/sta_info.h |    3 +++
 net/wireless/nl80211.c  |    3 +++
 8 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 5cfa579..68fc25f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1183,6 +1183,7 @@ enum nl80211_rate_info {
  *	station)
  * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
  * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
+ * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
  */
 enum nl80211_sta_info {
 	__NL80211_STA_INFO_INVALID,
@@ -1198,6 +1199,7 @@ enum nl80211_sta_info {
 	NL80211_STA_INFO_TX_PACKETS,
 	NL80211_STA_INFO_TX_RETRIES,
 	NL80211_STA_INFO_TX_FAILED,
+	NL80211_STA_INFO_SIGNAL_AVG,
 
 	/* keep last */
 	__NL80211_STA_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6b2af7a..589c4b1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -424,6 +424,7 @@ struct station_parameters {
  * @STATION_INFO_TX_RETRIES: @tx_retries filled
  * @STATION_INFO_TX_FAILED: @tx_failed filled
  * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
+ * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
  */
 enum station_info_flags {
 	STATION_INFO_INACTIVE_TIME	= 1<<0,
@@ -439,6 +440,7 @@ enum station_info_flags {
 	STATION_INFO_TX_RETRIES		= 1<<10,
 	STATION_INFO_TX_FAILED		= 1<<11,
 	STATION_INFO_RX_DROP_MISC	= 1<<12,
+	STATION_INFO_SIGNAL_AVG		= 1<<13,
 };
 
 /**
@@ -485,6 +487,7 @@ struct rate_info {
  * @plid: mesh peer link id
  * @plink_state: mesh peer link state
  * @signal: signal strength of last received packet in dBm
+ * @signal_avg: signal strength average in dBm
  * @txrate: current unicast bitrate to this station
  * @rx_packets: packets received from this station
  * @tx_packets: packets transmitted to this station
@@ -505,6 +508,7 @@ struct station_info {
 	u16 plid;
 	u8 plink_state;
 	s8 signal;
+	s8 signal_avg;
 	struct rate_info txrate;
 	u32 rx_packets;
 	u32 tx_packets;
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 4d6f865..798d9b9 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -6,6 +6,7 @@ config MAC80211
 	select CRYPTO_ARC4
 	select CRYPTO_AES
 	select CRC32
+	select AVERAGE
 	---help---
 	  This option enables the hardware independent IEEE 802.11
 	  networking stack.
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index db134b5..b0e0f6c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -343,8 +343,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 
 	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
 	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
-		sinfo->filled |= STATION_INFO_SIGNAL;
+		sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
 		sinfo->signal = (s8)sta->last_signal;
+		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
 	}
 
 	sinfo->txrate.flags = 0;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6289525..2fe8f5f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1163,6 +1163,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 	sta->rx_fragments++;
 	sta->rx_bytes += rx->skb->len;
 	sta->last_signal = status->signal;
+	ewma_add(&sta->avg_signal, -status->signal);
 
 	/*
 	 * Change STA power saving mode only at the end of a frame
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index eff5857..c426504 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -244,6 +244,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 	sta->local = local;
 	sta->sdata = sdata;
 
+	ewma_init(&sta->avg_signal, 1024, 8);
+
 	if (sta_prepare_rate_control(local, sta, gfp)) {
 		kfree(sta);
 		return NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 05f1130..fdca52c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 #include <linux/workqueue.h>
+#include <linux/average.h>
 #include "key.h"
 
 /**
@@ -223,6 +224,7 @@ enum plink_state {
  * @rx_fragments: number of received MPDUs
  * @rx_dropped: number of dropped MPDUs from this STA
  * @last_signal: signal of last received frame from this STA
+ * @avg_signal: moving average of signal of received frames from this STA
  * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
  * @tx_filtered_count: number of frames the hardware filtered for this STA
  * @tx_retry_failed: number of frames that failed retry
@@ -291,6 +293,7 @@ struct sta_info {
 	unsigned long rx_fragments;
 	unsigned long rx_dropped;
 	int last_signal;
+	struct ewma avg_signal;
 	__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
 
 	/* Updated from TX status path only, no locking requirements */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 960be4e..45fe06d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1874,6 +1874,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
 	if (sinfo->filled & STATION_INFO_SIGNAL)
 		NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
 			   sinfo->signal);
+	if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
+		NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
+			   sinfo->signal_avg);
 	if (sinfo->filled & STATION_INFO_TX_BITRATE) {
 		txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
 		if (!txrate)


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts
  2010-12-02 10:12 ` [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts Bruno Randolf
@ 2010-12-02 10:20   ` Johannes Berg
  2010-12-02 10:37     ` Bruno Randolf
  0 siblings, 1 reply; 7+ messages in thread
From: Johannes Berg @ 2010-12-02 10:20 UTC (permalink / raw)
  To: Bruno Randolf
  Cc: linville, randy.dunlap, br1, peterz, blp, linux-wireless,
	linux-kernel, Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm,
	kevin.granade

On Thu, 2010-12-02 at 19:12 +0900, Bruno Randolf wrote:

> +	/* get bitshift for weight */
> +	for (n = 0; !(weight & 1); n++)
> +		weight = weight >> 1;
> +	WARN_ON(weight > 1 || n < 1);

I'm sure there's something like log2() (and is_power_of_2() for the
warning) in the kernel already -- no need to reimplement it...

johannes


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts
  2010-12-02 10:20   ` Johannes Berg
@ 2010-12-02 10:37     ` Bruno Randolf
  0 siblings, 0 replies; 7+ messages in thread
From: Bruno Randolf @ 2010-12-02 10:37 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linville, randy.dunlap, peterz, blp, linux-wireless,
	linux-kernel, Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm,
	kevin.granade

On Thu December 2 2010 19:20:22 Johannes Berg wrote:
> On Thu, 2010-12-02 at 19:12 +0900, Bruno Randolf wrote:
> > +	/* get bitshift for weight */
> > +	for (n = 0; !(weight & 1); n++)
> > +		weight = weight >> 1;
> > +	WARN_ON(weight > 1 || n < 1);
> 
> I'm sure there's something like log2() (and is_power_of_2() for the
> warning) in the kernel already -- no need to reimplement it...

Ah, thanks for that! Will resend an improved version.

bruno

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] nl80211/mac80211: Report signal average
  2010-12-02 10:12 ` [PATCH 3/3] nl80211/mac80211: Report signal average Bruno Randolf
@ 2010-12-07 19:06   ` John W. Linville
  2010-12-07 19:17     ` Johannes Berg
  0 siblings, 1 reply; 7+ messages in thread
From: John W. Linville @ 2010-12-07 19:06 UTC (permalink / raw)
  To: Bruno Randolf
  Cc: randy.dunlap, br1, peterz, blp, linux-wireless, linux-kernel,
	Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm, kevin.granade,
	johannes

On Thu, Dec 02, 2010 at 07:12:43PM +0900, Bruno Randolf wrote:
> Extend nl80211 to report an exponential weighted moving average (EWMA) of the
> signal value. Since the signal value usually fluctuates between different
> packets, an average can be more useful than the value of the last packet.
> 
> This uses the recently added generic EWMA library function.
> 
> --
> v2:	fix ABI breakage and change factor to be a power of 2.
> 
> Signed-off-by: Bruno Randolf <br1@einfach.org>

Jouni and Johannes, are you satisfied with this version?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] nl80211/mac80211: Report signal average
  2010-12-07 19:06   ` John W. Linville
@ 2010-12-07 19:17     ` Johannes Berg
  0 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2010-12-07 19:17 UTC (permalink / raw)
  To: John W. Linville
  Cc: Bruno Randolf, randy.dunlap, br1, peterz, blp, linux-wireless,
	linux-kernel, Lars_Ericsson, j, stefanr, kosaki.motohiro, akpm,
	kevin.granade

On Tue, 2010-12-07 at 14:06 -0500, John W. Linville wrote:
> On Thu, Dec 02, 2010 at 07:12:43PM +0900, Bruno Randolf wrote:
> > Extend nl80211 to report an exponential weighted moving average (EWMA) of the
> > signal value. Since the signal value usually fluctuates between different
> > packets, an average can be more useful than the value of the last packet.
> > 
> > This uses the recently added generic EWMA library function.
> > 
> > --
> > v2:	fix ABI breakage and change factor to be a power of 2.
> > 
> > Signed-off-by: Bruno Randolf <br1@einfach.org>
> 
> Jouni and Johannes, are you satisfied with this version?

Yeah, I think with the v2 of the lib improvement it should be fine.

johannes


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-12-07 19:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-02 10:12 [PATCH 1/3] ath5k: Use EWMA factor of 1024 instead of 1000 Bruno Randolf
2010-12-02 10:12 ` [PATCH 2/3] lib: Improve EWMA efficiency by using bitshifts Bruno Randolf
2010-12-02 10:20   ` Johannes Berg
2010-12-02 10:37     ` Bruno Randolf
2010-12-02 10:12 ` [PATCH 3/3] nl80211/mac80211: Report signal average Bruno Randolf
2010-12-07 19:06   ` John W. Linville
2010-12-07 19:17     ` Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.