On 2020 Dec 07 (Mon) at 15:02:14 +0100 (+0100), Stefan Sperling wrote:
:On Mon, Dec 07, 2020 at 02:36:05PM +0100, Tobias Heider wrote:
:> Hi,
:> 
:> our net80211 gapwait accounting implementation seems to have several
:> problems:
:> - If we lose packets with serial numbers 0 und 2 but receive the
:>   packet with serial number 1, the first gap wait timeout will
:>   skip serial number 0, flush out serial number 1 and then wait
:>   for serial number 2. However, at this time the timeout is not
:>   re-armed and we have to wait for a window slide.
:> - The logic that does gap skip if too many packets are in the reorder
:>   buffer does not kick in if we lose two packets (as gapwait cannot
:>   reach windowsize - 1. Additionally, what the logic does is mostly
:>   equivalent to a normal window slide if we receive a packet that is
:>   beyond the window. So remove this logic completely.
:> 
:> To fix this use ba_gapwait to actually count all the packets
:> currently in the reorder buffer and restart the gap timeout if the
:> buffer is not empty after we flush out some of the packets.
:> 
:> Found and fix by Christian Erhardt (CC).
:> 
:> ok?
: 
:I am happy with this if it works well during testing.
:
:Could someone convince phessler@ to take this for a flight in Minecraft?
:

Works very well in my testing.

With all three of these diffs in my tree, playing in Minecraft over wifi
feels a lot closer to playing over wired.  In game taking off to fly is a
lot easier, and I have far fewer rubber-band incidents.

OK


:> Index: ieee80211_input.c
:> ===================================================================
:> RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
:> retrieving revision 1.221
:> diff -u -p -r1.221 ieee80211_input.c
:> --- ieee80211_input.c        28 Aug 2020 12:01:48 -0000      1.221
:> +++ ieee80211_input.c        7 Dec 2020 12:58:31 -0000
:> @@ -839,30 +839,10 @@ ieee80211_input_ba(struct ieee80211com *
:>      /* store Rx meta-data too */
:>      rxi->rxi_flags |= IEEE80211_RXI_AMPDU_DONE;
:>      ba->ba_buf[idx].rxi = *rxi;
:> +    ba->ba_gapwait++;
:>  
:> -    if (ba->ba_buf[ba->ba_head].m == NULL) {
:> -            if (ba->ba_gapwait < (ba->ba_winsize - 1)) {
:> -                    if (ba->ba_gapwait == 0) {
:> -                            timeout_add_msec(&ba->ba_gap_to,
:> -                                IEEE80211_BA_GAP_TIMEOUT);
:> -                    }
:> -                    ba->ba_gapwait++;
:> -            } else {
:> -                    /*
:> -                     * A full BA window worth of frames is now waiting.
:> -                     * Skip the missing frame at the head of the window.
:> -                     */
:> -                    int skipped = ieee80211_input_ba_gap_skip(ba);
:> -                    ic->ic_stats.is_ht_rx_ba_frame_lost += skipped;
:> -                    ba->ba_gapwait = 0;
:> -                    if (timeout_pending(&ba->ba_gap_to))
:> -                            timeout_del(&ba->ba_gap_to);
:> -            }
:> -    } else {
:> -            ba->ba_gapwait = 0;
:> -            if (timeout_pending(&ba->ba_gap_to))
:> -                    timeout_del(&ba->ba_gap_to);
:> -    }
:> +    if (ba->ba_buf[ba->ba_head].m == NULL && ba->ba_gapwait == 1)
:> +            timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT);
:>  
:>      ieee80211_input_ba_flush(ic, ni, ba, ml);
:>  }
:> @@ -894,6 +874,7 @@ ieee80211_input_ba_seq(struct ieee80211c
:>                      ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m,
:>                          ni, &ba->ba_buf[ba->ba_head].rxi, ml);
:>                      ba->ba_buf[ba->ba_head].m = NULL;
:> +                    ba->ba_gapwait--;
:>              } else
:>                      ic->ic_stats.is_ht_rx_ba_frame_lost++;
:>              ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
:> @@ -916,12 +897,18 @@ ieee80211_input_ba_flush(struct ieee8021
:>              ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
:>                  &ba->ba_buf[ba->ba_head].rxi, ml);
:>              ba->ba_buf[ba->ba_head].m = NULL;
:> +            ba->ba_gapwait--;
:>  
:>              ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
:>              /* move window forward */
:>              ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
:>      }
:>      ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
:> +
:> +    if (timeout_pending(&ba->ba_gap_to))
:> +            timeout_del(&ba->ba_gap_to);
:> +    if (ba->ba_gapwait)
:> +            timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT);
:>  }
:>  
:>  /* 
:> @@ -989,6 +976,7 @@ ieee80211_ba_move_window(struct ieee8021
:>                      ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
:>                          &ba->ba_buf[ba->ba_head].rxi, ml);
:>                      ba->ba_buf[ba->ba_head].m = NULL;
:> +                    ba->ba_gapwait--;
:>              } else
:>                      ic->ic_stats.is_ht_rx_ba_frame_lost++;
:>              ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
:> 
:

-- 
If the King's English was good enough for Jesus, it's good enough for me!
                -- "Ma" Ferguson, Governor of Texas (circa 1920)

Reply via email to