diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2008-07-08 18:52:43 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-11 01:20:30 -0400 |
commit | fc2d14e36c69a8d44a2f5230835b54e95025363e (patch) | |
tree | 318fd217475088d2a14b669b3f5f142a82c98de0 | |
parent | 8441dab26c0fb3d9c8cb8e9d2114a8f266a0b299 (diff) |
ixgb: rx cleanup performance improvements
rx cleanup should look more like our other drivers that have evolved
to nicer performance levels over time. Changes consist of refilling
tx buffers to hardware more often, some minor assignment cleanups.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r-- | drivers/net/ixgb/ixgb_main.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index c1dde795a837..365212b9e952 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -98,7 +98,7 @@ static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int); | |||
98 | #else | 98 | #else |
99 | static bool ixgb_clean_rx_irq(struct ixgb_adapter *); | 99 | static bool ixgb_clean_rx_irq(struct ixgb_adapter *); |
100 | #endif | 100 | #endif |
101 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *); | 101 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int); |
102 | 102 | ||
103 | static void ixgb_tx_timeout(struct net_device *dev); | 103 | static void ixgb_tx_timeout(struct net_device *dev); |
104 | static void ixgb_tx_timeout_task(struct work_struct *work); | 104 | static void ixgb_tx_timeout_task(struct work_struct *work); |
@@ -225,7 +225,7 @@ ixgb_up(struct ixgb_adapter *adapter) | |||
225 | ixgb_configure_tx(adapter); | 225 | ixgb_configure_tx(adapter); |
226 | ixgb_setup_rctl(adapter); | 226 | ixgb_setup_rctl(adapter); |
227 | ixgb_configure_rx(adapter); | 227 | ixgb_configure_rx(adapter); |
228 | ixgb_alloc_rx_buffers(adapter); | 228 | ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring)); |
229 | 229 | ||
230 | /* disable interrupts and get the hardware into a known state */ | 230 | /* disable interrupts and get the hardware into a known state */ |
231 | IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); | 231 | IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff); |
@@ -1906,6 +1906,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1906 | struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; | 1906 | struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; |
1907 | u32 length; | 1907 | u32 length; |
1908 | unsigned int i, j; | 1908 | unsigned int i, j; |
1909 | int cleaned_count = 0; | ||
1909 | bool cleaned = false; | 1910 | bool cleaned = false; |
1910 | 1911 | ||
1911 | i = rx_ring->next_to_clean; | 1912 | i = rx_ring->next_to_clean; |
@@ -1913,7 +1914,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1913 | buffer_info = &rx_ring->buffer_info[i]; | 1914 | buffer_info = &rx_ring->buffer_info[i]; |
1914 | 1915 | ||
1915 | while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) { | 1916 | while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) { |
1916 | struct sk_buff *skb, *next_skb; | 1917 | struct sk_buff *skb; |
1917 | u8 status; | 1918 | u8 status; |
1918 | 1919 | ||
1919 | #ifdef CONFIG_IXGB_NAPI | 1920 | #ifdef CONFIG_IXGB_NAPI |
@@ -1926,7 +1927,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1926 | skb = buffer_info->skb; | 1927 | skb = buffer_info->skb; |
1927 | buffer_info->skb = NULL; | 1928 | buffer_info->skb = NULL; |
1928 | 1929 | ||
1929 | prefetch(skb->data); | 1930 | prefetch(skb->data - NET_IP_ALIGN); |
1930 | 1931 | ||
1931 | if (++i == rx_ring->count) i = 0; | 1932 | if (++i == rx_ring->count) i = 0; |
1932 | next_rxd = IXGB_RX_DESC(*rx_ring, i); | 1933 | next_rxd = IXGB_RX_DESC(*rx_ring, i); |
@@ -1937,17 +1938,18 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) | |||
1937 | prefetch(next2_buffer); | 1938 | prefetch(next2_buffer); |
1938 | 1939 | ||
1939 | next_buffer = &rx_ring->buffer_info[i]; | 1940 | next_buffer = &rx_ring->buffer_info[i]; |
1940 | next_skb = next_buffer->skb; | ||
1941 | prefetch(next_skb); | ||
1942 | 1941 | ||
1943 | cleaned = true; | 1942 | cleaned = true; |
1943 | cleaned_count++; | ||
1944 | 1944 | ||
1945 | pci_unmap_single(pdev, | 1945 | pci_unmap_single(pdev, |
1946 | buffer_info->dma, | 1946 | buffer_info->dma, |
1947 | buffer_info->length, | 1947 | buffer_info->length, |
1948 | PCI_DMA_FROMDEVICE); | 1948 | PCI_DMA_FROMDEVICE); |
1949 | buffer_info->dma = 0; | ||
1949 | 1950 | ||
1950 | length = le16_to_cpu(rx_desc->length); | 1951 | length = le16_to_cpu(rx_desc->length); |
1952 | rx_desc->length = 0; | ||
1951 | 1953 | ||
1952 | if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { | 1954 | if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { |
1953 | 1955 | ||
@@ -2016,6 +2018,12 @@ rxdesc_done: | |||
2016 | /* clean up descriptor, might be written over by hw */ | 2018 | /* clean up descriptor, might be written over by hw */ |
2017 | rx_desc->status = 0; | 2019 | rx_desc->status = 0; |
2018 | 2020 | ||
2021 | /* return some buffers to hardware, one at a time is too slow */ | ||
2022 | if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) { | ||
2023 | ixgb_alloc_rx_buffers(adapter, cleaned_count); | ||
2024 | cleaned_count = 0; | ||
2025 | } | ||
2026 | |||
2019 | /* use prefetched values */ | 2027 | /* use prefetched values */ |
2020 | rx_desc = next_rxd; | 2028 | rx_desc = next_rxd; |
2021 | buffer_info = next_buffer; | 2029 | buffer_info = next_buffer; |
@@ -2023,7 +2031,9 @@ rxdesc_done: | |||
2023 | 2031 | ||
2024 | rx_ring->next_to_clean = i; | 2032 | rx_ring->next_to_clean = i; |
2025 | 2033 | ||
2026 | ixgb_alloc_rx_buffers(adapter); | 2034 | cleaned_count = IXGB_DESC_UNUSED(rx_ring); |
2035 | if (cleaned_count) | ||
2036 | ixgb_alloc_rx_buffers(adapter, cleaned_count); | ||
2027 | 2037 | ||
2028 | return cleaned; | 2038 | return cleaned; |
2029 | } | 2039 | } |
@@ -2034,7 +2044,7 @@ rxdesc_done: | |||
2034 | **/ | 2044 | **/ |
2035 | 2045 | ||
2036 | static void | 2046 | static void |
2037 | ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | 2047 | ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) |
2038 | { | 2048 | { |
2039 | struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; | 2049 | struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; |
2040 | struct net_device *netdev = adapter->netdev; | 2050 | struct net_device *netdev = adapter->netdev; |
@@ -2051,7 +2061,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | |||
2051 | 2061 | ||
2052 | 2062 | ||
2053 | /* leave three descriptors unused */ | 2063 | /* leave three descriptors unused */ |
2054 | while (--cleancount > 2) { | 2064 | while (--cleancount > 2 && cleaned_count--) { |
2055 | /* recycle! its good for you */ | 2065 | /* recycle! its good for you */ |
2056 | skb = buffer_info->skb; | 2066 | skb = buffer_info->skb; |
2057 | if (skb) { | 2067 | if (skb) { |