diff options
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch')
-rw-r--r-- | package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch new file mode 100644 index 0000000000..ed9efb2b0d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch @@ -0,0 +1,174 @@ +From: Felix Fietkau <nbd@nbd.name> +Date: Mon, 17 Aug 2020 13:29:56 +0200 +Subject: [PATCH] mac80211: optimize station connection monitor + +Calling mod_timer for every rx/tx packet can be quite expensive. +Instead of constantly updating the timer, we can simply let it run out +and check the timestamp of the last ACK or rx packet to re-arm it. + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2045,8 +2045,6 @@ void ieee80211_dynamic_ps_timer(struct t + void ieee80211_send_nullfunc(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + bool powersave); +-void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, +- struct ieee80211_hdr *hdr); + void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr, bool ack, u16 tx_time); + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2432,23 +2432,6 @@ static void ieee80211_set_disassoc(struc + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; + } + +-void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, +- struct ieee80211_hdr *hdr) +-{ +- /* +- * We can postpone the mgd.timer whenever receiving unicast frames +- * from AP because we know that the connection is working both ways +- * at that time. But multicast frames (and hence also beacons) must +- * be ignored here, because we need to trigger the timer during +- * data idle periods for sending the periodic probe request to the +- * AP we're connected to. +- */ +- if (is_multicast_ether_addr(hdr->addr1)) +- return; +- +- ieee80211_sta_reset_conn_monitor(sdata); +-} +- + static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) + { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; +@@ -2521,21 +2504,13 @@ void ieee80211_sta_tx_notify(struct ieee + { + ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time); + +- if (!ieee80211_is_data(hdr->frame_control)) +- return; +- +- if (ieee80211_is_any_nullfunc(hdr->frame_control) && +- sdata->u.mgd.probe_send_count > 0) { +- if (ack) +- ieee80211_sta_reset_conn_monitor(sdata); +- else +- sdata->u.mgd.nullfunc_failed = true; +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ if (!ieee80211_is_any_nullfunc(hdr->frame_control) || ++ !sdata->u.mgd.probe_send_count) + return; +- } + +- if (ack) +- ieee80211_sta_reset_conn_monitor(sdata); ++ if (!ack) ++ sdata->u.mgd.nullfunc_failed = true; ++ ieee80211_queue_work(&sdata->local->hw, &sdata->work); + } + + static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata, +@@ -3600,8 +3575,8 @@ static bool ieee80211_assoc_success(stru + * Start timer to probe the connection to the AP now. + * Also start the timer that will detect beacon loss. + */ +- ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); + ieee80211_sta_reset_beacon_monitor(sdata); ++ ieee80211_sta_reset_conn_monitor(sdata); + + ret = true; + out: +@@ -4569,10 +4544,26 @@ static void ieee80211_sta_conn_mon_timer + from_timer(sdata, t, u.mgd.conn_mon_timer); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_local *local = sdata->local; ++ struct sta_info *sta; ++ unsigned long timeout; + + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) + return; + ++ sta = sta_info_get(sdata, ifmgd->bssid); ++ if (!sta) ++ return; ++ ++ timeout = sta->status_stats.last_ack; ++ if (time_before(sta->status_stats.last_ack, sta->rx_stats.last_rx)) ++ timeout = sta->rx_stats.last_rx; ++ timeout += IEEE80211_CONNECTION_IDLE_TIME; ++ ++ if (time_is_before_jiffies(timeout)) { ++ mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout)); ++ return; ++ } ++ + ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); + } + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1811,9 +1811,6 @@ ieee80211_rx_h_sta_process(struct ieee80 + sta->rx_stats.last_rate = sta_stats_encode_rate(status); + } + +- if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) +- ieee80211_sta_rx_notify(rx->sdata, hdr); +- + sta->rx_stats.fragments++; + + u64_stats_update_begin(&rx->sta->rx_stats.syncp); +@@ -4148,7 +4145,6 @@ void ieee80211_check_fast_rx(struct sta_ + fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); + fastrx.expected_ds_bits = 0; + } else { +- fastrx.sta_notify = sdata->u.mgd.probe_send_count > 0; + fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); + fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr3); + fastrx.expected_ds_bits = +@@ -4378,11 +4374,6 @@ static bool ieee80211_invoke_fast_rx(str + pskb_trim(skb, skb->len - fast_rx->icv_len)) + goto drop; + +- if (unlikely(fast_rx->sta_notify)) { +- ieee80211_sta_rx_notify(rx->sdata, hdr); +- fast_rx->sta_notify = false; +- } +- + /* statistics part of ieee80211_rx_h_sta_process() */ + if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { + stats->last_signal = status->signal; +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -336,7 +336,6 @@ struct ieee80211_fast_tx { + * @expected_ds_bits: from/to DS bits expected + * @icv_len: length of the MIC if present + * @key: bool indicating encryption is expected (key is set) +- * @sta_notify: notify the MLME code (once) + * @internal_forward: forward froms internally on AP/VLAN type interfaces + * @uses_rss: copy of USES_RSS hw flag + * @da_offs: offset of the DA in the header (for header conversion) +@@ -352,7 +351,6 @@ struct ieee80211_fast_rx { + __le16 expected_ds_bits; + u8 icv_len; + u8 key:1, +- sta_notify:1, + internal_forward:1, + uses_rss:1; + u8 da_offs, sa_offs; +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -1227,9 +1227,6 @@ void ieee80211_tx_status_8023(struct iee + sta->status_stats.retry_count += retry_count; + + if (ieee80211_hw_check(hw, REPORTS_TX_ACK_STATUS)) { +- if (acked && vif->type == NL80211_IFTYPE_STATION) +- ieee80211_sta_reset_conn_monitor(sdata); +- + sta->status_stats.last_ack = jiffies; + if (info->flags & IEEE80211_TX_STAT_ACK) { + if (sta->status_stats.lost_packets) |