This seems to be a more accurate interpretation of the MiRA paper (a link
to paper can be found at the top of the ieee80211_mira.h header file).
I see a slight stabilization of Tx throughput with the change.

MiRA's rate probe interval is computed based on the number of frames sent,
and perhaps lost, during a probe attempt to another Tx rate.

If we saw no loss during our probe attempt the new interval will be small so
the rate may be probed again soon. If we saw high packet loss the new interval
will be larger (up to about 20 seconds) in order to reduce packet loss caused
by probing.

The paper says the probe interval for a rate needs to be updated if the rate's
goodput is worse than that of the "current transmission rate" (see the
"Adaptive probing interval" section). Our implementation interpreted
"current transmission rate" as "rate being probed right now" and adjusted
the interval of the previously probed rate. However, the context of this
section of the paper suggests that "current transmissions rate" intends to
refer to the currently selected best rate for our non-probing transmissions.
At least that's what I believe after having re-read the section a few times...

With this diff we update the probing interval of any rate which has been
probed and has lost against the best rate. As before, the interval of a
rate is reset to the minimum if it gets chosen as the best rate.

Note that there are two ways probing can be triggered, and the probe interval
is just one of those two. The other trigger is a significant change in measured
throughput (which happens when e.g. a laptop moves further from the AP, and we
start probing down). This other probing trigger is unaffected.
 

diff 25e76d314b84a6d0b1c697db14f987e4ad0a9520 
14a1ca7807811e518898c39a278a89782a0362d8
blob - 15b2250fc3701a48824bc0c5772586c30e19e85a
blob + fbfd7148bd3e7d82eca9c0221203b64318d57d2f
--- sys/net80211/ieee80211_mira.c
+++ sys/net80211/ieee80211_mira.c
@@ -73,7 +73,7 @@ int   ieee80211_mira_inter_mode_ra_finished(
            struct ieee80211_mira_node *, struct ieee80211_node *);
 int    ieee80211_mira_best_rate(struct ieee80211_mira_node *,
            struct ieee80211_node *);
-void   ieee80211_mira_update_probe_interval(struct ieee80211_mira_node *,
+void   ieee80211_mira_update_probe_interval(
            struct ieee80211_mira_goodput_stats *);
 void   ieee80211_mira_schedule_probe_timers(struct ieee80211_mira_node *,
            struct ieee80211_node *);
@@ -735,6 +735,19 @@ ieee80211_mira_probe_valid(struct ieee80211_mira_node 
 void
 ieee80211_mira_probe_done(struct ieee80211_mira_node *mn)
 {
+       int mcs;
+
+       /* Reset probe interval of the best rate. */
+       mn->g[mn->best_mcs].probe_interval = IEEE80211_MIRA_PROBE_TIMEOUT_MIN;
+       mn->g[mn->best_mcs].nprobes = 0;
+       mn->g[mn->best_mcs].nprobe_bytes = 0;
+
+       /* Update probing interval of other probed rates. */
+       for (mcs = 0; mcs < IEEE80211_HT_RATESET_NUM_MCS; mcs++) {
+               if (mcs != mn->best_mcs && (mn->probed_rates & (1 << mcs)))
+                       ieee80211_mira_update_probe_interval(&mn->g[mcs]);
+       }
+
        ieee80211_mira_cancel_timeouts(mn);
        ieee80211_mira_reset_driver_stats(mn);
        ieee80211_mira_reset_collision_stats(mn);
@@ -871,8 +884,7 @@ ieee80211_mira_best_rate(struct ieee80211_mira_node *m
 
 /* See section 5.1.1 (at "Adaptive probing interval") in MiRA paper. */
 void
-ieee80211_mira_update_probe_interval(struct ieee80211_mira_node *mn,
-    struct ieee80211_mira_goodput_stats *g)
+ieee80211_mira_update_probe_interval(struct ieee80211_mira_goodput_stats *g)
 {
        uint64_t lt;
        int intval;
@@ -971,17 +983,6 @@ void
 ieee80211_mira_probe_next_rate(struct ieee80211_mira_node *mn,
     struct ieee80211_node *ni)
 {
-       struct ieee80211_mira_goodput_stats *gprev, *g;
-       int prev_mcs;
-
-       prev_mcs = ieee80211_mira_prev_mcs(mn, ni);
-       gprev = &mn->g[prev_mcs];
-       g = &mn->g[ni->ni_txmcs];
-       /* If the previous rate was worse, increase its probing interval. */
-       if (prev_mcs != ni->ni_txmcs &&
-           gprev->measured + IEEE80211_MIRA_RATE_THRESHOLD < g->measured)
-               ieee80211_mira_update_probe_interval(mn, gprev);
-
        /* Select the next rate to probe. */
        mn->probed_rates |= (1 << ni->ni_txmcs);
        ni->ni_txmcs = ieee80211_mira_next_mcs(mn, ni);
@@ -1165,16 +1166,9 @@ ieee80211_mira_choose(struct ieee80211_mira_node *mn, 
                        DPRINTFN(4, ("probing MCS %d\n", ni->ni_txmcs));
                } else if (ieee80211_mira_inter_mode_ra_finished(mn, ni)) {
                        int best = ieee80211_mira_best_rate(mn, ni);
-                       if (mn->best_mcs != best) {
+                       if (mn->best_mcs != best)
                                mn->best_mcs = best;
-                               ni->ni_txmcs = best;
-                               /* Reset probe interval for new best rate. */
-                               mn->g[best].probe_interval =
-                                   IEEE80211_MIRA_PROBE_TIMEOUT_MIN;
-                               mn->g[best].nprobes = 0;
-                               mn->g[best].nprobe_bytes = 0;
-                       } else
-                               ni->ni_txmcs = mn->best_mcs;
+                       ni->ni_txmcs = mn->best_mcs;
                        ieee80211_mira_probe_done(mn);
                }
 

Reply via email to