diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-07-23 14:10:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-26 12:47:01 -0400 |
commit | 2d94d8ab76ea6c858c6e2eb0ab0403b00b031039 (patch) | |
tree | db8f6f4b56dfd3261ea6ce018ba6f571f1c3ccbb /drivers | |
parent | 4703bf73bd5b0d43c3eb5b547398d4f62dc5d4e1 (diff) |
igb: use buffer_info->dma instead of shinfo->nr_frags to determine unmap
This change makes it so that we use buffer_info->dma instead of
shinfo->nr_frags to determine if we need to unmap a received skb. By doing
this we can avoid a cache miss on small packets since the buffer_info
structure should already be prefetched.
Signed-off-by: Alexander Duyck <alexander.h.duyck@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')
-rw-r--r-- | drivers/net/igb/igb_main.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 2ffb51d6c959..12d8683c231e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -4538,6 +4538,20 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter, | |||
4538 | adapter->hw_csum_good++; | 4538 | adapter->hw_csum_good++; |
4539 | } | 4539 | } |
4540 | 4540 | ||
4541 | static inline u16 igb_get_hlen(struct igb_adapter *adapter, | ||
4542 | union e1000_adv_rx_desc *rx_desc) | ||
4543 | { | ||
4544 | /* HW will not DMA in data larger than the given buffer, even if it | ||
4545 | * parses the (NFS, of course) header to be larger. In that case, it | ||
4546 | * fills the header buffer and spills the rest into the page. | ||
4547 | */ | ||
4548 | u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & | ||
4549 | E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; | ||
4550 | if (hlen > adapter->rx_ps_hdr_size) | ||
4551 | hlen = adapter->rx_ps_hdr_size; | ||
4552 | return hlen; | ||
4553 | } | ||
4554 | |||
4541 | static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, | 4555 | static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, |
4542 | int *work_done, int budget) | 4556 | int *work_done, int budget) |
4543 | { | 4557 | { |
@@ -4552,7 +4566,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, | |||
4552 | int cleaned_count = 0; | 4566 | int cleaned_count = 0; |
4553 | unsigned int total_bytes = 0, total_packets = 0; | 4567 | unsigned int total_bytes = 0, total_packets = 0; |
4554 | unsigned int i; | 4568 | unsigned int i; |
4555 | u32 length, hlen, staterr; | 4569 | u32 staterr; |
4570 | u16 length; | ||
4556 | 4571 | ||
4557 | i = rx_ring->next_to_clean; | 4572 | i = rx_ring->next_to_clean; |
4558 | buffer_info = &rx_ring->buffer_info[i]; | 4573 | buffer_info = &rx_ring->buffer_info[i]; |
@@ -4589,17 +4604,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, | |||
4589 | goto send_up; | 4604 | goto send_up; |
4590 | } | 4605 | } |
4591 | 4606 | ||
4592 | /* HW will not DMA in data larger than the given buffer, even | 4607 | if (buffer_info->dma) { |
4593 | * if it parses the (NFS, of course) header to be larger. In | 4608 | u16 hlen = igb_get_hlen(adapter, rx_desc); |
4594 | * that case, it fills the header buffer and spills the rest | ||
4595 | * into the page. | ||
4596 | */ | ||
4597 | hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & | ||
4598 | E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; | ||
4599 | if (hlen > adapter->rx_ps_hdr_size) | ||
4600 | hlen = adapter->rx_ps_hdr_size; | ||
4601 | |||
4602 | if (!skb_shinfo(skb)->nr_frags) { | ||
4603 | pci_unmap_single(pdev, buffer_info->dma, | 4609 | pci_unmap_single(pdev, buffer_info->dma, |
4604 | adapter->rx_ps_hdr_size, | 4610 | adapter->rx_ps_hdr_size, |
4605 | PCI_DMA_FROMDEVICE); | 4611 | PCI_DMA_FROMDEVICE); |