From owner-svn-src-user@FreeBSD.ORG Mon Sep 5 08:44:47 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 59A5D1065672; Mon, 5 Sep 2011 08:44:47 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 47A358FC1C; Mon, 5 Sep 2011 08:44:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p858ilNw028328; Mon, 5 Sep 2011 08:44:47 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p858ilf9028326; Mon, 5 Sep 2011 08:44:47 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201109050844.p858ilf9028326@svn.freebsd.org> From: Adrian Chadd Date: Mon, 5 Sep 2011 08:44:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225389 - user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Sep 2011 08:44:47 -0000 Author: adrian Date: Mon Sep 5 08:44:46 2011 New Revision: 225389 URL: http://svn.freebsd.org/changeset/base/225389 Log: Begin teaching sample about MCS stuff. The basic differences include: * the "goodness" function is based purely on the average tx time calculation. For 11bg and 11a, the "best" tx time for a given rate is roughly half of the previous rate. So the metric of "is the best rate tx time better than double the current rate tx time" doesn't work for MCS. * 2-stream MCS rates have slightly higher best TX times than one-stream rates. This commit begins to flesh out some more average tx time based calculations, but it allows MCS rate avg times to be slightly higher than the "best", as long as the MCS rate is larger. This is absolutely not correct - as higher MCS rate doesn't at all mean "better throughput" but it at least means it'll be considered. This now finds and settles on an MCS rate that's giving a low average tx time, rather than wildly oscillating all over the place. The problem now is that the average TX time calculation in update_stats() doesn't take into account the aggregate frame behaviour, so any successful subframe will mean the average TX time will stay quite low. I'll address this in a followup commit. Modified: user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Modified: user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Mon Sep 5 08:41:57 2011 (r225388) +++ user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Mon Sep 5 08:44:46 2011 (r225389) @@ -196,9 +196,23 @@ pick_best_rate(struct ath_node *an, cons if (sn->stats[size_bin][rix].successive_failures > 3) continue; - if (best_rate_tt == 0 || tt < best_rate_tt) { - best_rate_tt = tt; - best_rate_rix = rix; + if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) { + if (best_rate_tt == 0 || tt <= best_rate_tt) { + best_rate_tt = tt; + best_rate_rix = rix; + } + } + + /* + * Since 2 stream rates have slightly higher TX times, + * allow a little bit of leeway. This should later + * be abstracted out and properly handled. + */ + if (an->an_node.ni_flags & IEEE80211_NODE_HT) { + if (best_rate_tt == 0 || (tt * 8 <= best_rate_tt * 10)) { + best_rate_tt = tt; + best_rate_rix = rix; + } } } return (best_rate_tt ? best_rate_rix : -1); @@ -257,6 +271,28 @@ pick_sample_rate(struct sample_softc *ss goto nextrate; } + /* + * When doing aggregation, successive failures don't happen + * as often, as sometimes some of the sub-frames get through. + * + * If the sample rix average tx time is greater than the + * average tx time of the current rix, don't immediately use + * the rate for sampling. + */ + if (an->an_node.ni_flags & IEEE80211_NODE_HT) { + if ((sn->stats[size_bin][rix].average_tx_time * 10 > + sn->stats[size_bin][current_rix].average_tx_time * 9) && + (ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout)) { + mask &= ~(1< 11M for non-HT rates */ if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) { if (DOT11RATE(rix) > 2*11 && rix > current_rix + 2) { @@ -453,7 +489,9 @@ ath_rate_findrate(struct ath_softc *sc, if (sn->sample_tt[size_bin] < average_tx_time * (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) { rix = pick_sample_rate(ssc, an, rt, size_bin); IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, - &an->an_node, "size %u sample rate %d %s current rate %d %s", + &an->an_node, "att %d sample_tt %d size %u sample rate %d %s current rate %d %s", + average_tx_time, + sn->sample_tt[size_bin], bin_to_size(size_bin), dot11rate(rt, rix), dot11rate_label(rt, rix), @@ -478,13 +516,49 @@ ath_rate_findrate(struct ath_softc *sc, ath_rate_pick_seed_rate_legacy(sc, an, frameLen); } else if (sn->packets_sent[size_bin] < 20) { /* let the bit-rate switch quickly during the first few packets */ + IEEE80211_NOTE(an->an_node.ni_vap, + IEEE80211_MSG_RATECTL, &an->an_node, + "%s: switching quickly..", __func__); change_rates = 1; } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) { /* min_switch seconds have gone by */ + IEEE80211_NOTE(an->an_node.ni_vap, + IEEE80211_MSG_RATECTL, &an->an_node, + "%s: min_switch %d > ticks_since_switch %d..", + __func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]); change_rates = 1; - } else if (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time) { + } else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) && + (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) { /* the current bit-rate is twice as slow as the best one */ + IEEE80211_NOTE(an->an_node.ni_vap, + IEEE80211_MSG_RATECTL, &an->an_node, + "%s: 2x att (= %d) < cur_rix att %d", + __func__, + 2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time); change_rates = 1; + } else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) { + int cur_rix = sn->current_rix[size_bin]; + int cur_att = sn->stats[size_bin][cur_rix].average_tx_time; + /* + * If the node is HT, upgrade it if the MCS rate is + * higher and the average tx time is within 20% of + * the current rate. It can fail a little. + * + * This is likely not optimal! + */ +#if 0 + printf("cur rix/att %x/%d, best rix/att %x/%d\n", + MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time); +#endif + if ((MCS(best_rix) > MCS(cur_rix)) && + (average_tx_time * 8) <= (cur_att * 10)) { + IEEE80211_NOTE(an->an_node.ni_vap, + IEEE80211_MSG_RATECTL, &an->an_node, + "%s: HT: best_rix 0x%d > cur_rix 0x%x, average_tx_time %d, cur_att %d", + __func__, + MCS(best_rix), MCS(cur_rix), average_tx_time, cur_att); + change_rates = 1; + } } sn->packets_since_sample[size_bin]++;