huge madwifi update (work in progress, disabled by default, compiles but breaks at...
[openwrt.git] / package / madwifi / patches-r3776 / 309-performance.patch
diff --git a/package/madwifi/patches-r3776/309-performance.patch b/package/madwifi/patches-r3776/309-performance.patch
new file mode 100644 (file)
index 0000000..517c336
--- /dev/null
@@ -0,0 +1,221 @@
+Index: madwifi-trunk-r3776/ath/if_ath.c
+===================================================================
+--- madwifi-trunk-r3776.orig/ath/if_ath.c      2008-07-17 02:23:00.000000000 +0200
++++ madwifi-trunk-r3776/ath/if_ath.c   2008-07-17 02:28:06.000000000 +0200
+@@ -3334,7 +3334,6 @@
+       struct ath_softc *sc = dev->priv;
+       struct ieee80211_node *ni = NULL;
+       struct ath_buf *bf = NULL;
+-      struct ether_header *eh;
+       ath_bufhead bf_head;
+       struct ath_buf *tbf;
+       struct sk_buff *tskb;
+@@ -3349,6 +3348,7 @@
+       */
+       int requeue = 0;
+ #ifdef ATH_SUPERG_FF
++      struct ether_header *eh;
+       unsigned int pktlen;
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct ath_txq *txq = NULL;
+Index: madwifi-trunk-r3776/net80211/ieee80211_output.c
+===================================================================
+--- madwifi-trunk-r3776.orig/net80211/ieee80211_output.c       2008-07-17 00:21:29.000000000 +0200
++++ madwifi-trunk-r3776/net80211/ieee80211_output.c    2008-07-17 02:35:10.000000000 +0200
+@@ -280,7 +280,7 @@
+        * normal vap. */
+       if (vap->iv_xrvap && (ni == vap->iv_bss) &&
+           vap->iv_xrvap->iv_sta_assoc) {
+-              struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC);
++              struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC);
+               if (skb1) {
+                       memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb));
+ #ifdef IEEE80211_DEBUG_REFCNT
+@@ -561,7 +561,7 @@
+       struct ieee80211_key *key, struct sk_buff *skb, int ismulticast)
+ {
+       /* XXX pre-calculate per node? */
+-      int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN;
++      int need_headroom = LLC_SNAPFRAMELEN + hdrsize;
+       int need_tailroom = 0;
+ #ifdef ATH_SUPERG_FF
+       int isff = ATH_FF_MAGIC_PRESENT(skb);
+@@ -603,109 +603,56 @@
+                               need_tailroom += cip->ic_miclen;
+       }
+-      if (skb_shared(skb)) {
+-              /* Take our own reference to the node in the clone */
+-              ieee80211_ref_node(SKB_NI(skb));
+-              /* Unshare the node, decrementing users in the old skb */
+-              skb = skb_unshare(skb, GFP_ATOMIC);
++      need_headroom -= skb_headroom(skb);
++      if (isff)
++              need_tailroom -= skb_tailroom(skb2);
++      else
++              need_tailroom -= skb_tailroom(skb);
++
++      if (need_headroom < 0)
++              need_headroom = 0;
++      if (need_tailroom < 0)
++              need_tailroom = 0;
++
++      if (skb_cloned(skb) || (need_headroom > 0) ||
++              (!isff && (need_tailroom > 0))) {
++
++              if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) {
++                      IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
++                              "%s: cannot expand storage (tail)\n", __func__);
++                      goto error;
++              }
+       }
+ #ifdef ATH_SUPERG_FF
+       if (isff) {
+-              if (skb == NULL) {
+-                      IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                              "%s: cannot unshare for encapsulation\n",
+-                              __func__);
+-                      vap->iv_stats.is_tx_nobuf++;
+-                      ieee80211_dev_kfree_skb(&skb2);
+-
+-                      return NULL;
+-              }
++              inter_headroom -= skb_headroom(skb2);
++              if (inter_headroom < 0)
++                      inter_headroom = 0;
++              if ((skb_cloned(skb2) ||
++                      (inter_headroom > 0) || (need_tailroom > 0))) {
+-              /* first skb header */
+-              if (skb_headroom(skb) < need_headroom) {
+-                      struct sk_buff *tmp = skb;
+-                      skb = skb_realloc_headroom(skb, need_headroom);
+-                      if (skb == NULL) {
++                      if (pskb_expand_head(skb2, inter_headroom,
++                              need_tailroom, GFP_ATOMIC)) {
+                               IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                                      "%s: cannot expand storage (head1)\n",
+-                                      __func__);
+-                              vap->iv_stats.is_tx_nobuf++;
+-                              ieee80211_dev_kfree_skb(&skb2);
+-                              return NULL;
+-                      } else
+-                              ieee80211_skb_copy_noderef(tmp, skb);
+-                      ieee80211_dev_kfree_skb(&tmp);
+-                      /* NB: cb[] area was copied, but not next ptr. must do that
+-                       *     prior to return on success. */
+-              }
+-
+-              /* second skb with header and tail adjustments possible */
+-              if (skb_tailroom(skb2) < need_tailroom) {
+-                      int n = 0;
+-                      if (inter_headroom > skb_headroom(skb2))
+-                              n = inter_headroom - skb_headroom(skb2);
+-                      if (pskb_expand_head(skb2, n,
+-                          need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) {
+-                              ieee80211_dev_kfree_skb(&skb2);
+-                              IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                                      "%s: cannot expand storage (tail2)\n",
+-                                      __func__);
+-                              vap->iv_stats.is_tx_nobuf++;
+-                              /* this shouldn't happen, but don't send first ff either */
+-                              ieee80211_dev_kfree_skb(&skb);
++                                      "%s: cannot expand storage (tail)\n", __func__);
++                              goto error;
+                       }
+-              } else if (skb_headroom(skb2) < inter_headroom) {
+-                      struct sk_buff *tmp = skb2;
+-
+-                      skb2 = skb_realloc_headroom(skb2, inter_headroom);
+-                      if (skb2 == NULL) {
+-                              IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                                      "%s: cannot expand storage (head2)\n",
+-                                      __func__);
+-                              vap->iv_stats.is_tx_nobuf++;
+-                              /* this shouldn't happen, but don't send first ff either */
+-                              ieee80211_dev_kfree_skb(&skb);
+-                              skb = NULL;
+-                      } else
+-                              ieee80211_skb_copy_noderef(tmp, skb);
+-                      ieee80211_dev_kfree_skb(&tmp);
+               }
+-              if (skb) {
+-                      skb->next = skb2;
+-              }
+-              return skb;
++              skb->next = skb2;
+       }
+ #endif /* ATH_SUPERG_FF */
+-      if (skb == NULL) {
+-              IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                      "%s: cannot unshare for encapsulation\n", __func__);
+-              vap->iv_stats.is_tx_nobuf++;
+-      } else if (skb_tailroom(skb) < need_tailroom) {
+-              int n = 0;
+-              if (need_headroom > skb_headroom(skb))
+-                      n = need_headroom - skb_headroom(skb);
+-              if (pskb_expand_head(skb, n, need_tailroom - 
+-                                      skb_tailroom(skb), GFP_ATOMIC)) {
+-                      IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                              "%s: cannot expand storage (tail)\n", __func__);
+-                      vap->iv_stats.is_tx_nobuf++;
+-                      ieee80211_dev_kfree_skb(&skb);
+-              }
+-      } else if (skb_headroom(skb) < need_headroom) {
+-              struct sk_buff *tmp = skb;
+-              skb = skb_realloc_headroom(skb, need_headroom);
+-              /* Increment reference count after copy */
+-              if (skb == NULL) {
+-                      IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                              "%s: cannot expand storage (head)\n", __func__);
+-                      vap->iv_stats.is_tx_nobuf++;
+-              } else
+-                      ieee80211_skb_copy_noderef(tmp, skb);
+-              ieee80211_dev_kfree_skb(&tmp);
+-      }
+       return skb;
++
++error:
++      vap->iv_stats.is_tx_nobuf++;
++      ieee80211_dev_kfree_skb(&skb);
++#ifdef ATH_SUPERG_FF
++      if (skb2)
++              ieee80211_dev_kfree_skb(&skb2);
++#endif
++      return NULL;
+ }
+ #define       KEY_UNDEFINED(k)        ((k).wk_cipher == &ieee80211_cipher_none)
+Index: madwifi-trunk-r3776/net80211/ieee80211_input.c
+===================================================================
+--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c        2008-07-17 02:20:52.000000000 +0200
++++ madwifi-trunk-r3776/net80211/ieee80211_input.c     2008-07-17 02:30:28.000000000 +0200
+@@ -713,7 +713,7 @@
+                       /* ether_type must be length as FF frames are always LLC/SNAP encap'd */ 
+                       frame_len = ntohs(eh_tmp->ether_type); 
+-                      skb1 = skb_copy(skb, GFP_ATOMIC);
++                      skb1 = skb_clone(skb, GFP_ATOMIC);
+                       if (skb1 == NULL)
+                               goto err;
+                       ieee80211_skb_copy_noderef(skb, skb1);
+@@ -1118,7 +1118,7 @@
+               if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
+                       /* Create a SKB for the BSS to send out. */
+-                      skb1 = skb_copy(skb, GFP_ATOMIC);
++                      skb1 = skb_clone(skb, GFP_ATOMIC);
+                       if (skb1)
+                               SKB_NI(skb1) = ieee80211_ref_node(vap->iv_bss); 
+               }
+@@ -2265,7 +2265,7 @@
+       if (filter_type && ((vap->app_filter & filter_type) == filter_type)) {
+               struct sk_buff *skb1;
+-              skb1 = skb_copy(skb, GFP_ATOMIC);
++              skb1 = skb_clone(skb, GFP_ATOMIC);
+               if (skb1 == NULL)
+                       return;
+               /* We duplicate the reference after skb_copy */
This page took 0.033078 seconds and 4 git commands to generate.