Root/package/madwifi/patches/342-performance.patch

1--- a/ath/if_ath.c
2+++ b/ath/if_ath.c
3@@ -3239,7 +3239,6 @@ ath_hardstart(struct sk_buff *skb, struc
4     struct ath_softc *sc = dev->priv;
5     struct ieee80211_node *ni = NULL;
6     struct ath_buf *bf = NULL;
7- struct ether_header *eh;
8     ath_bufhead bf_head;
9     struct ath_buf *tbf, *tempbf;
10     struct sk_buff *tskb;
11@@ -3251,6 +3250,7 @@ ath_hardstart(struct sk_buff *skb, struc
12     */
13     int requeue = 0;
14 #ifdef ATH_SUPERG_FF
15+ struct ether_header *eh;
16     unsigned int pktlen;
17     struct ieee80211com *ic = &sc->sc_ic;
18     struct ath_node *an;
19@@ -3316,27 +3316,9 @@ ath_hardstart(struct sk_buff *skb, struc
20         requeue = 1;
21         goto hardstart_fail;
22     }
23-#endif
24 
25- /* If the skb data is shared, we will copy it so we can strip padding
26- * without affecting any other bridge ports. */
27- if (skb_cloned(skb)) {
28- /* Remember the original SKB so we can free up our references */
29- struct sk_buff *skb_new;
30- skb_new = skb_copy(skb, GFP_ATOMIC);
31- if (skb_new == NULL) {
32- DPRINTF(sc, ATH_DEBUG_XMIT,
33- "Dropping; skb_copy failure.\n");
34- /* No free RAM, do not requeue! */
35- goto hardstart_fail;
36- }
37- ieee80211_skb_copy_noderef(skb, skb_new);
38- ieee80211_dev_kfree_skb(&skb);
39- skb = skb_new;
40- }
41     eh = (struct ether_header *)skb->data;
42 
43-#ifdef ATH_SUPERG_FF
44     /* NB: use this lock to protect an->an_tx_ffbuf (and txq->axq_stageq)
45      * in athff_can_aggregate() call too. */
46     ATH_TXQ_LOCK_IRQ(txq);
47--- a/net80211/ieee80211_output.c
48+++ b/net80211/ieee80211_output.c
49@@ -283,7 +283,7 @@ ieee80211_hardstart(struct sk_buff *skb,
50      * normal vap. */
51     if (vap->iv_xrvap && (ni == vap->iv_bss) &&
52         vap->iv_xrvap->iv_sta_assoc) {
53- struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC);
54+ struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC);
55         if (skb1) {
56             memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb));
57 #ifdef IEEE80211_DEBUG_REFCNT
58@@ -566,7 +566,7 @@ ieee80211_skbhdr_adjust(struct ieee80211
59     struct ieee80211_key *key, struct sk_buff *skb, int ismulticast)
60 {
61     /* XXX pre-calculate per node? */
62- int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN;
63+ int need_headroom = LLC_SNAPFRAMELEN + hdrsize;
64     int need_tailroom = 0;
65 #ifdef ATH_SUPERG_FF
66     int isff = ATH_FF_MAGIC_PRESENT(skb);
67@@ -608,109 +608,56 @@ ieee80211_skbhdr_adjust(struct ieee80211
68                 need_tailroom += cip->ic_miclen;
69     }
70 
71- if (skb_shared(skb)) {
72- /* Take our own reference to the node in the clone */
73- ieee80211_ref_node(SKB_CB(skb)->ni);
74- /* Unshare the node, decrementing users in the old skb */
75- skb = skb_unshare(skb, GFP_ATOMIC);
76+ need_headroom -= skb_headroom(skb);
77+ if (isff)
78+ need_tailroom -= skb_tailroom(skb2);
79+ else
80+ need_tailroom -= skb_tailroom(skb);
81+
82+ if (need_headroom < 0)
83+ need_headroom = 0;
84+ if (need_tailroom < 0)
85+ need_tailroom = 0;
86+
87+ if (skb_cloned(skb) || (need_headroom > 0) ||
88+ (!isff && (need_tailroom > 0))) {
89+
90+ if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) {
91+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
92+ "%s: cannot expand storage (tail)\n", __func__);
93+ goto error;
94+ }
95     }
96 
97 #ifdef ATH_SUPERG_FF
98     if (isff) {
99- if (skb == NULL) {
100- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
101- "%s: cannot unshare for encapsulation\n",
102- __func__);
103- vap->iv_stats.is_tx_nobuf++;
104- ieee80211_dev_kfree_skb(&skb2);
105-
106- return NULL;
107- }
108+ inter_headroom -= skb_headroom(skb2);
109+ if (inter_headroom < 0)
110+ inter_headroom = 0;
111+ if ((skb_cloned(skb2) ||
112+ (inter_headroom > 0) || (need_tailroom > 0))) {
113 
114- /* first skb header */
115- if (skb_headroom(skb) < need_headroom) {
116- struct sk_buff *tmp = skb;
117- skb = skb_realloc_headroom(skb, need_headroom);
118- if (skb == NULL) {
119+ if (pskb_expand_head(skb2, inter_headroom,
120+ need_tailroom, GFP_ATOMIC)) {
121                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
122- "%s: cannot expand storage (head1)\n",
123- __func__);
124- vap->iv_stats.is_tx_nobuf++;
125- ieee80211_dev_kfree_skb(&skb2);
126- return NULL;
127- } else
128- ieee80211_skb_copy_noderef(tmp, skb);
129- ieee80211_dev_kfree_skb(&tmp);
130- /* NB: cb[] area was copied, but not next ptr. must do that
131- * prior to return on success. */
132- }
133-
134- /* second skb with header and tail adjustments possible */
135- if (skb_tailroom(skb2) < need_tailroom) {
136- int n = 0;
137- if (inter_headroom > skb_headroom(skb2))
138- n = inter_headroom - skb_headroom(skb2);
139- if (pskb_expand_head(skb2, n,
140- need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) {
141- ieee80211_dev_kfree_skb(&skb2);
142- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
143- "%s: cannot expand storage (tail2)\n",
144- __func__);
145- vap->iv_stats.is_tx_nobuf++;
146- /* this shouldn't happen, but don't send first ff either */
147- ieee80211_dev_kfree_skb(&skb);
148+ "%s: cannot expand storage (tail)\n", __func__);
149+ goto error;
150             }
151- } else if (skb_headroom(skb2) < inter_headroom) {
152- struct sk_buff *tmp = skb2;
153-
154- skb2 = skb_realloc_headroom(skb2, inter_headroom);
155- if (skb2 == NULL) {
156- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
157- "%s: cannot expand storage (head2)\n",
158- __func__);
159- vap->iv_stats.is_tx_nobuf++;
160- /* this shouldn't happen, but don't send first ff either */
161- ieee80211_dev_kfree_skb(&skb);
162- skb = NULL;
163- } else
164- ieee80211_skb_copy_noderef(tmp, skb);
165- ieee80211_dev_kfree_skb(&tmp);
166         }
167- if (skb) {
168- skb->next = skb2;
169- }
170- return skb;
171+ skb->next = skb2;
172     }
173 #endif /* ATH_SUPERG_FF */
174- if (skb == NULL) {
175- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
176- "%s: cannot unshare for encapsulation\n", __func__);
177- vap->iv_stats.is_tx_nobuf++;
178- } else if (skb_tailroom(skb) < need_tailroom) {
179- int n = 0;
180- if (need_headroom > skb_headroom(skb))
181- n = need_headroom - skb_headroom(skb);
182- if (pskb_expand_head(skb, n, need_tailroom -
183- skb_tailroom(skb), GFP_ATOMIC)) {
184- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
185- "%s: cannot expand storage (tail)\n", __func__);
186- vap->iv_stats.is_tx_nobuf++;
187- ieee80211_dev_kfree_skb(&skb);
188- }
189- } else if (skb_headroom(skb) < need_headroom) {
190- struct sk_buff *tmp = skb;
191- skb = skb_realloc_headroom(skb, need_headroom);
192- /* Increment reference count after copy */
193- if (skb == NULL) {
194- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
195- "%s: cannot expand storage (head)\n", __func__);
196- vap->iv_stats.is_tx_nobuf++;
197- } else
198- ieee80211_skb_copy_noderef(tmp, skb);
199- ieee80211_dev_kfree_skb(&tmp);
200- }
201 
202     return skb;
203+
204+error:
205+ vap->iv_stats.is_tx_nobuf++;
206+ ieee80211_dev_kfree_skb(&skb);
207+#ifdef ATH_SUPERG_FF
208+ if (skb2)
209+ ieee80211_dev_kfree_skb(&skb2);
210+#endif
211+ return NULL;
212 }
213 
214 #define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none)
215--- a/net80211/ieee80211_input.c
216+++ b/net80211/ieee80211_input.c
217@@ -204,7 +204,6 @@ ieee80211_input(struct ieee80211vap * va
218     struct ieee80211_frame *wh;
219     struct ieee80211_key *key;
220     struct ether_header *eh;
221- struct sk_buff *skb2;
222 #ifdef ATH_SUPERG_FF
223     struct llc *llc;
224 #endif
225@@ -244,20 +243,6 @@ ieee80211_input(struct ieee80211vap * va
226         vap->iv_stats.is_rx_tooshort++;
227         goto out;
228     }
229- /* Clone the SKB... we assume somewhere in this driver that we 'own'
230- * the skbuff passed into hard start and we do a lot of messing with it
231- * but bridges under some cases will not clone for the first pass of skb
232- * to a bridge port, but will then clone for subsequent ones. This is
233- * odd behavior but it means that if we have trashed the skb we are given
234- * then other ports get clones of the residual garbage.
235- */
236- if ((skb2 = skb_copy(skb, GFP_ATOMIC)) == NULL) {
237- vap->iv_devstats.tx_dropped++;
238- goto out;
239- }
240- ieee80211_skb_copy_noderef(skb, skb2);
241- ieee80211_dev_kfree_skb(&skb);
242- skb = skb2;
243 
244     /*
245      * Bit of a cheat here, we use a pointer for a 3-address
246@@ -738,7 +723,7 @@ ieee80211_input(struct ieee80211vap * va
247             /* ether_type must be length as FF frames are always LLC/SNAP encap'd */
248             frame_len = ntohs(eh_tmp->ether_type);
249 
250- skb1 = skb_copy(skb, GFP_ATOMIC);
251+ skb1 = skb_clone(skb, GFP_ATOMIC);
252             if (skb1 == NULL)
253                 goto err;
254             ieee80211_skb_copy_noderef(skb, skb1);
255@@ -1137,7 +1122,7 @@ ieee80211_deliver_data(struct ieee80211_
256 
257         if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
258             /* Create a SKB for the BSS to send out. */
259- skb1 = skb_copy(skb, GFP_ATOMIC);
260+ skb1 = skb_clone(skb, GFP_ATOMIC);
261             if (skb1)
262                 SKB_CB(skb1)->ni = ieee80211_ref_node(vap->iv_bss);
263         }
264

Archive Download this file



interactive