History

mac80211: improve minstrels rate sorting by means of throughput & probability

This patch improves the way minstrel sorts rates according to throughput and success probability. 3 FOR-loops across the entire rate set in function minstrel_update_stats() which where used to determine the fastest, second fastest and most robust rate are reduced to 1 FOR-loop. The sorted list of rates according throughput is extended to the best four rates as we need them in upcoming joint rate and power control. The sorting is done via the new function minstrel_sort_best_tp_rates(). The most robust rate selection is aligned with minstrel_ht's approach. Once any success probability is above 95% the one with the highest throughput is chosen as most robust rate. If success probabilities of all rates are below 95%, the rate with the highest succ. prob. is elected as most robust one

Thomas Huehn committed 13 years ago

Commit 2ff2b691 parent db8c5ee3 files · +49 −36Browse files

Unified · Split

3 files
  1. net/mac80211/rc80211_minstrel.c +40 −31
  2. net/mac80211/rc80211_minstrel.h +5 −3
  3. net/mac80211/rc80211_minstrel_debugfs.c +4 −2
net/mac80211/rc80211_minstrel.c+40−31
@@ -69,14 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) · 68 unmodified lines
6969 return i;
7070 }
7171
72+/* find & sort topmost throughput rates */
73+static inline void
74+minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
75+{
76+ int j = MAX_THR_RATES;
77+
78+ while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp)
79+ j--;
80+ if (j < MAX_THR_RATES - 1)
81+ memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
82+ if (j < MAX_THR_RATES)
83+ tp_list[j] = i;
84+}
85+
7286 static void
7387 minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
7488 {
75− u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0;
76− u32 max_prob = 0, index_max_prob = 0;
89+ u8 tmp_tp_rate[MAX_THR_RATES];
90+ u8 tmp_prob_rate = 0;
7791 u32 usecs;
7892 int i;
7993
94+ for (i=0; i < MAX_THR_RATES; i++)
95+ tmp_tp_rate[i] = 0;
96+
8097 for (i = 0; i < mi->n_rates; i++) {
8198 struct minstrel_rate *mr = &mi->r[i];
8299
@@ -120,35 +137,27 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) · 37 unmodified lines
120137 }
121138 if (!mr->adjusted_retry_count)
122139 mr->adjusted_retry_count = 2;
123− }
124140
125− for (i = 0; i < mi->n_rates; i++) {
126− struct minstrel_rate *mr = &mi->r[i];
127− if (max_tp < mr->cur_tp) {
128− index_max_tp = i;
129− max_tp = mr->cur_tp;
130− }
131− if (max_prob < mr->probability) {
132− index_max_prob = i;
133− max_prob = mr->probability;
141+ minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate);
142+
143+ /* To determine the most robust rate (max_prob_rate) used at
144+ * 3rd mmr stage we distinct between two cases:
145+ * (1) if any success probabilitiy >= 95%, out of those rates
146+ * choose the maximum throughput rate as max_prob_rate
147+ * (2) if all success probabilities < 95%, the rate with
148+ * highest success probability is choosen as max_prob_rate */
149+ if (mr->probability >= MINSTREL_FRAC(95,100)) {
150+ if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp)
151+ tmp_prob_rate = i;
152+ } else {
153+ if (mr->probability >= mi->r[tmp_prob_rate].probability)
154+ tmp_prob_rate = i;
134155 }
135156 }
136157
137− max_tp = 0;
138− for (i = 0; i < mi->n_rates; i++) {
139− struct minstrel_rate *mr = &mi->r[i];
140−
141− if (i == index_max_tp)
142− continue;
143−
144− if (max_tp < mr->cur_tp) {
145− index_max_tp2 = i;
146− max_tp = mr->cur_tp;
147− }
148− }
149− mi->max_tp_rate = index_max_tp;
150− mi->max_tp_rate2 = index_max_tp2;
151− mi->max_prob_rate = index_max_prob;
158+ /* Assign the new rate set */
159+ memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate));
160+ mi->max_prob_rate = tmp_prob_rate;
152161
153162 /* Reset update timer */
154163 mi->stats_update = jiffies;
@@ -254,7 +263,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 99 unmodified lines
254263 sampling_ratio = mp->lookaround_rate;
255264
256265 /* init rateindex [ndx] with max throughput rate */
257− ndx = mi->max_tp_rate;
266+ ndx = mi->max_tp_rate[0];
258267
259268 /* increase sum packet counter */
260269 mi->packet_count++;
@@ -322,7 +331,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 61 unmodified lines
322331 * to use it, as this only wastes precious airtime */
323332 if (!mrr_capable && rate_sampling &&
324333 (mi->r[ndx].probability > MINSTREL_FRAC(95, 100)))
325− ndx = mi->max_tp_rate;
334+ ndx = mi->max_tp_rate[0];
326335
327336 /* mrr setup for 1st stage */
328337 ar[0].idx = mi->r[ndx].rix;
@@ -342,9 +351,9 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 13 unmodified lines
342351 if (indirect_rate_sampling)
343352 mrr_ndx[0] = sample_ndx;
344353 else
345− mrr_ndx[0] = mi->max_tp_rate;
354+ mrr_ndx[0] = mi->max_tp_rate[0];
346355 } else {
347− mrr_ndx[0] = mi->max_tp_rate2;
356+ mrr_ndx[0] = mi->max_tp_rate[1];
348357 }
349358
350359 /* mrr setup for 3rd & 4th stage */
net/mac80211/rc80211_minstrel.h+5−3
@@ -18,6 +18,9 @@ · 17 unmodified lines
1818 #define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
1919 #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
2020
21+/* number of highest throughput rates to consider*/
22+#define MAX_THR_RATES 4
23+
2124 /*
2225 * Perform EWMA (Exponentially Weighted Moving Average) calculation
2326 */
@@ -65,9 +68,8 @@ struct minstrel_sta_info { · 41 unmodified lines
6568
6669 unsigned int lowest_rix;
6770
68− unsigned int max_tp_rate;
69− unsigned int max_tp_rate2;
70− unsigned int max_prob_rate;
71+ u8 max_tp_rate[MAX_THR_RATES];
72+ u8 max_prob_rate;
7173 unsigned int packet_count;
7274 unsigned int sample_count;
7375 int sample_deferred;
net/mac80211/rc80211_minstrel_debugfs.c+4−2
@@ -73,8 +73,10 @@ minstrel_stats_open(struct inode *inode, struct file *file) · 72 unmodified lines
7373 for (i = 0; i < mi->n_rates; i++) {
7474 struct minstrel_rate *mr = &mi->r[i];
7575
76− *(p++) = (i == mi->max_tp_rate) ? 'T' : ' ';
77− *(p++) = (i == mi->max_tp_rate2) ? 't' : ' ';
76+ *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
77+ *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
78+ *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' ';
79+ *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' ';
7880 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
7981 p += sprintf(p, "%3u%s", mr->bitrate / 2,
8082 (mr->bitrate & 1 ? ".5" : " "));

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t