aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/igb_main.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-02-06 18:15:04 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-07 05:43:01 -0500
commit69d3ca5357bb93bb3a139c5d90077407f8828bd1 (patch)
tree462944f1fc5fab09b8fa2c3d632e3c875aeeba31 /drivers/net/igb/igb_main.c
parent3e450669cc7060d56d886f53e31182f5fef103c7 (diff)
igb: optimize/refactor receive path
While cleaning up the skb_over panic with small frames I found there was room for improvement in the ordering of operations within the rx receive flow. These changes will place the prefetch for the next descriptor to a point earlier in the rx path. 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/net/igb/igb_main.c')
-rw-r--r--drivers/net/igb/igb_main.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 8b80fe343435..21f0c229b64e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3803,6 +3803,7 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
3803 unsigned int total_bytes = 0, total_packets = 0; 3803 unsigned int total_bytes = 0, total_packets = 0;
3804 3804
3805 i = rx_ring->next_to_clean; 3805 i = rx_ring->next_to_clean;
3806 buffer_info = &rx_ring->buffer_info[i];
3806 rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); 3807 rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
3807 staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 3808 staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
3808 3809
@@ -3810,25 +3811,22 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
3810 if (*work_done >= budget) 3811 if (*work_done >= budget)
3811 break; 3812 break;
3812 (*work_done)++; 3813 (*work_done)++;
3813 buffer_info = &rx_ring->buffer_info[i];
3814 3814
3815 /* HW will not DMA in data larger than the given buffer, even 3815 skb = buffer_info->skb;
3816 * if it parses the (NFS, of course) header to be larger. In 3816 prefetch(skb->data - NET_IP_ALIGN);
3817 * that case, it fills the header buffer and spills the rest 3817 buffer_info->skb = NULL;
3818 * into the page. 3818
3819 */ 3819 i++;
3820 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & 3820 if (i == rx_ring->count)
3821 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; 3821 i = 0;
3822 if (hlen > adapter->rx_ps_hdr_size) 3822 next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
3823 hlen = adapter->rx_ps_hdr_size; 3823 prefetch(next_rxd);
3824 next_buffer = &rx_ring->buffer_info[i];
3824 3825
3825 length = le16_to_cpu(rx_desc->wb.upper.length); 3826 length = le16_to_cpu(rx_desc->wb.upper.length);
3826 cleaned = true; 3827 cleaned = true;
3827 cleaned_count++; 3828 cleaned_count++;
3828 3829
3829 skb = buffer_info->skb;
3830 prefetch(skb->data - NET_IP_ALIGN);
3831 buffer_info->skb = NULL;
3832 if (!adapter->rx_ps_hdr_size) { 3830 if (!adapter->rx_ps_hdr_size) {
3833 pci_unmap_single(pdev, buffer_info->dma, 3831 pci_unmap_single(pdev, buffer_info->dma,
3834 adapter->rx_buffer_len + 3832 adapter->rx_buffer_len +
@@ -3838,6 +3836,16 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
3838 goto send_up; 3836 goto send_up;
3839 } 3837 }
3840 3838
3839 /* HW will not DMA in data larger than the given buffer, even
3840 * if it parses the (NFS, of course) header to be larger. In
3841 * that case, it fills the header buffer and spills the rest
3842 * into the page.
3843 */
3844 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
3845 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
3846 if (hlen > adapter->rx_ps_hdr_size)
3847 hlen = adapter->rx_ps_hdr_size;
3848
3841 if (!skb_shinfo(skb)->nr_frags) { 3849 if (!skb_shinfo(skb)->nr_frags) {
3842 pci_unmap_single(pdev, buffer_info->dma, 3850 pci_unmap_single(pdev, buffer_info->dma,
3843 adapter->rx_ps_hdr_size + 3851 adapter->rx_ps_hdr_size +
@@ -3867,13 +3875,6 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
3867 3875
3868 skb->truesize += length; 3876 skb->truesize += length;
3869 } 3877 }
3870send_up:
3871 i++;
3872 if (i == rx_ring->count)
3873 i = 0;
3874 next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
3875 prefetch(next_rxd);
3876 next_buffer = &rx_ring->buffer_info[i];
3877 3878
3878 if (!(staterr & E1000_RXD_STAT_EOP)) { 3879 if (!(staterr & E1000_RXD_STAT_EOP)) {
3879 buffer_info->skb = next_buffer->skb; 3880 buffer_info->skb = next_buffer->skb;
@@ -3882,7 +3883,7 @@ send_up:
3882 next_buffer->dma = 0; 3883 next_buffer->dma = 0;
3883 goto next_desc; 3884 goto next_desc;
3884 } 3885 }
3885 3886send_up:
3886 if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { 3887 if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
3887 dev_kfree_skb_irq(skb); 3888 dev_kfree_skb_irq(skb);
3888 goto next_desc; 3889 goto next_desc;
@@ -3909,7 +3910,6 @@ next_desc:
3909 /* use prefetched values */ 3910 /* use prefetched values */
3910 rx_desc = next_rxd; 3911 rx_desc = next_rxd;
3911 buffer_info = next_buffer; 3912 buffer_info = next_buffer;
3912
3913 staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 3913 staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
3914 } 3914 }
3915 3915