This is a note to let you know that I've just added the patch titled sfc: Properly sync RX DMA buffer when it is not the last in the page to the 3.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch and it can be found in the queue-3.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 5c642c59d8774dc6d965917ec672d96f82dbfc59 Mon Sep 17 00:00:00 2001 From: Ben Hutchings <bhutchings@xxxxxxxxxxxxxx> Date: Thu, 20 Dec 2012 18:48:20 +0000 Subject: sfc: Properly sync RX DMA buffer when it is not the last in the page From: Ben Hutchings <bhutchings@xxxxxxxxxxxxxx> [ Upstream commit 3a68f19d7afb80f548d016effbc6ed52643a8085 ] We may currently allocate two RX DMA buffers to a page, and only unmap the page when the second is completed. We do not sync the first RX buffer to be completed; this can result in packet loss or corruption if the last RX buffer completed in a NAPI poll is the first in a page and is not DMA-coherent. (In the middle of a NAPI poll, we will handle the following RX completion and unmap the page *before* looking at the content of the first buffer.) Signed-off-by: Ben Hutchings <bhutchings@xxxxxxxxxxxxxx> [bwh: Backported to 3.4: adjust context] Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/net/ethernet/sfc/rx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -245,7 +245,8 @@ static int efx_init_rx_buffers_page(stru } static void efx_unmap_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf) + struct efx_rx_buffer *rx_buf, + unsigned int used_len) { if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { struct efx_rx_page_state *state; @@ -256,6 +257,10 @@ static void efx_unmap_rx_buffer(struct e state->dma_addr, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); + } else if (used_len) { + dma_sync_single_for_cpu(&efx->pci_dev->dev, + rx_buf->dma_addr, used_len, + DMA_FROM_DEVICE); } } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { pci_unmap_single(efx->pci_dev, rx_buf->dma_addr, @@ -278,7 +283,7 @@ static void efx_free_rx_buffer(struct ef static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - efx_unmap_rx_buffer(rx_queue->efx, rx_buf); + efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0); efx_free_rx_buffer(rx_queue->efx, rx_buf); } @@ -544,10 +549,10 @@ void efx_rx_packet(struct efx_rx_queue * goto out; } - /* Release card resources - assumes all RX buffers consumed in-order - * per RX queue + /* Release and/or sync DMA mapping - assumes all RX buffers + * consumed in-order per RX queue */ - efx_unmap_rx_buffer(efx, rx_buf); + efx_unmap_rx_buffer(efx, rx_buf, len); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. Patches currently in stable-queue which might be from bhutchings@xxxxxxxxxxxxxx are queue-3.4/sfc-really-disable-flow-control-while-flushing.patch queue-3.4/sfc-disable-vf-queues-during-register-self-test.patch queue-3.4/sfc-correctly-initialise-reset_method-in-siena_test_chip.patch queue-3.4/sfc-do-not-attempt-to-flush-queues-if-dma-is-disabled.patch queue-3.4/sfc-avoid-generating-over-length-mc_cmd_flush_rx_queues-request.patch queue-3.4/sfc-work-around-flush-timeout-when-flushes-have-completed.patch queue-3.4/sfc-add-parentheses-around-use-of-bitfield-macro-arguments.patch queue-3.4/sfc-fix-mcdi-structure-field-lookup.patch queue-3.4/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch queue-3.4/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch queue-3.4/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch queue-3.4/sfc-lock-tx-queues-when-calling-netif_device_detach.patch queue-3.4/sfc-convert-firmware-subtypes-to-native-byte-order-in-efx_mcdi_get_board_cfg.patch queue-3.4/sfc-fix-timekeeping-in-efx_mcdi_poll.patch queue-3.4/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch queue-3.4/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html