Skip to content

Commit

Permalink
ixgb: rx cleanup performance improvements
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jesse Brandeburg authored and Jeff Garzik committed Jul 11, 2008
1 parent 8441dab commit fc2d14e
Showing 1 changed file with 19 additions and 9 deletions.
28 changes: 19 additions & 9 deletions drivers/net/ixgb/ixgb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int);
#else
static bool ixgb_clean_rx_irq(struct ixgb_adapter *);
#endif
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *);
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);

static void ixgb_tx_timeout(struct net_device *dev);
static void ixgb_tx_timeout_task(struct work_struct *work);
Expand Down Expand Up @@ -225,7 +225,7 @@ ixgb_up(struct ixgb_adapter *adapter)
ixgb_configure_tx(adapter);
ixgb_setup_rctl(adapter);
ixgb_configure_rx(adapter);
ixgb_alloc_rx_buffers(adapter);
ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring));

/* disable interrupts and get the hardware into a known state */
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
Expand Down Expand Up @@ -1906,14 +1906,15 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
u32 length;
unsigned int i, j;
int cleaned_count = 0;
bool cleaned = false;

i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];

while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
struct sk_buff *skb, *next_skb;
struct sk_buff *skb;
u8 status;

#ifdef CONFIG_IXGB_NAPI
Expand All @@ -1926,7 +1927,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
skb = buffer_info->skb;
buffer_info->skb = NULL;

prefetch(skb->data);
prefetch(skb->data - NET_IP_ALIGN);

if (++i == rx_ring->count) i = 0;
next_rxd = IXGB_RX_DESC(*rx_ring, i);
Expand All @@ -1937,17 +1938,18 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
prefetch(next2_buffer);

next_buffer = &rx_ring->buffer_info[i];
next_skb = next_buffer->skb;
prefetch(next_skb);

cleaned = true;
cleaned_count++;

pci_unmap_single(pdev,
buffer_info->dma,
buffer_info->length,
PCI_DMA_FROMDEVICE);
buffer_info->dma = 0;

length = le16_to_cpu(rx_desc->length);
rx_desc->length = 0;

if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {

Expand Down Expand Up @@ -2016,14 +2018,22 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
/* clean up descriptor, might be written over by hw */
rx_desc->status = 0;

/* return some buffers to hardware, one at a time is too slow */
if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) {
ixgb_alloc_rx_buffers(adapter, cleaned_count);
cleaned_count = 0;
}

/* use prefetched values */
rx_desc = next_rxd;
buffer_info = next_buffer;
}

rx_ring->next_to_clean = i;

ixgb_alloc_rx_buffers(adapter);
cleaned_count = IXGB_DESC_UNUSED(rx_ring);
if (cleaned_count)
ixgb_alloc_rx_buffers(adapter, cleaned_count);

return cleaned;
}
Expand All @@ -2034,7 +2044,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
**/

static void
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count)
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
Expand All @@ -2051,7 +2061,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)


/* leave three descriptors unused */
while (--cleancount > 2) {
while (--cleancount > 2 && cleaned_count--) {
/* recycle! its good for you */
skb = buffer_info->skb;
if (skb) {
Expand Down

0 comments on commit fc2d14e

Please sign in to comment.