mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 01:28:59 +00:00
175 lines
5.9 KiB
Diff
175 lines
5.9 KiB
Diff
|
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)
|