aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2009-10-09 05:19:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:06 -0400
commit2f301227a1ede57504694e1f64839839f5737cac (patch)
treec148ca6c3409f5f8fed4455fba3a78fe31469135 /drivers/net/wireless/iwlwifi/iwl-tx.c
parentae751bab9f55c3152ebf713c89a4fb6f439c2575 (diff)
iwlwifi: use paged Rx
This switches the iwlwifi driver to use paged skb from linear skb for Rx buffer. So that it relieves some Rx buffer allocation pressure for the memory subsystem. Currently iwlwifi (4K for 3945) requests 8K bytes for Rx buffer. Due to the trailing skb_shared_info in the skb->data, alloc_skb() will do the next order allocation, which is 16K bytes. This is suboptimal and more likely to fail when the system is under memory usage pressure. Switching to paged Rx skb lets us allocate the RXB directly by alloc_pages(), so that only order 1 allocation is required. It also adjusts the area spin_lock (with IRQ disabled) protected in the tasklet because tasklet guarentees to run only on one CPU and the new unprotected code can be preempted by the IRQ handler. This saves us from spawning another workqueue to make skb_linearize/__pskb_pull_tail happy (which cannot be called in hard irq context). Finally, mac80211 doesn't support paged Rx yet. So we linearize the skb for all the management frames and software decryption or defragmentation required data frames before handed to mac80211. For all the other frames, we __pskb_pull_tail 64 bytes in the linear area of the skb for mac80211 to handle them properly. Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index d0bd7cd024ad..5c43d7c43b30 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1153,7 +1153,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
1153 */ 1153 */
1154void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1154void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1155{ 1155{
1156 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 1156 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1157 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 1157 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1158 int txq_id = SEQ_TO_QUEUE(sequence); 1158 int txq_id = SEQ_TO_QUEUE(sequence);
1159 int index = SEQ_TO_INDEX(sequence); 1159 int index = SEQ_TO_INDEX(sequence);
@@ -1180,10 +1180,10 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1180 1180
1181 /* Input error checking is done when commands are added to queue. */ 1181 /* Input error checking is done when commands are added to queue. */
1182 if (meta->flags & CMD_WANT_SKB) { 1182 if (meta->flags & CMD_WANT_SKB) {
1183 meta->source->reply_skb = rxb->skb; 1183 meta->source->reply_page = (unsigned long)rxb_addr(rxb);
1184 rxb->skb = NULL; 1184 rxb->page = NULL;
1185 } else if (meta->callback) 1185 } else if (meta->callback)
1186 meta->callback(priv, cmd, rxb->skb); 1186 meta->callback(priv, cmd, pkt);
1187 1187
1188 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); 1188 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
1189 1189
@@ -1442,7 +1442,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1442void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, 1442void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1443 struct iwl_rx_mem_buffer *rxb) 1443 struct iwl_rx_mem_buffer *rxb)
1444{ 1444{
1445 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 1445 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1446 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; 1446 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1447 struct iwl_tx_queue *txq = NULL; 1447 struct iwl_tx_queue *txq = NULL;
1448 struct iwl_ht_agg *agg; 1448 struct iwl_ht_agg *agg;