mac80211: Update to version 4.19.221
[librecmc/librecmc.git] / package / kernel / mac80211 / patches / subsys / 357-mac80211-optimize-skb-resizing.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Sun, 17 Mar 2019 18:11:30 +0100
3 Subject: [PATCH] mac80211: optimize skb resizing
4
5 When forwarding unicast packets from ethernet to batman-adv over 802.11s
6 (with forwarding disabled), the typical required headroom to transmit
7 encrypted packets on mt76 is 32 (802.11) + 6 (802.11s) + 8 (CCMP) +
8 2 (padding) + 6 (LLC) + 18 (batman-adv) - 14 (old ethernet header) = 58 bytes.
9
10 On systems where NET_SKB_PAD is 64 this leads to a call to pskb_expand_head
11 for every packet, since mac80211 also tries to allocate 16 bytes status
12 headroom for radiotap headers.
13
14 This patch fixes these unnecessary reallocations by only requiring the extra
15 status headroom in ieee80211_tx_monitor()
16 If however a reallocation happens before that call, the status headroom gets
17 added there as well, in order to avoid double reallocation.
18
19 The patch also cleans up the code by moving the headroom calculation to
20 ieee80211_skb_resize.
21
22 Signed-off-by: Felix Fietkau <nbd@nbd.name>
23 ---
24
25 --- a/net/mac80211/ieee80211_i.h
26 +++ b/net/mac80211/ieee80211_i.h
27 @@ -1750,6 +1750,9 @@ void ieee80211_clear_fast_xmit(struct st
28  int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
29                               const u8 *buf, size_t len,
30                               const u8 *dest, __be16 proto, bool unencrypted);
31 +int ieee80211_skb_resize(struct ieee80211_local *local,
32 +                        struct ieee80211_sub_if_data *sdata,
33 +                        struct sk_buff *skb, int hdrlen, int hdr_add);
34  
35  /* HT */
36  void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
37 --- a/net/mac80211/status.c
38 +++ b/net/mac80211/status.c
39 @@ -671,6 +671,11 @@ void ieee80211_tx_monitor(struct ieee802
40                 }
41         }
42  
43 +       if (ieee80211_skb_resize(local, NULL, skb, 0, 0)) {
44 +               dev_kfree_skb(skb);
45 +               return;
46 +       }
47 +
48         /* send frame to monitor interfaces now */
49         rtap_len = ieee80211_tx_radiotap_len(info);
50         if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
51 --- a/net/mac80211/tx.c
52 +++ b/net/mac80211/tx.c
53 @@ -1920,42 +1920,53 @@ static bool ieee80211_tx(struct ieee8021
54  }
55  
56  /* device xmit handlers */
57 -
58 -enum ieee80211_encrypt {
59 -       ENCRYPT_NO,
60 -       ENCRYPT_MGMT,
61 -       ENCRYPT_DATA,
62 -};
63 -
64 -static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
65 -                               struct sk_buff *skb,
66 -                               int head_need,
67 -                               enum ieee80211_encrypt encrypt)
68 +int ieee80211_skb_resize(struct ieee80211_local *local,
69 +                        struct ieee80211_sub_if_data *sdata,
70 +                        struct sk_buff *skb, int hdr_len, int hdr_extra)
71  {
72 -       struct ieee80211_local *local = sdata->local;
73 -       bool enc_tailroom;
74 -       int tail_need = 0;
75 -
76 -       enc_tailroom = encrypt == ENCRYPT_MGMT ||
77 -                      (encrypt == ENCRYPT_DATA &&
78 -                       sdata->crypto_tx_tailroom_needed_cnt);
79 -
80 -       if (enc_tailroom) {
81 -               tail_need = IEEE80211_ENCRYPT_TAILROOM;
82 -               tail_need -= skb_tailroom(skb);
83 -               tail_need = max_t(int, tail_need, 0);
84 +       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
85 +       struct ieee80211_hdr *hdr;
86 +       int head_need, head_max;
87 +       int tail_need, tail_max;
88 +       bool enc_tailroom = false;
89 +
90 +       if (sdata && !hdr_len &&
91 +           !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
92 +               hdr = (struct ieee80211_hdr *) skb->data;
93 +               enc_tailroom = (sdata->crypto_tx_tailroom_needed_cnt ||
94 +                               ieee80211_is_mgmt(hdr->frame_control));
95 +               hdr_len += sdata->encrypt_headroom;
96 +       }
97 +
98 +       head_need = head_max = hdr_len;
99 +       tail_need = tail_max = 0;
100 +       if (!sdata) {
101 +               head_need = head_max = local->tx_headroom;
102 +       } else {
103 +               head_max += hdr_extra;
104 +               head_max += max_t(int, local->tx_headroom,
105 +                                 local->hw.extra_tx_headroom);
106 +               head_need += local->hw.extra_tx_headroom;
107 +
108 +               tail_max = IEEE80211_ENCRYPT_TAILROOM;
109 +               if (enc_tailroom)
110 +                       tail_need = tail_max;
111         }
112  
113         if (skb_cloned(skb) &&
114             (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) ||
115              !skb_clone_writable(skb, ETH_HLEN) || enc_tailroom))
116                 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
117 -       else if (head_need || tail_need)
118 +       else if (head_need > skb_headroom(skb) ||
119 +                tail_need > skb_tailroom(skb))
120                 I802_DEBUG_INC(local->tx_expand_skb_head);
121         else
122                 return 0;
123  
124 -       if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
125 +       head_max = max_t(int, 0, head_max - skb_headroom(skb));
126 +       tail_max = max_t(int, 0, tail_max - skb_tailroom(skb));
127 +
128 +       if (pskb_expand_head(skb, head_max, tail_max, GFP_ATOMIC)) {
129                 wiphy_debug(local->hw.wiphy,
130                             "failed to reallocate TX buffer\n");
131                 return -ENOMEM;
132 @@ -1970,24 +1981,9 @@ void ieee80211_xmit(struct ieee80211_sub
133  {
134         struct ieee80211_local *local = sdata->local;
135         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
136 -       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
137 -       int headroom;
138 -       enum ieee80211_encrypt encrypt;
139 -
140 -       if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)
141 -               encrypt = ENCRYPT_NO;
142 -       else if (ieee80211_is_mgmt(hdr->frame_control))
143 -               encrypt = ENCRYPT_MGMT;
144 -       else
145 -               encrypt = ENCRYPT_DATA;
146 -
147 -       headroom = local->tx_headroom;
148 -       if (encrypt != ENCRYPT_NO)
149 -               headroom += sdata->encrypt_headroom;
150 -       headroom -= skb_headroom(skb);
151 -       headroom = max_t(int, 0, headroom);
152 +       struct ieee80211_hdr *hdr;
153  
154 -       if (ieee80211_skb_resize(sdata, skb, headroom, encrypt)) {
155 +       if (ieee80211_skb_resize(local, sdata, skb, 0, 0)) {
156                 ieee80211_free_txskb(&local->hw, skb);
157                 return;
158         }
159 @@ -2762,30 +2758,14 @@ static struct sk_buff *ieee80211_build_h
160  
161         skb_pull(skb, skip_header_bytes);
162         padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
163 -       head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
164 +       head_need = hdrlen + encaps_len + meshhdrlen;
165         head_need += padsize;
166  
167 -       /*
168 -        * So we need to modify the skb header and hence need a copy of
169 -        * that. The head_need variable above doesn't, so far, include
170 -        * the needed header space that we don't need right away. If we
171 -        * can, then we don't reallocate right now but only after the
172 -        * frame arrives at the master device (if it does...)
173 -        *
174 -        * If we cannot, however, then we will reallocate to include all
175 -        * the ever needed space. Also, if we need to reallocate it anyway,
176 -        * make it big enough for everything we may ever need.
177 -        */
178 -
179 -       if (head_need > 0 || skb_cloned(skb)) {
180 -               head_need += sdata->encrypt_headroom;
181 -               head_need += local->tx_headroom;
182 -               head_need = max_t(int, 0, head_need);
183 -               if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
184 -                       ieee80211_free_txskb(&local->hw, skb);
185 -                       skb = NULL;
186 -                       return ERR_PTR(-ENOMEM);
187 -               }
188 +       if (ieee80211_skb_resize(local, sdata, skb, head_need,
189 +                                sdata->encrypt_headroom)) {
190 +               ieee80211_free_txskb(&local->hw, skb);
191 +               skb = NULL;
192 +               return ERR_PTR(-ENOMEM);
193         }
194  
195         if (encaps_data)
196 @@ -3408,7 +3388,6 @@ static bool ieee80211_xmit_fast(struct i
197         struct ieee80211_local *local = sdata->local;
198         u16 ethertype = (skb->data[12] << 8) | skb->data[13];
199         int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
200 -       int hw_headroom = sdata->local->hw.extra_tx_headroom;
201         struct ethhdr eth;
202         struct ieee80211_tx_info *info;
203         struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
204 @@ -3460,10 +3439,7 @@ static bool ieee80211_xmit_fast(struct i
205          * as the may-encrypt argument for the resize to not account for
206          * more room than we already have in 'extra_head'
207          */
208 -       if (unlikely(ieee80211_skb_resize(sdata, skb,
209 -                                         max_t(int, extra_head + hw_headroom -
210 -                                                    skb_headroom(skb), 0),
211 -                                         ENCRYPT_NO))) {
212 +       if (unlikely(ieee80211_skb_resize(local, sdata, skb, extra_head, 0))) {
213                 kfree_skb(skb);
214                 return true;
215         }