igb: use buffer_info->dma instead of shinfo->nr_frags to determine unmap
authorAlexander Duyck <alexander.h.duyck@intel.com>
Thu, 23 Jul 2009 18:10:06 +0000 (18:10 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 26 Jul 2009 16:47:01 +0000 (09:47 -0700)
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>
drivers/net/igb/igb_main.c

index 2ffb51d6c9591a720ad49c2b507c7ca19cf60afe..12d8683c231e192af01205743f472463994c33a4 100644 (file)
@@ -4538,6 +4538,20 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
        adapter->hw_csum_good++;
 }
 
+static inline u16 igb_get_hlen(struct igb_adapter *adapter,
+                               union e1000_adv_rx_desc *rx_desc)
+{
+       /* HW will not DMA in data larger than the given buffer, even if it
+        * parses the (NFS, of course) header to be larger.  In that case, it
+        * fills the header buffer and spills the rest into the page.
+        */
+       u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+                  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+       if (hlen > adapter->rx_ps_hdr_size)
+               hlen = adapter->rx_ps_hdr_size;
+       return hlen;
+}
+
 static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
                                 int *work_done, int budget)
 {
@@ -4552,7 +4566,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
        int cleaned_count = 0;
        unsigned int total_bytes = 0, total_packets = 0;
        unsigned int i;
-       u32 length, hlen, staterr;
+       u32 staterr;
+       u16 length;
 
        i = rx_ring->next_to_clean;
        buffer_info = &rx_ring->buffer_info[i];
@@ -4589,17 +4604,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
                        goto send_up;
                }
 
-               /* HW will not DMA in data larger than the given buffer, even
-                * if it parses the (NFS, of course) header to be larger.  In
-                * that case, it fills the header buffer and spills the rest
-                * into the page.
-                */
-               hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
-                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
-               if (hlen > adapter->rx_ps_hdr_size)
-                       hlen = adapter->rx_ps_hdr_size;
-
-               if (!skb_shinfo(skb)->nr_frags) {
+               if (buffer_info->dma) {
+                       u16 hlen = igb_get_hlen(adapter, rx_desc);
                        pci_unmap_single(pdev, buffer_info->dma,
                                         adapter->rx_ps_hdr_size,
                                         PCI_DMA_FROMDEVICE);