|
@@ -1154,7 +1154,7 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
|
|
|
PAGE_SIZE,
|
|
|
DMA_FROM_DEVICE,
|
|
|
I40E_RX_DMA_ATTR);
|
|
|
- __free_pages(rx_bi->page, 0);
|
|
|
+ __page_frag_cache_drain(rx_bi->page, rx_bi->pagecnt_bias);
|
|
|
|
|
|
rx_bi->page = NULL;
|
|
|
rx_bi->page_offset = 0;
|
|
@@ -1299,6 +1299,7 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring,
|
|
|
bi->dma = dma;
|
|
|
bi->page = page;
|
|
|
bi->page_offset = 0;
|
|
|
+ bi->pagecnt_bias = 1;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -1604,7 +1605,10 @@ static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
|
|
|
rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
|
|
|
|
|
|
/* transfer page from old buffer to new buffer */
|
|
|
- *new_buff = *old_buff;
|
|
|
+ new_buff->dma = old_buff->dma;
|
|
|
+ new_buff->page = old_buff->page;
|
|
|
+ new_buff->page_offset = old_buff->page_offset;
|
|
|
+ new_buff->pagecnt_bias = old_buff->pagecnt_bias;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1656,6 +1660,7 @@ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer,
|
|
|
#if (PAGE_SIZE >= 8192)
|
|
|
unsigned int last_offset = PAGE_SIZE - I40E_RXBUFFER_2048;
|
|
|
#endif
|
|
|
+ unsigned int pagecnt_bias = rx_buffer->pagecnt_bias--;
|
|
|
|
|
|
/* Is any reuse possible? */
|
|
|
if (unlikely(!i40e_page_is_reusable(page)))
|
|
@@ -1663,7 +1668,7 @@ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer,
|
|
|
|
|
|
#if (PAGE_SIZE < 8192)
|
|
|
/* if we are only owner of page we can reuse it */
|
|
|
- if (unlikely(page_count(page) != 1))
|
|
|
+ if (unlikely(page_count(page) != pagecnt_bias))
|
|
|
return false;
|
|
|
|
|
|
/* flip page offset to other buffer */
|
|
@@ -1676,9 +1681,14 @@ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer,
|
|
|
return false;
|
|
|
#endif
|
|
|
|
|
|
- /* Inc ref count on page before passing it up to the stack */
|
|
|
- get_page(page);
|
|
|
-
|
|
|
+ /* If we have drained the page fragment pool we need to update
|
|
|
+ * the pagecnt_bias and page count so that we fully restock the
|
|
|
+ * number of references the driver holds.
|
|
|
+ */
|
|
|
+ if (unlikely(pagecnt_bias == 1)) {
|
|
|
+ page_ref_add(page, USHRT_MAX);
|
|
|
+ rx_buffer->pagecnt_bias = USHRT_MAX;
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1725,7 +1735,6 @@ static bool i40e_add_rx_frag(struct i40e_ring *rx_ring,
|
|
|
return true;
|
|
|
|
|
|
/* this page cannot be reused so discard it */
|
|
|
- __free_pages(page, 0);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1819,6 +1828,8 @@ struct sk_buff *i40e_fetch_rx_buffer(struct i40e_ring *rx_ring,
|
|
|
/* we are not reusing the buffer so unmap it */
|
|
|
dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma, PAGE_SIZE,
|
|
|
DMA_FROM_DEVICE, I40E_RX_DMA_ATTR);
|
|
|
+ __page_frag_cache_drain(rx_buffer->page,
|
|
|
+ rx_buffer->pagecnt_bias);
|
|
|
}
|
|
|
|
|
|
/* clear contents of buffer_info */
|