2009-03-01 05:22:13

by Pavel Roskin

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 1/1] ath5k: fix hw rate index condition

On Thu, 2009-02-26 at 22:06 -0500, Bob Copeland wrote:
> On Thu, Feb 26, 2009 at 06:39:12PM -0800, Luis R. Rodriguez wrote:
> > Might be worth adding a note why this is the case. Can't we simply avoid
> > this by checking earlier for the error or simply assigning it an actual
> > default _good_ hw rate value?
>
> I guess an alternative is to initialize to 0, that would count any rx
> packets whose hw rate we don't know about as the base rate, so it would
> probably bias the RC to 1mb, but this is already one of those 'should
> never happen' cases.

I would prefer that we don't hide problems.

If we don't know why we cannot get a valid rate, we should use WARN_ON
and find out why and when it happens. I'm fine with using a bogus rate
with WARN_ON.

If we decide that we indeed cannot find the actual rate, then WARN_ON
should be removed and the bogus rate replaced with an "unknown rate",
that is, a special value that is never translated to a valid rate and
never given to any rate control algorithm. Using a bogus rate without a
warning is wrong in my opinion.

It should be possible to represent "unknown rate" as such. That applies
to all drivers. I remember that b43 also failed to report the rate in
some cases (for the first received packet or something like that).

--
Regards,
Pavel Roskin


2009-03-03 03:47:01

by Bob Copeland

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 1/1] ath5k: fix hw rate index condition

On Sun, Mar 01, 2009 at 12:21:52AM -0500, Pavel Roskin wrote:
> I would prefer that we don't hide problems.
>
> If we don't know why we cannot get a valid rate, we should use WARN_ON
> and find out why and when it happens. I'm fine with using a bogus rate
> with WARN_ON.

So here is at least stage one of this, not yet the global "unknown rate"
infrastructure, but hopefully it will allow us to track down the issue.

It makes hw_to_driver_rix a little uglier, but oh well. Thoughts?

From: Bob Copeland <[email protected]>
Date: Mon, 2 Mar 2009 21:55:18 -0500
Subject: [PATCH] ath5k: warn and correct rate for unknown hw rate indexes

ath5k sets up a mapping table from the hardware rate index to
the rate index used by mac80211; however, we have seen some
received frames with incorrect rate indexes. Such frames
normally get dropped with a warning in __ieee80211_rx(), but the
warning doesn't include enough context to track down the error.

This patch adds a warning to hw_to_driver_rix for any lookups
that result in a rate index of -1, then returns a valid rate so
the frame can be processed.

This also includes the bug fix suggested by Pavel Roskin, in which
the mapping table is made signed, so rates initialized to -1 stay
that way.

Signed-off-by: Bob Copeland <[email protected]>
---
drivers/net/wireless/ath5k/base.c | 15 ++++++++++++---
drivers/net/wireless/ath5k/base.h | 2 +-
2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index f7c424d..8d4b11c 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1100,9 +1100,18 @@ ath5k_mode_setup(struct ath5k_softc *sc)
static inline int
ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
{
- WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
- "hw_rix out of bounds: %x\n", hw_rix);
- return sc->rate_idx[sc->curband->band][hw_rix];
+ int rix;
+
+ /* return base rate on errors */
+ if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+ "hw_rix out of bounds: %x\n", hw_rix))
+ return 0;
+
+ rix = sc->rate_idx[sc->curband->band][hw_rix];
+ if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
+ rix = 0;
+
+ return rix;
}

/***************\
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index 20e0d14..8229561 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -112,7 +112,7 @@ struct ath5k_softc {
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ieee80211_channel channels[ATH_CHAN_MAX];
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
- u8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+ s8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
enum nl80211_iftype opmode;
struct ath5k_hw *ah; /* Atheros HW */

--
1.6.0.6



--
Bob Copeland %% http://www.bobcopeland.com

2009-03-03 04:31:23

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 1/1] ath5k: fix hw rate index condition

