321-mac80211-optimize-station-connection-monitor.patch 5.9 KB

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