1
0

304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. From: Felix Fietkau <nbd@nbd.name>
  2. Date: Sat, 6 Feb 2021 16:33:14 +0100
  3. Subject: [PATCH] mac80211: minstrel_ht: rework rate downgrade code and
  4. max_prob rate selection
  5. The current fallback code for fast rate switching on potentially failing rates
  6. is triggering too often if there is some strong noise on the channel. This can
  7. lead to wild fluctuations in the rate selection.
  8. Additionally, switching down to max_prob_rate can create a significant gap down
  9. in throughput, especially when using only 2 spatial streams, because max_prob_rate
  10. is limited to using fewer streams than the max_tp rates.
  11. In order to improve throughput without reducing reliability too much, use the
  12. rate downgrade code for the max_prob_rate only, and allow the non-downgraded
  13. max_prob_rate to use as many spatial streams as the max_tp rates
  14. Signed-off-by: Felix Fietkau <nbd@nbd.name>
  15. ---
  16. --- a/net/mac80211/rc80211_minstrel_ht.c
  17. +++ b/net/mac80211/rc80211_minstrel_ht.c
  18. @@ -580,6 +580,14 @@ minstrel_ht_set_best_prob_rate(struct mi
  19. int cur_tp_avg, cur_group, cur_idx;
  20. int max_gpr_group, max_gpr_idx;
  21. int max_gpr_tp_avg, max_gpr_prob;
  22. + int min_dur;
  23. +
  24. + min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]),
  25. + minstrel_get_duration(mi->max_tp_rate[1]));
  26. +
  27. + /* make the rate at least 18% slower than max tp rates */
  28. + if (minstrel_get_duration(index) <= min_dur * 19 / 16)
  29. + return;
  30. cur_group = MI_RATE_GROUP(index);
  31. cur_idx = MI_RATE_IDX(index);
  32. @@ -601,11 +609,6 @@ minstrel_ht_set_best_prob_rate(struct mi
  33. !minstrel_ht_is_legacy_group(max_tp_group))
  34. return;
  35. - /* skip rates faster than max tp rate with lower prob */
  36. - if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) &&
  37. - mrs->prob_avg < max_tp_prob)
  38. - return;
  39. -
  40. max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
  41. max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
  42. max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
  43. @@ -663,40 +666,6 @@ minstrel_ht_assign_best_tp_rates(struct
  44. }
  45. -/*
  46. - * Try to increase robustness of max_prob rate by decrease number of
  47. - * streams if possible.
  48. - */
  49. -static inline void
  50. -minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
  51. -{
  52. - struct minstrel_mcs_group_data *mg;
  53. - int tmp_max_streams, group, tmp_idx, tmp_prob;
  54. - int tmp_tp = 0;
  55. -
  56. - if (!mi->sta->deflink.ht_cap.ht_supported)
  57. - return;
  58. -
  59. - group = MI_RATE_GROUP(mi->max_tp_rate[0]);
  60. - tmp_max_streams = minstrel_mcs_groups[group].streams;
  61. - for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
  62. - mg = &mi->groups[group];
  63. - if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
  64. - continue;
  65. -
  66. - tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate);
  67. - tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
  68. -
  69. - if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
  70. - (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
  71. - mi->max_prob_rate = mg->max_group_prob_rate;
  72. - tmp_tp = minstrel_ht_get_tp_avg(mi, group,
  73. - tmp_idx,
  74. - tmp_prob);
  75. - }
  76. - }
  77. -}
  78. -
  79. static u16
  80. __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
  81. enum minstrel_sample_type type)
  82. @@ -1176,8 +1145,6 @@ minstrel_ht_update_stats(struct minstrel
  83. mi->max_prob_rate = tmp_max_prob_rate;
  84. - /* Try to increase robustness of max_prob_rate*/
  85. - minstrel_ht_prob_rate_reduce_streams(mi);
  86. minstrel_ht_refill_sample_rates(mi);
  87. #ifdef CPTCFG_MAC80211_DEBUGFS
  88. @@ -1256,7 +1223,7 @@ minstrel_ht_ri_txstat_valid(struct minst
  89. }
  90. static void
  91. -minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
  92. +minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx)
  93. {
  94. int group, orig_group;
  95. @@ -1271,11 +1238,7 @@ minstrel_downgrade_rate(struct minstrel_
  96. minstrel_mcs_groups[orig_group].streams)
  97. continue;
  98. - if (primary)
  99. - *idx = mi->groups[group].max_group_tp_rate[0];
  100. - else
  101. - *idx = mi->groups[group].max_group_tp_rate[1];
  102. - break;
  103. + *idx = mi->groups[group].max_group_prob_rate;
  104. }
  105. }
  106. @@ -1286,7 +1249,7 @@ minstrel_ht_tx_status(void *priv, struct
  107. struct ieee80211_tx_info *info = st->info;
  108. struct minstrel_ht_sta *mi = priv_sta;
  109. struct ieee80211_tx_rate *ar = info->status.rates;
  110. - struct minstrel_rate_stats *rate, *rate2;
  111. + struct minstrel_rate_stats *rate;
  112. struct minstrel_priv *mp = priv;
  113. u32 update_interval = mp->update_interval;
  114. bool last, update = false;
  115. @@ -1354,18 +1317,13 @@ minstrel_ht_tx_status(void *priv, struct
  116. /*
  117. * check for sudden death of spatial multiplexing,
  118. * downgrade to a lower number of streams if necessary.
  119. + * only do this for the max_prob_rate to prevent spurious
  120. + * rate fluctuations when the link changes suddenly
  121. */
  122. - rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
  123. + rate = minstrel_get_ratestats(mi, mi->max_prob_rate);
  124. if (rate->attempts > 30 &&
  125. rate->success < rate->attempts / 4) {
  126. - minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
  127. - update = true;
  128. - }
  129. -
  130. - rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
  131. - if (rate2->attempts > 30 &&
  132. - rate2->success < rate2->attempts / 4) {
  133. - minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
  134. + minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate);
  135. update = true;
  136. }
  137. }