add performance improvement for madwifi on low-memory systems
authorFelix Fietkau <nbd@openwrt.org>
Thu, 17 Apr 2008 02:40:55 +0000 (02:40 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 17 Apr 2008 02:40:55 +0000 (02:40 +0000)
SVN-Revision: 10850

package/madwifi/patches/350-performance.patch [new file with mode: 0644]

diff --git a/package/madwifi/patches/350-performance.patch b/package/madwifi/patches/350-performance.patch
new file mode 100644 (file)
index 0000000..e88c084
--- /dev/null
@@ -0,0 +1,178 @@
+Index: madwifi-trunk-r3314/ath/if_ath.c
+===================================================================
+--- madwifi-trunk-r3314.orig/ath/if_ath.c      2008-04-17 02:56:31.000000000 +0200
++++ madwifi-trunk-r3314/ath/if_ath.c   2008-04-17 03:20:28.000000000 +0200
+@@ -3237,7 +3237,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, *tempbf;
+       struct sk_buff *tskb;
+@@ -3249,6 +3248,7 @@
+       */
+       int requeue = 0;
+ #ifdef ATH_SUPERG_FF
++      struct ether_header *eh;
+       unsigned int pktlen;
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct ath_node *an;
+@@ -3314,27 +3314,9 @@
+               requeue = 1;
+               goto hardstart_fail;
+       }
+-#endif
+-      /* If the skb data is shared, we will copy it so we can strip padding
+-       * without affecting any other bridge ports. */
+-      if (skb_cloned(skb)) {
+-              /* Remember the original SKB so we can free up our references */
+-              struct sk_buff *skb_new;
+-              skb_new = skb_copy(skb, GFP_ATOMIC);
+-              if (skb_new == NULL) {
+-                      DPRINTF(sc, ATH_DEBUG_XMIT,
+-                              "Dropping; skb_copy failure.\n");
+-                      /* No free RAM, do not requeue! */
+-                      goto hardstart_fail;
+-              }
+-              ieee80211_skb_copy_noderef(skb, skb_new);
+-              ieee80211_dev_kfree_skb(&skb);
+-              skb = skb_new;
+-      }
+       eh = (struct ether_header *)skb->data;
+-#ifdef ATH_SUPERG_FF
+       /* NB: use this lock to protect an->an_tx_ffbuf (and txq->axq_stageq)
+        *     in athff_can_aggregate() call too. */
+       ATH_TXQ_LOCK_IRQ(txq);
+Index: madwifi-trunk-r3314/net80211/ieee80211_output.c
+===================================================================
+--- madwifi-trunk-r3314.orig/net80211/ieee80211_output.c       2008-04-17 02:56:30.000000000 +0200
++++ madwifi-trunk-r3314/net80211/ieee80211_output.c    2008-04-17 04:29:06.000000000 +0200
+@@ -615,100 +615,45 @@
+               skb = skb_unshare(skb, GFP_ATOMIC);
+       }
+-#ifdef ATH_SUPERG_FF
+-      if (isff) {
+-              if (skb == NULL) {
++      if (skb_cloned(skb) ||
++              (need_headroom > skb_headroom(skb)) ||
++              (!isff && (need_tailroom > skb_tailroom(skb)))) {
++
++              if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) {
+                       IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                              "%s: cannot unshare for encapsulation\n",
+-                              __func__);
++                              "%s: cannot expand storage (tail)\n", __func__);
+                       vap->iv_stats.is_tx_nobuf++;
+-                      ieee80211_dev_kfree_skb(&skb2);
+-
++                      ieee80211_dev_kfree_skb(&skb);
+                       return NULL;
+               }
++      }
+-              /* first skb header */
+-              if (skb_headroom(skb) < need_headroom) {
+-                      struct sk_buff *tmp = skb;
+-                      skb = skb_realloc_headroom(skb, need_headroom);
+-                      if (skb == NULL) {
+-                              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. */
++#ifdef ATH_SUPERG_FF
++      if (isff) {
++              if (skb_shared(skb2)) {
++                      /* Take our own reference to the node in the clone */
++                      ieee80211_ref_node(SKB_CB(skb2)->ni);
++                      /* Unshare the node, decrementing users in the old skb */
++                      skb2 = skb_unshare(skb2, GFP_ATOMIC);
+               }
+-              /* 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);
+-                      }
+-              } else if (skb_headroom(skb2) < inter_headroom) {
+-                      struct sk_buff *tmp = skb2;
++              if ((skb_cloned(skb2) ||
++                      (inter_headroom > skb_headroom(skb2)) ||
++                      (need_tailroom > skb_tailroom(skb2)))) {
+-                      skb2 = skb_realloc_headroom(skb2, inter_headroom);
+-                      if (skb2 == NULL) {
++                      if (pskb_expand_head(skb2, inter_headroom,
++                              need_tailroom, GFP_ATOMIC)) {
+                               IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+-                                      "%s: cannot expand storage (head2)\n",
+-                                      __func__);
++                                      "%s: cannot expand storage (tail)\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;
++                              ieee80211_dev_kfree_skb(&skb2);
++                              return NULL;
++                      }
+               }
+-              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;
+ }