diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-04-17 02:40:55 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-04-17 02:40:55 +0000 | 
| commit | d3f4ff8b1474ba31c36d10cdefcf4dfd2abdbf41 (patch) | |
| tree | 6e0922c92a7837045cae055ad74a3a304aced526 | |
| parent | 7c8a43078f5761aaa260414fc17b65cb64e1904a (diff) | |
add performance improvement for madwifi on low-memory systems
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10850 3c298f89-4303-0410-b956-a3cf2f4a3e73
| -rw-r--r-- | package/madwifi/patches/350-performance.patch | 178 | 
1 files changed, 178 insertions, 0 deletions
| diff --git a/package/madwifi/patches/350-performance.patch b/package/madwifi/patches/350-performance.patch new file mode 100644 index 000000000..e88c084db --- /dev/null +++ b/package/madwifi/patches/350-performance.patch @@ -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; + } | 
