diff options
author | Eyal Shapira <eyal@wizery.com> | 2014-04-05 19:42:18 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-04-13 09:51:04 -0400 |
commit | e53839eb9882c99d3781eab0fe1b2d4369a6a2cc (patch) | |
tree | 9eedaa4715a809d7508896a9d214dbd50e59e13c | |
parent | 198266a3c110e8a68895a24e937003f5da0c5f60 (diff) |
iwlwifi: mvm: rs: fix and cleanup rs_get_rate_action
Change the down/upscale decision logic a bit to be based
on different success ratio thresholds. This fixes the implementation
compared to the rate scale algorithm which was planned to yield
optimal results. Also fix a case where a lower rate wasn't explored
despite being a potential for better throughput.
While at it rewrite rs_get_rate_action to be more clear and clean.
Cc: <stable@vger.kernel.org> [3.14]
Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.c | 127 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.h | 1 |
2 files changed, 60 insertions, 68 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index cd32ad54384e..97b8fac214a1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -1658,85 +1658,76 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm, | |||
1658 | { | 1658 | { |
1659 | enum rs_action action = RS_ACTION_STAY; | 1659 | enum rs_action action = RS_ACTION_STAY; |
1660 | 1660 | ||
1661 | /* Too many failures, decrease rate */ | ||
1662 | if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { | 1661 | if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { |
1663 | IWL_DEBUG_RATE(mvm, | 1662 | IWL_DEBUG_RATE(mvm, |
1664 | "decrease rate because of low SR\n"); | 1663 | "Decrease rate because of low SR\n"); |
1665 | action = RS_ACTION_DOWNSCALE; | 1664 | return RS_ACTION_DOWNSCALE; |
1666 | /* No throughput measured yet for adjacent rates; try increase. */ | ||
1667 | } else if ((low_tpt == IWL_INVALID_VALUE) && | ||
1668 | (high_tpt == IWL_INVALID_VALUE)) { | ||
1669 | if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) { | ||
1670 | IWL_DEBUG_RATE(mvm, | ||
1671 | "Good SR and no high rate measurement. " | ||
1672 | "Increase rate\n"); | ||
1673 | action = RS_ACTION_UPSCALE; | ||
1674 | } else if (low != IWL_RATE_INVALID) { | ||
1675 | IWL_DEBUG_RATE(mvm, | ||
1676 | "Remain in current rate\n"); | ||
1677 | action = RS_ACTION_STAY; | ||
1678 | } | ||
1679 | } | 1665 | } |
1680 | 1666 | ||
1681 | /* Both adjacent throughputs are measured, but neither one has better | 1667 | if ((low_tpt == IWL_INVALID_VALUE) && |
1682 | * throughput; we're using the best rate, don't change it! | 1668 | (high_tpt == IWL_INVALID_VALUE) && |
1683 | */ | 1669 | (high != IWL_RATE_INVALID)) { |
1684 | else if ((low_tpt != IWL_INVALID_VALUE) && | ||
1685 | (high_tpt != IWL_INVALID_VALUE) && | ||
1686 | (low_tpt < current_tpt) && | ||
1687 | (high_tpt < current_tpt)) { | ||
1688 | IWL_DEBUG_RATE(mvm, | 1670 | IWL_DEBUG_RATE(mvm, |
1689 | "Both high and low are worse. " | 1671 | "No data about high/low rates. Increase rate\n"); |
1690 | "Maintain rate\n"); | 1672 | return RS_ACTION_UPSCALE; |
1691 | action = RS_ACTION_STAY; | ||
1692 | } | 1673 | } |
1693 | 1674 | ||
1694 | /* At least one adjacent rate's throughput is measured, | 1675 | if ((high_tpt == IWL_INVALID_VALUE) && |
1695 | * and may have better performance. | 1676 | (high != IWL_RATE_INVALID) && |
1696 | */ | 1677 | (low_tpt != IWL_INVALID_VALUE) && |
1697 | else { | 1678 | (low_tpt < current_tpt)) { |
1698 | /* Higher adjacent rate's throughput is measured */ | 1679 | IWL_DEBUG_RATE(mvm, |
1699 | if (high_tpt != IWL_INVALID_VALUE) { | 1680 | "No data about high rate and low rate is worse. Increase rate\n"); |
1700 | /* Higher rate has better throughput */ | 1681 | return RS_ACTION_UPSCALE; |
1701 | if (high_tpt > current_tpt && | 1682 | } |
1702 | sr >= IWL_RATE_INCREASE_TH) { | ||
1703 | IWL_DEBUG_RATE(mvm, | ||
1704 | "Higher rate is better and good " | ||
1705 | "SR. Increate rate\n"); | ||
1706 | action = RS_ACTION_UPSCALE; | ||
1707 | } else { | ||
1708 | IWL_DEBUG_RATE(mvm, | ||
1709 | "Higher rate isn't better OR " | ||
1710 | "no good SR. Maintain rate\n"); | ||
1711 | action = RS_ACTION_STAY; | ||
1712 | } | ||
1713 | 1683 | ||
1714 | /* Lower adjacent rate's throughput is measured */ | 1684 | if ((high_tpt != IWL_INVALID_VALUE) && |
1715 | } else if (low_tpt != IWL_INVALID_VALUE) { | 1685 | (high_tpt > current_tpt)) { |
1716 | /* Lower rate has better throughput */ | 1686 | IWL_DEBUG_RATE(mvm, |
1717 | if (low_tpt > current_tpt) { | 1687 | "Higher rate is better. Increate rate\n"); |
1718 | IWL_DEBUG_RATE(mvm, | 1688 | return RS_ACTION_UPSCALE; |
1719 | "Lower rate is better. " | ||
1720 | "Decrease rate\n"); | ||
1721 | action = RS_ACTION_DOWNSCALE; | ||
1722 | } else if (sr >= IWL_RATE_INCREASE_TH) { | ||
1723 | IWL_DEBUG_RATE(mvm, | ||
1724 | "Lower rate isn't better and " | ||
1725 | "good SR. Increase rate\n"); | ||
1726 | action = RS_ACTION_UPSCALE; | ||
1727 | } | ||
1728 | } | ||
1729 | } | 1689 | } |
1730 | 1690 | ||
1731 | /* Sanity check; asked for decrease, but success rate or throughput | 1691 | if ((low_tpt != IWL_INVALID_VALUE) && |
1732 | * has been good at old rate. Don't change it. | 1692 | (high_tpt != IWL_INVALID_VALUE) && |
1733 | */ | 1693 | (low_tpt < current_tpt) && |
1734 | if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) && | 1694 | (high_tpt < current_tpt)) { |
1735 | ((sr > IWL_RATE_HIGH_TH) || | ||
1736 | (current_tpt > (100 * tbl->expected_tpt[low])))) { | ||
1737 | IWL_DEBUG_RATE(mvm, | 1695 | IWL_DEBUG_RATE(mvm, |
1738 | "Sanity check failed. Maintain rate\n"); | 1696 | "Both high and low are worse. Maintain rate\n"); |
1739 | action = RS_ACTION_STAY; | 1697 | return RS_ACTION_STAY; |
1698 | } | ||
1699 | |||
1700 | if ((low_tpt != IWL_INVALID_VALUE) && | ||
1701 | (low_tpt > current_tpt)) { | ||
1702 | IWL_DEBUG_RATE(mvm, | ||
1703 | "Lower rate is better\n"); | ||
1704 | action = RS_ACTION_DOWNSCALE; | ||
1705 | goto out; | ||
1706 | } | ||
1707 | |||
1708 | if ((low_tpt == IWL_INVALID_VALUE) && | ||
1709 | (low != IWL_RATE_INVALID)) { | ||
1710 | IWL_DEBUG_RATE(mvm, | ||
1711 | "No data about lower rate\n"); | ||
1712 | action = RS_ACTION_DOWNSCALE; | ||
1713 | goto out; | ||
1714 | } | ||
1715 | |||
1716 | IWL_DEBUG_RATE(mvm, "Maintain rate\n"); | ||
1717 | |||
1718 | out: | ||
1719 | if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { | ||
1720 | if (sr >= RS_SR_NO_DECREASE) { | ||
1721 | IWL_DEBUG_RATE(mvm, | ||
1722 | "SR is above NO DECREASE. Avoid downscale\n"); | ||
1723 | action = RS_ACTION_STAY; | ||
1724 | } else if (current_tpt > (100 * tbl->expected_tpt[low])) { | ||
1725 | IWL_DEBUG_RATE(mvm, | ||
1726 | "Current TPT is higher than max expected in low rate. Avoid downscale\n"); | ||
1727 | action = RS_ACTION_STAY; | ||
1728 | } else { | ||
1729 | IWL_DEBUG_RATE(mvm, "Decrease rate\n"); | ||
1730 | } | ||
1740 | } | 1731 | } |
1741 | 1732 | ||
1742 | return action; | 1733 | return action; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index 9892d92d5901..fbb476aadb22 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h | |||
@@ -156,6 +156,7 @@ enum { | |||
156 | #define IWL_RATE_HIGH_TH 10880 /* 85% */ | 156 | #define IWL_RATE_HIGH_TH 10880 /* 85% */ |
157 | #define IWL_RATE_INCREASE_TH 6400 /* 50% */ | 157 | #define IWL_RATE_INCREASE_TH 6400 /* 50% */ |
158 | #define RS_SR_FORCE_DECREASE 1920 /* 15% */ | 158 | #define RS_SR_FORCE_DECREASE 1920 /* 15% */ |
159 | #define RS_SR_NO_DECREASE 10880 /* 85% */ | ||
159 | 160 | ||
160 | #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ | 161 | #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ |
161 | #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) | 162 | #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) |