aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2008-07-08 18:52:43 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-07-11 01:20:30 -0400
commitfc2d14e36c69a8d44a2f5230835b54e95025363e (patch)
tree318fd217475088d2a14b669b3f5f142a82c98de0
parent8441dab26c0fb3d9c8cb8e9d2114a8f266a0b299 (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.c28
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
99static bool ixgb_clean_rx_irq(struct ixgb_adapter *); 99static bool ixgb_clean_rx_irq(struct ixgb_adapter *);
100#endif 100#endif
101static void ixgb_alloc_rx_buffers(struct ixgb_adapter *); 101static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);
102 102
103static void ixgb_tx_timeout(struct net_device *dev); 103static void ixgb_tx_timeout(struct net_device *dev);
104static void ixgb_tx_timeout_task(struct work_struct *work); 104static 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
2036static void 2046static void
2037ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) 2047ixgb_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) {