lede/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch
AmadeusGhost b1677a562c
mac80211: bump to 5.8-rc2, add ath10k VHT support and very basic support for ipq807x ath11k (#5288)
* mac80211: bump to 5.8-rc2

changelog:
  dfe0bc8 mac80211: allow ACS restriction with fixed channel
  727685c mac80211: rt2x00: define RF5592 in init_eeprom routine
  cfd2f3b mac80211: create channel list for fixed channel operation
  d1100c7 mac80211: Update to version 5.7.5-1
  ed2015c mac80211: Update to version 5.8-rc2-1
  a956c14 mac80211: util: don't warn on missing sband iftype data
  8b3e170 hostapd: fix incorrect service name
  68bf5a9 mac80211: don't kill wireless daemon on teardown
  25e0ae6 mac80211: make cfg80211 testmode support optional (and disabled by default)
  b7727a8 mac80211: fix AQL issues
  3d731fc mac80211: merge performance improvement patches

* mt76: update to 2020-07-22

Signed-off-by: Felix Fietkau <nbd@nbd.name>

* mac80211: allow VHT on 2.4GHz

Allow VHT rate on 2.4GHz in order to use 256-QAM

Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>

* ath10k: allow VHT on 2.4GHz

Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>

* hostapd: add vendor_vht option

hostapd has vendor_vht option to enable VHT (256-QAM) on 2.4GHz
Add this option to hostapd.sh so users can enable it via uci

Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>

* ipq807x: Refresh kernel configuration

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

* ipq807x: Add WCSS bus

This is needed to build ath11k.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

* mac80211: Add ath11k

This adds the Qualcomm 802.11ax wireless chipset support.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

Co-authored-by: Felix Fietkau <nbd@nbd.name>
Co-authored-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
Co-authored-by: Hauke Mehrtens <hauke@hauke-m.de>
2020-08-07 23:53:02 +08:00

202 lines
6.9 KiB
Diff

From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 17 Mar 2019 18:11:30 +0100
Subject: [PATCH] mac80211: optimize skb resizing
When forwarding unicast packets from ethernet to batman-adv over 802.11s
(with forwarding disabled), the typical required headroom to transmit
encrypted packets on mt76 is 32 (802.11) + 6 (802.11s) + 8 (CCMP) +
2 (padding) + 6 (LLC) + 18 (batman-adv) - 14 (old ethernet header) = 58 bytes.
On systems where NET_SKB_PAD is 64 this leads to a call to pskb_expand_head
for every packet, since mac80211 also tries to allocate 16 bytes status
headroom for radiotap headers.
This patch fixes these unnecessary reallocations by only requiring the extra
status headroom in ieee80211_tx_monitor()
If however a reallocation happens before that call, the status headroom gets
added there as well, in order to avoid double reallocation.
The patch also cleans up the code by moving the headroom calculation to
ieee80211_skb_resize.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1809,6 +1809,9 @@ int ieee80211_tx_control_port(struct wip
u64 *cookie);
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len);
+int ieee80211_skb_resize(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, int hdrlen, int hdr_add);
/* HT */
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -835,6 +835,11 @@ void ieee80211_tx_monitor(struct ieee802
struct net_device *prev_dev = NULL;
int rtap_len;
+ if (ieee80211_skb_resize(local, NULL, skb, 0, 0)) {
+ dev_kfree_skb(skb);
+ return;
+ }
+
/* send frame to monitor interfaces now */
rtap_len = ieee80211_tx_radiotap_len(info, status);
if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1937,37 +1937,53 @@ static bool ieee80211_tx(struct ieee8021
}
/* device xmit handlers */
-
-static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb,
- int head_need, bool may_encrypt)
+int ieee80211_skb_resize(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, int hdr_len, int hdr_extra)
{
- struct ieee80211_local *local = sdata->local;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr;
- bool enc_tailroom;
- int tail_need = 0;
-
- hdr = (struct ieee80211_hdr *) skb->data;
- enc_tailroom = may_encrypt &&
- (sdata->crypto_tx_tailroom_needed_cnt ||
- ieee80211_is_mgmt(hdr->frame_control));
-
- if (enc_tailroom) {
- tail_need = IEEE80211_ENCRYPT_TAILROOM;
- tail_need -= skb_tailroom(skb);
- tail_need = max_t(int, tail_need, 0);
+ int head_need, head_max;
+ int tail_need, tail_max;
+ bool enc_tailroom = false;
+
+ if (sdata && !hdr_len &&
+ !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
+ hdr = (struct ieee80211_hdr *) skb->data;
+ enc_tailroom = (sdata->crypto_tx_tailroom_needed_cnt ||
+ ieee80211_is_mgmt(hdr->frame_control));
+ hdr_len += sdata->encrypt_headroom;
+ }
+
+ head_need = head_max = hdr_len;
+ tail_need = tail_max = 0;
+ if (!sdata) {
+ head_need = head_max = local->tx_headroom;
+ } else {
+ head_max += hdr_extra;
+ head_max += max_t(int, local->tx_headroom,
+ local->hw.extra_tx_headroom);
+ head_need += local->hw.extra_tx_headroom;
+
+ tail_max = IEEE80211_ENCRYPT_TAILROOM;
+ if (enc_tailroom)
+ tail_need = tail_max;
}
if (skb_cloned(skb) &&
(!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) ||
!skb_clone_writable(skb, ETH_HLEN) || enc_tailroom))
I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
- else if (head_need || tail_need)
+ else if (head_need > skb_headroom(skb) ||
+ tail_need > skb_tailroom(skb))
I802_DEBUG_INC(local->tx_expand_skb_head);
else
return 0;
- if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
+ head_max = max_t(int, 0, head_max - skb_headroom(skb));
+ tail_max = max_t(int, 0, tail_max - skb_tailroom(skb));
+
+ if (pskb_expand_head(skb, head_max, tail_max, GFP_ATOMIC)) {
wiphy_debug(local->hw.wiphy,
"failed to reallocate TX buffer\n");
return -ENOMEM;
@@ -1983,18 +1999,8 @@ void ieee80211_xmit(struct ieee80211_sub
struct ieee80211_local *local = sdata->local;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr;
- int headroom;
- bool may_encrypt;
-
- may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
- headroom = local->tx_headroom;
- if (may_encrypt)
- headroom += sdata->encrypt_headroom;
- headroom -= skb_headroom(skb);
- headroom = max_t(int, 0, headroom);
-
- if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
+ if (ieee80211_skb_resize(local, sdata, skb, 0, 0)) {
ieee80211_free_txskb(&local->hw, skb);
return;
}
@@ -2809,29 +2815,13 @@ static struct sk_buff *ieee80211_build_h
}
skb_pull(skb, skip_header_bytes);
- head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
+ head_need = hdrlen + encaps_len + meshhdrlen;
- /*
- * So we need to modify the skb header and hence need a copy of
- * that. The head_need variable above doesn't, so far, include
- * the needed header space that we don't need right away. If we
- * can, then we don't reallocate right now but only after the
- * frame arrives at the master device (if it does...)
- *
- * If we cannot, however, then we will reallocate to include all
- * the ever needed space. Also, if we need to reallocate it anyway,
- * make it big enough for everything we may ever need.
- */
-
- if (head_need > 0 || skb_cloned(skb)) {
- head_need += sdata->encrypt_headroom;
- head_need += local->tx_headroom;
- head_need = max_t(int, 0, head_need);
- if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
- ieee80211_free_txskb(&local->hw, skb);
- skb = NULL;
- return ERR_PTR(-ENOMEM);
- }
+ if (ieee80211_skb_resize(local, sdata, skb, head_need,
+ sdata->encrypt_headroom)) {
+ ieee80211_free_txskb(&local->hw, skb);
+ skb = NULL;
+ return ERR_PTR(-ENOMEM);
}
if (encaps_data)
@@ -3446,7 +3436,6 @@ static bool ieee80211_xmit_fast(struct i
struct ieee80211_local *local = sdata->local;
u16 ethertype = (skb->data[12] << 8) | skb->data[13];
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
- int hw_headroom = sdata->local->hw.extra_tx_headroom;
struct ethhdr eth;
struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
@@ -3498,10 +3487,7 @@ static bool ieee80211_xmit_fast(struct i
* as the may-encrypt argument for the resize to not account for
* more room than we already have in 'extra_head'
*/
- if (unlikely(ieee80211_skb_resize(sdata, skb,
- max_t(int, extra_head + hw_headroom -
- skb_headroom(skb), 0),
- false))) {
+ if (unlikely(ieee80211_skb_resize(local, sdata, skb, extra_head, 0))) {
kfree_skb(skb);
return true;
}