#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);
        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);
        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;
        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
                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);
                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))) {
 
                /* 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;
 }
  **/
 
 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;
 
 
        /* leave three descriptors unused */
-       while (--cleancount > 2) {
+       while (--cleancount > 2 && cleaned_count--) {
                /* recycle! its good for you */
                skb = buffer_info->skb;
                if (skb) {