f8287c53a7ac55b85a53de84e48b0f247f294835
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / subsys / 321-mac80211-optimize-station-connection-monitor.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Mon, 17 Aug 2020 13:29:56 +0200
3 Subject: [PATCH] mac80211: optimize station connection monitor
4
5 Calling mod_timer for every rx/tx packet can be quite expensive.
6 Instead of constantly updating the timer, we can simply let it run out
7 and check the timestamp of the last ACK or rx packet to re-arm it.
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 ---
11
12 --- a/net/mac80211/ieee80211_i.h
13 +++ b/net/mac80211/ieee80211_i.h
14 @@ -2045,8 +2045,6 @@ void ieee80211_dynamic_ps_timer(struct t
15 void ieee80211_send_nullfunc(struct ieee80211_local *local,
16 struct ieee80211_sub_if_data *sdata,
17 bool powersave);
18 -void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
19 - struct ieee80211_hdr *hdr);
20 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
21 struct ieee80211_hdr *hdr, bool ack, u16 tx_time);
22
23 --- a/net/mac80211/mlme.c
24 +++ b/net/mac80211/mlme.c
25 @@ -2432,23 +2432,6 @@ static void ieee80211_set_disassoc(struc
26 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
27 }
28
29 -void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
30 - struct ieee80211_hdr *hdr)
31 -{
32 - /*
33 - * We can postpone the mgd.timer whenever receiving unicast frames
34 - * from AP because we know that the connection is working both ways
35 - * at that time. But multicast frames (and hence also beacons) must
36 - * be ignored here, because we need to trigger the timer during
37 - * data idle periods for sending the periodic probe request to the
38 - * AP we're connected to.
39 - */
40 - if (is_multicast_ether_addr(hdr->addr1))
41 - return;
42 -
43 - ieee80211_sta_reset_conn_monitor(sdata);
44 -}
45 -
46 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
47 {
48 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
49 @@ -2521,21 +2504,13 @@ void ieee80211_sta_tx_notify(struct ieee
50 {
51 ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
52
53 - if (!ieee80211_is_data(hdr->frame_control))
54 - return;
55 -
56 - if (ieee80211_is_any_nullfunc(hdr->frame_control) &&
57 - sdata->u.mgd.probe_send_count > 0) {
58 - if (ack)
59 - ieee80211_sta_reset_conn_monitor(sdata);
60 - else
61 - sdata->u.mgd.nullfunc_failed = true;
62 - ieee80211_queue_work(&sdata->local->hw, &sdata->work);
63 + if (!ieee80211_is_any_nullfunc(hdr->frame_control) ||
64 + !sdata->u.mgd.probe_send_count)
65 return;
66 - }
67
68 - if (ack)
69 - ieee80211_sta_reset_conn_monitor(sdata);
70 + if (!ack)
71 + sdata->u.mgd.nullfunc_failed = true;
72 + ieee80211_queue_work(&sdata->local->hw, &sdata->work);
73 }
74
75 static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
76 @@ -3600,8 +3575,8 @@ static bool ieee80211_assoc_success(stru
77 * Start timer to probe the connection to the AP now.
78 * Also start the timer that will detect beacon loss.
79 */
80 - ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
81 ieee80211_sta_reset_beacon_monitor(sdata);
82 + ieee80211_sta_reset_conn_monitor(sdata);
83
84 ret = true;
85 out:
86 @@ -4569,10 +4544,26 @@ static void ieee80211_sta_conn_mon_timer
87 from_timer(sdata, t, u.mgd.conn_mon_timer);
88 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
89 struct ieee80211_local *local = sdata->local;
90 + struct sta_info *sta;
91 + unsigned long timeout;
92
93 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
94 return;
95
96 + sta = sta_info_get(sdata, ifmgd->bssid);
97 + if (!sta)
98 + return;
99 +
100 + timeout = sta->status_stats.last_ack;
101 + if (time_before(sta->status_stats.last_ack, sta->rx_stats.last_rx))
102 + timeout = sta->rx_stats.last_rx;
103 + timeout += IEEE80211_CONNECTION_IDLE_TIME;
104 +
105 + if (time_is_before_jiffies(timeout)) {
106 + mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
107 + return;
108 + }
109 +
110 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
111 }
112
113 --- a/net/mac80211/rx.c
114 +++ b/net/mac80211/rx.c
115 @@ -1812,9 +1812,6 @@ ieee80211_rx_h_sta_process(struct ieee80
116 sta->rx_stats.last_rate = sta_stats_encode_rate(status);
117 }
118
119 - if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
120 - ieee80211_sta_rx_notify(rx->sdata, hdr);
121 -
122 sta->rx_stats.fragments++;
123
124 u64_stats_update_begin(&rx->sta->rx_stats.syncp);
125 @@ -4149,7 +4146,6 @@ void ieee80211_check_fast_rx(struct sta_
126 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
127 fastrx.expected_ds_bits = 0;
128 } else {
129 - fastrx.sta_notify = sdata->u.mgd.probe_send_count > 0;
130 fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
131 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr3);
132 fastrx.expected_ds_bits =
133 @@ -4379,11 +4375,6 @@ static bool ieee80211_invoke_fast_rx(str
134 pskb_trim(skb, skb->len - fast_rx->icv_len))
135 goto drop;
136
137 - if (unlikely(fast_rx->sta_notify)) {
138 - ieee80211_sta_rx_notify(rx->sdata, hdr);
139 - fast_rx->sta_notify = false;
140 - }
141 -
142 /* statistics part of ieee80211_rx_h_sta_process() */
143 if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
144 stats->last_signal = status->signal;
145 --- a/net/mac80211/sta_info.h
146 +++ b/net/mac80211/sta_info.h
147 @@ -336,7 +336,6 @@ struct ieee80211_fast_tx {
148 * @expected_ds_bits: from/to DS bits expected
149 * @icv_len: length of the MIC if present
150 * @key: bool indicating encryption is expected (key is set)
151 - * @sta_notify: notify the MLME code (once)
152 * @internal_forward: forward froms internally on AP/VLAN type interfaces
153 * @uses_rss: copy of USES_RSS hw flag
154 * @da_offs: offset of the DA in the header (for header conversion)
155 @@ -352,7 +351,6 @@ struct ieee80211_fast_rx {
156 __le16 expected_ds_bits;
157 u8 icv_len;
158 u8 key:1,
159 - sta_notify:1,
160 internal_forward:1,
161 uses_rss:1;
162 u8 da_offs, sa_offs;
163 --- a/net/mac80211/status.c
164 +++ b/net/mac80211/status.c
165 @@ -1227,9 +1227,6 @@ void ieee80211_tx_status_8023(struct iee
166 sta->status_stats.retry_count += retry_count;
167
168 if (ieee80211_hw_check(hw, REPORTS_TX_ACK_STATUS)) {
169 - if (acked && vif->type == NL80211_IFTYPE_STATION)
170 - ieee80211_sta_reset_conn_monitor(sdata);
171 -
172 sta->status_stats.last_ack = jiffies;
173 if (info->flags & IEEE80211_TX_STAT_ACK) {
174 if (sta->status_stats.lost_packets)