From patchwork Tue Mar 26 15:20:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Henriques X-Patchwork-Id: 231387 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 8C0D82C00CF for ; Wed, 27 Mar 2013 02:24:45 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UKVjr-0002t7-4A; Tue, 26 Mar 2013 15:24:39 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UKVjB-0001os-V2 for kernel-team@lists.ubuntu.com; Tue, 26 Mar 2013 15:23:58 +0000 Received: from bl20-143-66.dsl.telepac.pt ([2.81.143.66] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1UKVjB-0004rE-Kt; Tue, 26 Mar 2013 15:23:57 +0000 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Subject: [PATCH 134/150] sfc: Fix efx_rx_buf_offset() in the presence of swiotlb Date: Tue, 26 Mar 2013 15:20:33 +0000 Message-Id: <1364311249-14454-135-git-send-email-luis.henriques@canonical.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1364311249-14454-1-git-send-email-luis.henriques@canonical.com> References: <1364311249-14454-1-git-send-email-luis.henriques@canonical.com> X-Extended-Stable: 3.5 Cc: Ben Hutchings X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com 3.5.7.9 -stable review patch. If anyone has any objections, please let me know. ------------------ From: Ben Hutchings commit b590ace09d51cd39744e0f7662c5e4a0d1b5d952 upstream. We assume that the mapping between DMA and virtual addresses is done on whole pages, so we can find the page offset of an RX buffer using the lower bits of the DMA address. However, swiotlb maps in units of 2K, breaking this assumption. Add an explicit page_offset field to struct efx_rx_buffer. Signed-off-by: Ben Hutchings Signed-off-by: Luis Henriques --- drivers/net/ethernet/sfc/net_driver.h | 4 +++- drivers/net/ethernet/sfc/rx.c | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 8e3e0cf..b3b3a60 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -206,6 +206,7 @@ struct efx_tx_queue { * Will be %NULL if the buffer slot is currently free. * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE. * Will be %NULL if the buffer slot is currently free. + * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE. * @len: Buffer length, in bytes. * @flags: Flags for buffer and packet state. */ @@ -215,7 +216,8 @@ struct efx_rx_buffer { struct sk_buff *skb; struct page *page; } u; - unsigned int len; + u16 page_offset; + u16 len; u16 flags; }; #define EFX_RX_BUF_PAGE 0x0001 diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 622b0d7..7faaea8 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -90,11 +90,7 @@ static unsigned int rx_refill_threshold; static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, struct efx_rx_buffer *buf) { - /* Offset is always within one page, so we don't need to consider - * the page order. - */ - return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) + - efx->type->rx_buffer_hash_size; + return buf->page_offset + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -188,6 +184,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) struct efx_rx_buffer *rx_buf; struct page *page; void *page_addr; + unsigned int page_offset; struct efx_rx_page_state *state; dma_addr_t dma_addr; unsigned index, count; @@ -214,12 +211,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) page_addr += sizeof(struct efx_rx_page_state); dma_addr += sizeof(struct efx_rx_page_state); + page_offset = sizeof(struct efx_rx_page_state); split: index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; + rx_buf->page_offset = page_offset; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; rx_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; @@ -231,6 +230,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) get_page(page); dma_addr += (PAGE_SIZE >> 1); page_addr += (PAGE_SIZE >> 1); + page_offset += (PAGE_SIZE >> 1); ++count; goto split; }