2009/3/3 Bob Copeland <[email protected]>:
> On Sun, Mar 01, 2009 at 12:21:52AM -0500, Pavel Roskin wrote:
>> I would prefer that we don't hide problems.
>>
>> If we don't know why we cannot get a valid rate, we should use WARN_ON
>> and find out why and when it happens.  I'm fine with using a bogus rate
>> with WARN_ON.
>
> So here is at least stage one of this, not yet the global "unknown rate"
> infrastructure, but hopefully it will allow us to track down the issue.
>
> It makes hw_to_driver_rix a little uglier, but oh well.  Thoughts?
>
> From: Bob Copeland <[email protected]>
> Date: Mon, 2 Mar 2009 21:55:18 -0500
> Subject: [PATCH] ath5k: warn and correct rate for unknown hw rate indexes
>
> ath5k sets up a mapping table from the hardware rate index to
> the rate index used by mac80211; however, we have seen some
> received frames with incorrect rate indexes.  Such frames
> normally get dropped with a warning in __ieee80211_rx(), but the
> warning doesn't include enough context to track down the error.
>
> This patch adds a warning to hw_to_driver_rix for any lookups
> that result in a rate index of -1, then returns a valid rate so
> the frame can be processed.
>
> This also includes the bug fix suggested by Pavel Roskin, in which
> the mapping table is made signed, so rates initialized to -1 stay
> that way.
>
> Signed-off-by: Bob Copeland <[email protected]>
> ---
>  drivers/net/wireless/ath5k/base.c |   15 ++++++++++++---
>  drivers/net/wireless/ath5k/base.h |    2 +-
>  2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
> index f7c424d..8d4b11c 100644
> --- a/drivers/net/wireless/ath5k/base.c
> +++ b/drivers/net/wireless/ath5k/base.c
> @@ -1100,9 +1100,18 @@ ath5k_mode_setup(struct ath5k_softc *sc)
>  static inline int
>  ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
>  {
> -       WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
> -                       "hw_rix out of bounds: %x\n", hw_rix);
> -       return sc->rate_idx[sc->curband->band][hw_rix];
> +       int rix;
> +
> +       /* return base rate on errors */
> +       if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
> +                       "hw_rix out of bounds: %x\n", hw_rix))
> +               return 0;
> +
> +       rix = sc->rate_idx[sc->curband->band][hw_rix];
> +       if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
> +               rix = 0;
> +
> +       return rix;
>  }
>
>  /***************\
> diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
> index 20e0d14..8229561 100644
> --- a/drivers/net/wireless/ath5k/base.h
> +++ b/drivers/net/wireless/ath5k/base.h
> @@ -112,7 +112,7 @@ struct ath5k_softc {
>        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
>        struct ieee80211_channel channels[ATH_CHAN_MAX];
>        struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
> -       u8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
> +       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
>        enum nl80211_iftype     opmode;
>        struct ath5k_hw         *ah;            /* Atheros HW */
>
> --
> 1.6.0.6
>

Another thought...

According to docs the rate field is only valid if more flag is clear
(we have the last descriptor) and only if the receive ok flag is set
or both receive ok and phy error flags are cleared. We never do such
checks so we might actually try to process this field when we already
know we shouldn't...

Also the following rate codes are reserved (except XR codes that we
already know):

0x00
0x04 -> the short preamble flag
0x05
0x10 - 0x17
0x1f

and i don't believe i've ever seen them, so we can warn on them too
and print something like "Reserved rate code: %x", also it would be
nice to warn on XR rates (1,2,3,6,7) in case we want to debug this in
the future.


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2009-03-03 13:03:22

by Bob Copeland

[permalink] [raw]
Subject: Re: [ath5k-devel] [PATCH 1/1] ath5k: fix hw rate index condition

On Tue, Mar 03, 2009 at 06:31:05AM +0200, Nick Kossifidis wrote:
>
> According to docs the rate field is only valid if more flag is clear
> (we have the last descriptor) and only if the receive ok flag is set
> or both receive ok and phy error flags are cleared. We never do such
> checks so we might actually try to process this field when we already
> know we shouldn't...

Well, we do skip rs_more packets without getting the rate, hopefully
phy error packets too. The warning would definitely show if we have
any bugs there.

> Also the following rate codes are reserved (except XR codes that we
> already know):
[snip]
> and i don't believe i've ever seen them, so we can warn on them too
> and print something like "Reserved rate code: %x", also it would be
> nice to warn on XR rates (1,2,3,6,7) in case we want to debug this in
> the future.

Good idea, though I'm somewhat of the mind that we should let the
current patch go in for a bit and see if any of these pop up. But
that's because I'm lazy :)

--
Bob Copeland %% http://www.bobcopeland.com