Skip to content

Commit

Permalink
igb: update driver to make use of DMA_ATTR_SKIP_CPU_SYNC
Browse files Browse the repository at this point in the history
The ARM architecture provides a mechanism for deferring cache line
invalidation in the case of map/unmap.  This patch makes use of this
mechanism to avoid unnecessary synchronization.

A secondary effect of this change is that the portion of the page that
has been synchronized for use by the CPU should be writable and could be
passed up the stack (at least on ARM).

The last bit that occurred to me is that on architectures where the
sync_for_cpu call invalidates cache lines we were prefetching and then
invalidating the first 128 bytes of the packet.  To avoid that I have
moved the sync up to before we perform the prefetch and allocate the
skbuff so that we can actually make use of it.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Alexander Duyck <[email protected]>
Acked-by: Jeff Kirsher <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: "James E.J. Bottomley" <[email protected]>
Cc: Chris Metcalf <[email protected]>
Cc: David Howells <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Hans-Christian Noren Egtvedt <[email protected]>
Cc: Helge Deller <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Jonas Bonn <[email protected]>
Cc: Keguang Zhang <[email protected]>
Cc: Ley Foon Tan <[email protected]>
Cc: Mark Salter <[email protected]>
Cc: Max Filippov <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Rich Felker <[email protected]>
Cc: Richard Kuo <[email protected]>
Cc: Russell King <[email protected]>
Cc: Steven Miao <[email protected]>
Cc: Tobias Klauser <[email protected]>
Cc: Vineet Gupta <[email protected]>
Cc: Yoshinori Sato <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Alexander Duyck authored and torvalds committed Dec 15, 2016
1 parent 44fdffd commit 5be5955
Showing 1 changed file with 33 additions and 20 deletions.
53 changes: 33 additions & 20 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3947,10 +3947,21 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring)
if (!buffer_info->page)
continue;

dma_unmap_page(rx_ring->dev,
buffer_info->dma,
PAGE_SIZE,
DMA_FROM_DEVICE);
/* Invalidate cache lines that may have been written to by
* device so that we avoid corrupting memory.
*/
dma_sync_single_range_for_cpu(rx_ring->dev,
buffer_info->dma,
buffer_info->page_offset,
IGB_RX_BUFSZ,
DMA_FROM_DEVICE);

/* free resources associated with mapping */
dma_unmap_page_attrs(rx_ring->dev,
buffer_info->dma,
PAGE_SIZE,
DMA_FROM_DEVICE,
DMA_ATTR_SKIP_CPU_SYNC);
__free_page(buffer_info->page);

buffer_info->page = NULL;
Expand Down Expand Up @@ -6812,12 +6823,6 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring,

/* transfer page from old buffer to new buffer */
*new_buff = *old_buff;

/* sync the buffer for use by the device */
dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma,
old_buff->page_offset,
IGB_RX_BUFSZ,
DMA_FROM_DEVICE);
}

static inline bool igb_page_is_reserved(struct page *page)
Expand Down Expand Up @@ -6938,6 +6943,13 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
page = rx_buffer->page;
prefetchw(page);

/* we are reusing so sync this buffer for CPU use */
dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma,
rx_buffer->page_offset,
size,
DMA_FROM_DEVICE);

if (likely(!skb)) {
void *page_addr = page_address(page) +
rx_buffer->page_offset;
Expand All @@ -6962,21 +6974,15 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
prefetchw(skb->data);
}

/* we are reusing so sync this buffer for CPU use */
dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma,
rx_buffer->page_offset,
size,
DMA_FROM_DEVICE);

/* pull page into skb */
if (igb_add_rx_frag(rx_ring, rx_buffer, size, rx_desc, skb)) {
/* hand second half of page back to the ring */
igb_reuse_rx_page(rx_ring, rx_buffer);
} else {
/* we are not reusing the buffer so unmap it */
dma_unmap_page(rx_ring->dev, rx_buffer->dma,
PAGE_SIZE, DMA_FROM_DEVICE);
dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
PAGE_SIZE, DMA_FROM_DEVICE,
DMA_ATTR_SKIP_CPU_SYNC);
}

/* clear contents of rx_buffer */
Expand Down Expand Up @@ -7234,7 +7240,8 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
}

/* map page for use */
dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
dma = dma_map_page_attrs(rx_ring->dev, page, 0, PAGE_SIZE,
DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);

/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
Expand Down Expand Up @@ -7275,6 +7282,12 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
if (!igb_alloc_mapped_page(rx_ring, bi))
break;

/* sync the buffer for use by the device */
dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
bi->page_offset,
IGB_RX_BUFSZ,
DMA_FROM_DEVICE);

/* Refresh the desc even if buffer_addrs didn't change
* because each write-back erases this info.
*/
Expand Down

0 comments on commit 5be5955

Please sign in to comment.