aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
authorNick Nunley <nicholasx.d.nunley@intel.com>2010-05-04 17:58:07 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-06 00:30:12 -0400
commit2873957df0ead5b53fa00fddfb52ca3df38af4a9 (patch)
tree3332fef2c0b6ac1877299ab171ce7a316a786301 /drivers/net/igb
parenta84afa40e07b6882ca46a7287d8ca4a8c5430f60 (diff)
igb: reduce cache misses on tx cleanup
This patch reduces the number of skb cache misses in the clean_tx_irq path, and results in an overall increase in tx packet throughput. Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb')
-rw-r--r--drivers/net/igb/igb.h4
-rw-r--r--drivers/net/igb/igb_main.c45
2 files changed, 22 insertions, 27 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 735ede9c7d75..6e63d9a7fc75 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -141,8 +141,10 @@ struct igb_buffer {
141 unsigned long time_stamp; 141 unsigned long time_stamp;
142 u16 length; 142 u16 length;
143 u16 next_to_watch; 143 u16 next_to_watch;
144 u16 mapped_as_page; 144 unsigned int bytecount;
145 u16 gso_segs; 145 u16 gso_segs;
146 union skb_shared_tx shtx;
147 u8 mapped_as_page;
146 }; 148 };
147 /* RX */ 149 /* RX */
148 struct { 150 struct {
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 438737d58688..589cf4a6427a 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3899,34 +3899,33 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
3899{ 3899{
3900 struct igb_buffer *buffer_info; 3900 struct igb_buffer *buffer_info;
3901 struct device *dev = tx_ring->dev; 3901 struct device *dev = tx_ring->dev;
3902 unsigned int len = skb_headlen(skb); 3902 unsigned int hlen = skb_headlen(skb);
3903 unsigned int count = 0, i; 3903 unsigned int count = 0, i;
3904 unsigned int f; 3904 unsigned int f;
3905 u16 gso_segs = skb_shinfo(skb)->gso_segs ?: 1;
3905 3906
3906 i = tx_ring->next_to_use; 3907 i = tx_ring->next_to_use;
3907 3908
3908 buffer_info = &tx_ring->buffer_info[i]; 3909 buffer_info = &tx_ring->buffer_info[i];
3909 BUG_ON(len >= IGB_MAX_DATA_PER_TXD); 3910 BUG_ON(hlen >= IGB_MAX_DATA_PER_TXD);
3910 buffer_info->length = len; 3911 buffer_info->length = hlen;
3911 /* set time_stamp *before* dma to help avoid a possible race */ 3912 /* set time_stamp *before* dma to help avoid a possible race */
3912 buffer_info->time_stamp = jiffies; 3913 buffer_info->time_stamp = jiffies;
3913 buffer_info->next_to_watch = i; 3914 buffer_info->next_to_watch = i;
3914 buffer_info->dma = dma_map_single(dev, skb->data, len, 3915 buffer_info->dma = dma_map_single(dev, skb->data, hlen,
3915 DMA_TO_DEVICE); 3916 DMA_TO_DEVICE);
3916 if (dma_mapping_error(dev, buffer_info->dma)) 3917 if (dma_mapping_error(dev, buffer_info->dma))
3917 goto dma_error; 3918 goto dma_error;
3918 3919
3919 for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { 3920 for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
3920 struct skb_frag_struct *frag; 3921 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[f];
3922 unsigned int len = frag->size;
3921 3923
3922 count++; 3924 count++;
3923 i++; 3925 i++;
3924 if (i == tx_ring->count) 3926 if (i == tx_ring->count)
3925 i = 0; 3927 i = 0;
3926 3928
3927 frag = &skb_shinfo(skb)->frags[f];
3928 len = frag->size;
3929
3930 buffer_info = &tx_ring->buffer_info[i]; 3929 buffer_info = &tx_ring->buffer_info[i];
3931 BUG_ON(len >= IGB_MAX_DATA_PER_TXD); 3930 BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
3932 buffer_info->length = len; 3931 buffer_info->length = len;
@@ -3944,7 +3943,10 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
3944 } 3943 }
3945 3944
3946 tx_ring->buffer_info[i].skb = skb; 3945 tx_ring->buffer_info[i].skb = skb;
3947 tx_ring->buffer_info[i].gso_segs = skb_shinfo(skb)->gso_segs ?: 1; 3946 tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
3947 /* multiply data chunks by size of headers */
3948 tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
3949 tx_ring->buffer_info[i].gso_segs = gso_segs;
3948 tx_ring->buffer_info[first].next_to_watch = i; 3950 tx_ring->buffer_info[first].next_to_watch = i;
3949 3951
3950 return ++count; 3952 return ++count;
@@ -5288,22 +5290,21 @@ static void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
5288/** 5290/**
5289 * igb_tx_hwtstamp - utility function which checks for TX time stamp 5291 * igb_tx_hwtstamp - utility function which checks for TX time stamp
5290 * @q_vector: pointer to q_vector containing needed info 5292 * @q_vector: pointer to q_vector containing needed info
5291 * @skb: packet that was just sent 5293 * @buffer: pointer to igb_buffer structure
5292 * 5294 *
5293 * If we were asked to do hardware stamping and such a time stamp is 5295 * If we were asked to do hardware stamping and such a time stamp is
5294 * available, then it must have been for this skb here because we only 5296 * available, then it must have been for this skb here because we only
5295 * allow only one such packet into the queue. 5297 * allow only one such packet into the queue.
5296 */ 5298 */
5297static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) 5299static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *buffer_info)
5298{ 5300{
5299 struct igb_adapter *adapter = q_vector->adapter; 5301 struct igb_adapter *adapter = q_vector->adapter;
5300 union skb_shared_tx *shtx = skb_tx(skb);
5301 struct e1000_hw *hw = &adapter->hw; 5302 struct e1000_hw *hw = &adapter->hw;
5302 struct skb_shared_hwtstamps shhwtstamps; 5303 struct skb_shared_hwtstamps shhwtstamps;
5303 u64 regval; 5304 u64 regval;
5304 5305
5305 /* if skb does not support hw timestamp or TX stamp not valid exit */ 5306 /* if skb does not support hw timestamp or TX stamp not valid exit */
5306 if (likely(!shtx->hardware) || 5307 if (likely(!buffer_info->shtx.hardware) ||
5307 !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) 5308 !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
5308 return; 5309 return;
5309 5310
@@ -5311,7 +5312,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
5311 regval |= (u64)rd32(E1000_TXSTMPH) << 32; 5312 regval |= (u64)rd32(E1000_TXSTMPH) << 32;
5312 5313
5313 igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval); 5314 igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
5314 skb_tstamp_tx(skb, &shhwtstamps); 5315 skb_tstamp_tx(buffer_info->skb, &shhwtstamps);
5315} 5316}
5316 5317
5317/** 5318/**
@@ -5326,7 +5327,6 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5326 struct net_device *netdev = tx_ring->netdev; 5327 struct net_device *netdev = tx_ring->netdev;
5327 struct e1000_hw *hw = &adapter->hw; 5328 struct e1000_hw *hw = &adapter->hw;
5328 struct igb_buffer *buffer_info; 5329 struct igb_buffer *buffer_info;
5329 struct sk_buff *skb;
5330 union e1000_adv_tx_desc *tx_desc, *eop_desc; 5330 union e1000_adv_tx_desc *tx_desc, *eop_desc;
5331 unsigned int total_bytes = 0, total_packets = 0; 5331 unsigned int total_bytes = 0, total_packets = 0;
5332 unsigned int i, eop, count = 0; 5332 unsigned int i, eop, count = 0;
@@ -5342,19 +5342,12 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5342 tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); 5342 tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
5343 buffer_info = &tx_ring->buffer_info[i]; 5343 buffer_info = &tx_ring->buffer_info[i];
5344 cleaned = (i == eop); 5344 cleaned = (i == eop);
5345 skb = buffer_info->skb;
5346 5345
5347 if (skb) { 5346 if (buffer_info->skb) {
5348 unsigned int segs, bytecount; 5347 total_bytes += buffer_info->bytecount;
5349 /* gso_segs is currently only valid for tcp */ 5348 /* gso_segs is currently only valid for tcp */
5350 segs = buffer_info->gso_segs; 5349 total_packets += buffer_info->gso_segs;
5351 /* multiply data chunks by size of headers */ 5350 igb_tx_hwtstamp(q_vector, buffer_info);
5352 bytecount = ((segs - 1) * skb_headlen(skb)) +
5353 skb->len;
5354 total_packets += segs;
5355 total_bytes += bytecount;
5356
5357 igb_tx_hwtstamp(q_vector, skb);
5358 } 5351 }
5359 5352
5360 igb_unmap_and_free_tx_resource(tx_ring, buffer_info); 5353 igb_unmap_and_free_tx_resource(tx_ring, buffer_info);