From patchwork Tue Mar 14 17:15:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Pujari, Bimmy" X-Patchwork-Id: 738796 X-Patchwork-Delegate: jeffrey.t.kirsher@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vjKdk5W3Cz9rxm for ; Wed, 15 Mar 2017 03:17:46 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="qXOCeneO"; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 406778968B; Tue, 14 Mar 2017 16:17:45 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kJKNcxIctQbq; Tue, 14 Mar 2017 16:17:41 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id B8F7F8976F; Tue, 14 Mar 2017 16:17:40 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id 4241C1BFEBB for ; Tue, 14 Mar 2017 16:17:39 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 3A1DD8959C for ; Tue, 14 Mar 2017 16:17:39 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6I3NLKeppopo for ; Tue, 14 Mar 2017 16:17:36 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by whitealder.osuosl.org (Postfix) with ESMTPS id 5F4D88960C for ; Tue, 14 Mar 2017 16:17:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1489508256; x=1521044256; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=4wD5Bz926WkUaBoK/sn1b62nx90EVnZdES60Zl67gu4=; b=qXOCeneOqHqihqdlg2JzdfyT+AU1yz8ZSeVQVUHN2pL2nzHHMRkztR/B c5jrLdT6ip8EfyZ4Qo7IxFDn44Tikw==; Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Mar 2017 09:17:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.36,164,1486454400"; d="scan'208"; a="1108362395" Received: from bimmy.jf.intel.com (HELO bimmy.linux1.jf.intel.com) ([10.166.35.87]) by orsmga001.jf.intel.com with ESMTP; 14 Mar 2017 09:17:34 -0700 From: Bimmy Pujari To: intel-wired-lan@lists.osuosl.org Date: Tue, 14 Mar 2017 10:15:23 -0700 Message-Id: <1489511727-10959-2-git-send-email-bimmy.pujari@intel.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1489511727-10959-1-git-send-email-bimmy.pujari@intel.com> References: <1489511727-10959-1-git-send-email-bimmy.pujari@intel.com> Subject: [Intel-wired-lan] [next PATCH S63 2/6] i40e/i40evf: Pull code for grabbing and syncing rx_buffer from fetch_buffer X-BeenThere: intel-wired-lan@lists.osuosl.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-wired-lan-bounces@lists.osuosl.org Sender: "Intel-wired-lan" From: Alexander Duyck This patch pulls the code responsible for fetching the Rx buffer and synchronizing DMA into a function, specifically called i40e_get_rx_buffer. The general idea is to allow for better code reuse by pulling this out of i40e_fetch_rx_buffer. We dropped a couple of prefetches since the time between the prefetch being called and the data being accessed was too small to be useful. Signed-off-by: Alexander Duyck Change-ID: I4885fce4b2637dbedc8e16431169d23d3d7e79b9 Tested-by: Andrew Bowers --- Testing Hints: Basic Rx testing should be enough to verify this is working correctly. drivers/net/ethernet/intel/i40e/i40e_txrx.c | 58 ++++++++++++++++----------- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 58 ++++++++++++++++----------- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 68936b6..d1fc0f0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1754,9 +1754,35 @@ static bool i40e_add_rx_frag(struct i40e_ring *rx_ring, } /** + * i40e_get_rx_buffer - Fetch Rx buffer and synchronize data for use + * @rx_ring: rx descriptor ring to transact packets on + * @size: size of buffer to add to skb + * + * This function will pull an Rx buffer from the ring and synchronize it + * for use by the CPU. + */ +static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring, + const unsigned int size) +{ + struct i40e_rx_buffer *rx_buffer; + + rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; + prefetchw(rx_buffer->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); + + return rx_buffer; +} + +/** * i40e_fetch_rx_buffer - Allocate skb and populate it * @rx_ring: rx descriptor ring to transact packets on - * @rx_desc: descriptor containing info written by hardware + * @rx_buffer: rx buffer to pull data from * @size: size of buffer to add to skb * * This function allocates an skb on the fly, and populates it with the page @@ -1766,19 +1792,13 @@ static bool i40e_add_rx_frag(struct i40e_ring *rx_ring, */ static inline struct sk_buff *i40e_fetch_rx_buffer(struct i40e_ring *rx_ring, - union i40e_rx_desc *rx_desc, + struct i40e_rx_buffer *rx_buffer, struct sk_buff *skb, unsigned int size) { - struct i40e_rx_buffer *rx_buffer; - struct page *page; - - rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; - page = rx_buffer->page; - prefetchw(page); - if (likely(!skb)) { - void *page_addr = page_address(page) + rx_buffer->page_offset; + void *page_addr = page_address(rx_buffer->page) + + rx_buffer->page_offset; /* prefetch first cache line of first page */ prefetch(page_addr); @@ -1794,21 +1814,8 @@ struct sk_buff *i40e_fetch_rx_buffer(struct i40e_ring *rx_ring, rx_ring->rx_stats.alloc_buff_failed++; return NULL; } - - /* we will be copying header into skb->data in - * pskb_may_pull so it is in our interest to prefetch - * it now to avoid a possible cache miss - */ - 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 (i40e_add_rx_frag(rx_ring, rx_buffer, size, skb)) { /* hand second half of page back to the ring */ @@ -1886,6 +1893,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) bool failure = false; while (likely(total_rx_packets < budget)) { + struct i40e_rx_buffer *rx_buffer; union i40e_rx_desc *rx_desc; unsigned int size; u16 vlan_tag; @@ -1918,7 +1926,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) */ dma_rmb(); - skb = i40e_fetch_rx_buffer(rx_ring, rx_desc, skb, size); + rx_buffer = i40e_get_rx_buffer(rx_ring, size); + + skb = i40e_fetch_rx_buffer(rx_ring, rx_buffer, skb, size); if (!skb) break; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index e41eb46..2320ec4 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1113,9 +1113,35 @@ static bool i40e_add_rx_frag(struct i40e_ring *rx_ring, } /** + * i40e_get_rx_buffer - Fetch Rx buffer and synchronize data for use + * @rx_ring: rx descriptor ring to transact packets on + * @size: size of buffer to add to skb + * + * This function will pull an Rx buffer from the ring and synchronize it + * for use by the CPU. + */ +static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring, + const unsigned int size) +{ + struct i40e_rx_buffer *rx_buffer; + + rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; + prefetchw(rx_buffer->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); + + return rx_buffer; +} + +/** * i40evf_fetch_rx_buffer - Allocate skb and populate it * @rx_ring: rx descriptor ring to transact packets on - * @rx_desc: descriptor containing info written by hardware + * @rx_buffer: rx buffer to pull data from * @size: size of buffer to add to skb * * This function allocates an skb on the fly, and populates it with the page @@ -1125,19 +1151,13 @@ static bool i40e_add_rx_frag(struct i40e_ring *rx_ring, */ static inline struct sk_buff *i40evf_fetch_rx_buffer(struct i40e_ring *rx_ring, - union i40e_rx_desc *rx_desc, + struct i40e_rx_buffer *rx_buffer, struct sk_buff *skb, unsigned int size) { - struct i40e_rx_buffer *rx_buffer; - struct page *page; - - rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; - page = rx_buffer->page; - prefetchw(page); - if (likely(!skb)) { - void *page_addr = page_address(page) + rx_buffer->page_offset; + void *page_addr = page_address(rx_buffer->page) + + rx_buffer->page_offset; /* prefetch first cache line of first page */ prefetch(page_addr); @@ -1153,21 +1173,8 @@ struct sk_buff *i40evf_fetch_rx_buffer(struct i40e_ring *rx_ring, rx_ring->rx_stats.alloc_buff_failed++; return NULL; } - - /* we will be copying header into skb->data in - * pskb_may_pull so it is in our interest to prefetch - * it now to avoid a possible cache miss - */ - 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 (i40e_add_rx_frag(rx_ring, rx_buffer, size, skb)) { /* hand second half of page back to the ring */ @@ -1240,6 +1247,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) bool failure = false; while (likely(total_rx_packets < budget)) { + struct i40e_rx_buffer *rx_buffer; union i40e_rx_desc *rx_desc; unsigned int size; u16 vlan_tag; @@ -1272,7 +1280,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) */ dma_rmb(); - skb = i40evf_fetch_rx_buffer(rx_ring, rx_desc, skb, size); + rx_buffer = i40e_get_rx_buffer(rx_ring, size); + + skb = i40evf_fetch_rx_buffer(rx_ring, rx_buffer, skb, size); if (!skb) break;