From owner-svn-src-user@FreeBSD.ORG Mon Sep 5 15:11:01 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 BDDAF10656B9; Mon, 5 Sep 2011 15:11:01 +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 AC78E8FC12; Mon, 5 Sep 2011 15:11:01 +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 p85FB1rj042844; Mon, 5 Sep 2011 15:11:01 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p85FB1J2042841; Mon, 5 Sep 2011 15:11:01 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201109051511.p85FB1J2042841@svn.freebsd.org> From: Adrian Chadd Date: Mon, 5 Sep 2011 15:11:01 +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: r225401 - 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 15:11:01 -0000 Author: adrian Date: Mon Sep 5 15:11:01 2011 New Revision: 225401 URL: http://svn.freebsd.org/changeset/base/225401 Log: Begin fleshing out an EWMA packet rate percentage figure and use that when considering the best rate. This is a more optimal figure than using the overall percentage, which doesn't adapt quickly over time. This is a lot more stable than before (between 100-130mbit on my netbook) but as the rate sampling for MCS still samples (almost) all rates, performance can jump quite a bit. 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.h 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 14:37:59 2011 (r225400) +++ user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Mon Sep 5 15:11:01 2011 (r225401) @@ -195,9 +195,7 @@ pick_best_rate(struct ath_node *an, cons /* Calculate percentage if possible */ if (sn->stats[size_bin][rix].total_packets > 0) { - pct = - (100 * sn->stats[size_bin][rix].packets_acked) / - sn->stats[size_bin][rix].total_packets; + pct = sn->stats[size_bin][rix].ewma_pct; } else { /* XXX for now, assume 95% ok */ pct = 95; @@ -683,6 +681,71 @@ ath_rate_setupxtxdesc(struct ath_softc * s3code, sched->t3); /* series 3 */ } +/* + * Update the EWMA percentage. + * + * This is a simple hack to track an EWMA based on the current + * rate scenario. For the rate codes which failed, this will + * record a 0% against it. For the rate code which succeeded, + * EWMA will record the nbad*100/nframes percentage against it. + */ +static void +update_ewma_stats(struct ath_softc *sc, struct ath_node *an, + int frame_size, + int rix0, int tries0, + int rix1, int tries1, + int rix2, int tries2, + int rix3, int tries3, + int short_tries, int tries, int status, + int nframes, int nbad) +{ + struct sample_node *sn = ATH_NODE_SAMPLE(an); + struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); + const int size_bin = size_to_bin(frame_size); + int tries_so_far; + int pct; + int rix = rix0; + + /* Calculate percentage based on current rate */ + if (nframes == 0) + nframes = nbad = 1; + pct = ((nframes - nbad) * 1000) / nframes; + + /* Figure out which rate index succeeded */ + tries_so_far = tries0; + + if (tries1 && tries_so_far < tries) { + tries_so_far += tries1; + rix = rix1; + /* XXX bump ewma pct */ + } + + if (tries2 && tries_so_far < tries) { + tries_so_far += tries2; + rix = rix2; + /* XXX bump ewma pct */ + } + + if (tries3 && tries_so_far < tries) { + rix = rix3; + /* XXX bump ewma pct */ + } + + /* rix is the successful rate, update EWMA for final rix */ + if (sn->stats[size_bin][rix].total_packets < + ssc->smoothing_minpackets) { + /* just average the first few packets */ + int a_pct = (sn->stats[size_bin][rix].packets_acked * 1000) / + (sn->stats[size_bin][rix].total_packets); + sn->stats[size_bin][rix0].ewma_pct = a_pct; + } else { + /* use a ewma */ + sn->stats[size_bin][rix0].ewma_pct = + ((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) + + (pct * (100 - ssc->smoothing_rate))) / 100; + } +} + static void update_stats(struct ath_softc *sc, struct ath_node *an, int frame_size, @@ -852,6 +915,14 @@ ath_rate_tx_complete(struct ath_softc *s 0, 0, short_tries, long_tries, status, nframes, nbad); + update_ewma_stats(sc, an, frame_size, + final_rix, long_tries, + 0, 0, + 0, 0, + 0, 0, + short_tries, long_tries, status, + nframes, nbad); + } else { int finalTSIdx = ts->ts_finaltsi; int i; @@ -938,6 +1009,16 @@ ath_rate_tx_complete(struct ath_softc *s status, nframes, nbad); } + + update_ewma_stats(sc, an, frame_size, + rc[0].rix, rc[0].tries, + rc[1].rix, rc[1].tries, + rc[2].rix, rc[2].tries, + rc[3].rix, rc[3].tries, + short_tries, long_tries, + long_tries > rc[0].tries, + nframes, nbad); + } } @@ -1059,6 +1140,7 @@ ath_rate_ctl_reset(struct ath_softc *sc, sn->stats[y][rix].total_packets = 0; sn->stats[y][rix].packets_acked = 0; sn->stats[y][rix].last_tx = 0; + sn->stats[y][rix].ewma_pct = 0; sn->stats[y][rix].perfect_tx_time = calc_usecs_unicast_packet(sc, size, rix, 0, 0, @@ -1124,12 +1206,14 @@ sample_stats(void *arg, struct ieee80211 for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { if (sn->stats[y][rix].total_packets == 0) continue; - printf("[%2u %s:%4u] %8d:%-8d (%3d%%) T %8d F %4d avg %5u last %u\n", + printf("[%2u %s:%4u] %8d:%-8d (%3d%%) (EWMA %3d.%1d%%) T %8d F %4d avg %5u last %u\n", dot11rate(rt, rix), dot11rate_label(rt, rix), bin_to_size(y), sn->stats[y][rix].total_packets, sn->stats[y][rix].packets_acked, (100*sn->stats[y][rix].packets_acked)/sn->stats[y][rix].total_packets, + sn->stats[y][rix].ewma_pct / 10, + sn->stats[y][rix].ewma_pct % 10, sn->stats[y][rix].tries, sn->stats[y][rix].successive_failures, sn->stats[y][rix].average_tx_time, Modified: user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h Mon Sep 5 14:37:59 2011 (r225400) +++ user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h Mon Sep 5 15:11:01 2011 (r225401) @@ -51,6 +51,7 @@ struct sample_softc { int max_successive_failures; int stale_failure_timeout; /* how long to honor max_successive_failures */ int min_switch; /* min time between rate changes */ + int min_good_pct; /* min good percentage for a rate to be considered */ }; #define ATH_SOFTC_SAMPLE(sc) ((struct sample_softc *)sc->sc_rc) @@ -58,8 +59,9 @@ struct rate_stats { unsigned average_tx_time; int successive_failures; int tries; - int total_packets; - int packets_acked; + int total_packets; /* pkts total since assoc */ + int packets_acked; /* pkts acked since assoc */ + int ewma_pct; /* EWMA percentage */ unsigned perfect_tx_time; /* transmit time for 0 retries */ int last_tx; };