343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. From: Felix Fietkau <nbd@openwrt.org>
  2. Date: Thu, 3 Mar 2016 23:20:06 +0100
  3. Subject: [PATCH] mac80211: minstrel_ht: improve sample rate skip logic
  4. There were a few issues that were slowing down the process of finding
  5. the optimal rate, especially on devices with multi-rate retry
  6. limitations:
  7. When max_tp_rate[0] was slower than max_tp_rate[1], the code did not
  8. sample max_tp_rate[1], which would often allow it to switch places with
  9. max_tp_rate[0] (e.g. if only the first sampling attempts were bad, but the
  10. rate is otherwise good).
  11. Also, sample attempts of rates between max_tp_rate[0] and [1] were being
  12. ignored in this case, because the code only checked if the rate was
  13. slower than [1].
  14. Fix this by checking against the fastest / second fastest max_tp_rate
  15. instead of assuming a specific order between the two.
  16. In my tests this patch significantly reduces the time until minstrel_ht
  17. finds the optimal rate right after assoc
  18. Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  19. ---
  20. --- a/net/mac80211/rc80211_minstrel_ht.c
  21. +++ b/net/mac80211/rc80211_minstrel_ht.c
  22. @@ -958,6 +958,7 @@ minstrel_get_sample_rate(struct minstrel
  23. struct minstrel_rate_stats *mrs;
  24. struct minstrel_mcs_group_data *mg;
  25. unsigned int sample_dur, sample_group, cur_max_tp_streams;
  26. + int tp_rate1, tp_rate2;
  27. int sample_idx = 0;
  28. if (mi->sample_wait > 0) {
  29. @@ -979,14 +980,22 @@ minstrel_get_sample_rate(struct minstrel
  30. mrs = &mg->rates[sample_idx];
  31. sample_idx += sample_group * MCS_GROUP_RATES;
  32. + /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */
  33. + if (minstrel_get_duration(mi->max_tp_rate[0]) >
  34. + minstrel_get_duration(mi->max_tp_rate[1])) {
  35. + tp_rate1 = mi->max_tp_rate[1];
  36. + tp_rate2 = mi->max_tp_rate[0];
  37. + } else {
  38. + tp_rate1 = mi->max_tp_rate[0];
  39. + tp_rate2 = mi->max_tp_rate[1];
  40. + }
  41. +
  42. /*
  43. * Sampling might add some overhead (RTS, no aggregation)
  44. - * to the frame. Hence, don't use sampling for the currently
  45. - * used rates.
  46. + * to the frame. Hence, don't use sampling for the highest currently
  47. + * used highest throughput or probability rate.
  48. */
  49. - if (sample_idx == mi->max_tp_rate[0] ||
  50. - sample_idx == mi->max_tp_rate[1] ||
  51. - sample_idx == mi->max_prob_rate)
  52. + if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate)
  53. return -1;
  54. /*
  55. @@ -1001,10 +1010,10 @@ minstrel_get_sample_rate(struct minstrel
  56. * if the link is working perfectly.
  57. */
  58. - cur_max_tp_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
  59. + cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
  60. MCS_GROUP_RATES].streams;
  61. sample_dur = minstrel_get_duration(sample_idx);
  62. - if (sample_dur >= minstrel_get_duration(mi->max_tp_rate[1]) &&
  63. + if (sample_dur >= minstrel_get_duration(tp_rate2) &&
  64. (cur_max_tp_streams - 1 <
  65. minstrel_mcs_groups[sample_group].streams ||
  66. sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {