mac80211: add minstrel fixes that fix mt76 issues in legacy mode
Remove deferred sampling code which does not work well with rate tables + probing. Fix tx status handling if the first invalid rate idx is not set to -1 Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		| @@ -0,0 +1,96 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Wed, 11 Nov 2020 19:17:44 +0100 | ||||||
|  | Subject: [PATCH] mac80211: minstrel: remove deferred sampling code | ||||||
|  |  | ||||||
|  | Deferring sampling attempts to the second stage has some bad interactions | ||||||
|  | with drivers that process the rate table in hardware and use the probe flag | ||||||
|  | to indicate probing packets (e.g. most mt76 drivers). On affected drivers | ||||||
|  | it can lead to probing not working at all. | ||||||
|  |  | ||||||
|  | If the link conditions turn worse, it might not be such a good idea to | ||||||
|  | do a lot of sampling for lower rates in this case. | ||||||
|  |  | ||||||
|  | Fix this by simply skipping the sample attempt instead of deferring it, | ||||||
|  | but keep the checks that would allow it to be sampled if it was skipped | ||||||
|  | too often, but only if it has less than 95% success probability. | ||||||
|  |  | ||||||
|  | Also ensure that IEEE80211_TX_CTL_RATE_CTRL_PROBE is set for all probing | ||||||
|  | packets. | ||||||
|  |  | ||||||
|  | Cc: stable@vger.kernel.org | ||||||
|  | Fixes: cccf129f820e ("mac80211: add the 'minstrel' rate control algorithm") | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/net/mac80211/rc80211_minstrel.c | ||||||
|  | +++ b/net/mac80211/rc80211_minstrel.c | ||||||
|  | @@ -287,12 +287,6 @@ minstrel_tx_status(void *priv, struct ie | ||||||
|  |  			mi->r[ndx].stats.success += success; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0)) | ||||||
|  | -		mi->sample_packets++; | ||||||
|  | - | ||||||
|  | -	if (mi->sample_deferred > 0) | ||||||
|  | -		mi->sample_deferred--; | ||||||
|  | - | ||||||
|  |  	if (time_after(jiffies, mi->last_stats_update + | ||||||
|  |  				mp->update_interval / (mp->new_avg ? 2 : 1))) | ||||||
|  |  		minstrel_update_stats(mp, mi); | ||||||
|  | @@ -367,7 +361,7 @@ minstrel_get_rate(void *priv, struct iee | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  |  	delta = (mi->total_packets * sampling_ratio / 100) - | ||||||
|  | -			(mi->sample_packets + mi->sample_deferred / 2); | ||||||
|  | +			mi->sample_packets; | ||||||
|  |   | ||||||
|  |  	/* delta < 0: no sampling required */ | ||||||
|  |  	prev_sample = mi->prev_sample; | ||||||
|  | @@ -376,7 +370,6 @@ minstrel_get_rate(void *priv, struct iee | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  |  	if (mi->total_packets >= 10000) { | ||||||
|  | -		mi->sample_deferred = 0; | ||||||
|  |  		mi->sample_packets = 0; | ||||||
|  |  		mi->total_packets = 0; | ||||||
|  |  	} else if (delta > mi->n_rates * 2) { | ||||||
|  | @@ -401,19 +394,8 @@ minstrel_get_rate(void *priv, struct iee | ||||||
|  |  	 * rate sampling method should be used. | ||||||
|  |  	 * Respect such rates that are not sampled for 20 interations. | ||||||
|  |  	 */ | ||||||
|  | -	if (mrr_capable && | ||||||
|  | -	    msr->perfect_tx_time > mr->perfect_tx_time && | ||||||
|  | -	    msr->stats.sample_skipped < 20) { | ||||||
|  | -		/* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark | ||||||
|  | -		 * packets that have the sampling rate deferred to the | ||||||
|  | -		 * second MRR stage. Increase the sample counter only | ||||||
|  | -		 * if the deferred sample rate was actually used. | ||||||
|  | -		 * Use the sample_deferred counter to make sure that | ||||||
|  | -		 * the sampling is not done in large bursts */ | ||||||
|  | -		info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||||||
|  | -		rate++; | ||||||
|  | -		mi->sample_deferred++; | ||||||
|  | -	} else { | ||||||
|  | +	if (msr->perfect_tx_time < mr->perfect_tx_time || | ||||||
|  | +	    msr->stats.sample_skipped >= 20) { | ||||||
|  |  		if (!msr->sample_limit) | ||||||
|  |  			return; | ||||||
|  |   | ||||||
|  | @@ -433,6 +415,7 @@ minstrel_get_rate(void *priv, struct iee | ||||||
|  |   | ||||||
|  |  	rate->idx = mi->r[ndx].rix; | ||||||
|  |  	rate->count = minstrel_get_retry_count(&mi->r[ndx], info); | ||||||
|  | +	info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | --- a/net/mac80211/rc80211_minstrel.h | ||||||
|  | +++ b/net/mac80211/rc80211_minstrel.h | ||||||
|  | @@ -126,7 +126,6 @@ struct minstrel_sta_info { | ||||||
|  |  	u8 max_prob_rate; | ||||||
|  |  	unsigned int total_packets; | ||||||
|  |  	unsigned int sample_packets; | ||||||
|  | -	int sample_deferred; | ||||||
|  |   | ||||||
|  |  	unsigned int sample_row; | ||||||
|  |  	unsigned int sample_column; | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Wed, 11 Nov 2020 19:25:39 +0100 | ||||||
|  | Subject: [PATCH] mac80211: minstrel: fix tx status processing corner case | ||||||
|  |  | ||||||
|  | Some drivers fill the status rate list without setting the rate index after | ||||||
|  | the final rate to -1. minstrel_ht already deals with this, but minstrel | ||||||
|  | doesn't, which causes it to get stuck at the lowest rate on these drivers. | ||||||
|  |  | ||||||
|  | Fix this by checking the count as well. | ||||||
|  |  | ||||||
|  | Cc: stable@vger.kernel.org | ||||||
|  | Fixes: cccf129f820e ("mac80211: add the 'minstrel' rate control algorithm") | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/net/mac80211/rc80211_minstrel.c | ||||||
|  | +++ b/net/mac80211/rc80211_minstrel.c | ||||||
|  | @@ -274,7 +274,7 @@ minstrel_tx_status(void *priv, struct ie | ||||||
|  |  	success = !!(info->flags & IEEE80211_TX_STAT_ACK); | ||||||
|  |   | ||||||
|  |  	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||||||
|  | -		if (ar[i].idx < 0) | ||||||
|  | +		if (ar[i].idx < 0 || !ar[i].count) | ||||||
|  |  			break; | ||||||
|  |   | ||||||
|  |  		ndx = rix_to_ndx(mi, ar[i].idx); | ||||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau