Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp6276505ybx; Mon, 11 Nov 2019 06:44:27 -0800 (PST) X-Google-Smtp-Source: APXvYqwAEOI3c+HWl2M7LUcXqYrqnjjs58EAQ8WBSoNWfgaTZwYMjc15Q05qhLijNYM10W81lEZm X-Received: by 2002:a50:f296:: with SMTP id f22mr26707915edm.26.1573483467476; Mon, 11 Nov 2019 06:44:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573483467; cv=none; d=google.com; s=arc-20160816; b=a5aq8gb4rW/KTotWyySl3BxvzT6CNi5pOgLMBfXKzbUr+LmeYiGJDcufVnbRHL6+GW t+rCFDryvDWvyO3sWXxFhYvjVQXKcexkYHArGHi0PktPrOjw+hUGyCBJCjeXEnZDUKp4 Xa6V5jQI3DXriHll/et2azEhXKwdhM2GFzvirE/7DLUhZCr5eXcx+VHBR9lde5o1wM1U MI4Ykm+ZsO8IRekteOF88XVW8M43HzPslxVGapdYO9vYpw3AjPu8lXP4FYsgELEVvYoL 7L6QncYdzLbEzQHMBIUguH1DGLZYZtCx1PqndozAkIh+hn5hXpzkkuMHXLcLr/E3GcA8 qX9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=viIYXvdq5uAm0aTPd5kHPH6km5fnj/Xc8sOtkZh5iok=; b=liTHX7yCa/ye7F62IU+NG/jALh6sw9EHL67DFyVVL0KafC7rugZEHJolLuOUhRPUPM bgPuaXXe8M0DR0nemOFtNYi+SMMYLLDkNOsZh02mmdWAKDouGhoGAM6A1wzRL8eEx6sS MM6h7xniinE/FEBXZlUA0Rplwc71zmdR1+JRXUpgcZBA+NM2aF8Q4KZ8QgCzVNK9uXEw AIqpRAEzrv/glGdL1TQ4UlpiLm1kuzlFp3ePhDKuuzyihGVljIEOOtiyt/Dftepdu/71 v74SclJRrVyRXNcXh1YVusCAIY9vJoILGkv0/ukmc7Xef2TOGlp5OBaLrZjHvi+O/wCi 73ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b=CB2IXLhV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e11si9770443eje.376.2019.11.11.06.44.03; Mon, 11 Nov 2019 06:44:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b=CB2IXLhV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727100AbfKKOnB (ORCPT + 99 others); Mon, 11 Nov 2019 09:43:01 -0500 Received: from smtprelay-out1.synopsys.com ([198.182.47.102]:44432 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726889AbfKKOm7 (ORCPT ); Mon, 11 Nov 2019 09:42:59 -0500 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 70152C0E0E; Mon, 11 Nov 2019 14:42:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1573483379; bh=OCh1D547y/ayETMzIo+QdmplbDDiqGFplipLwIl0zCI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:In-Reply-To: References:From; b=CB2IXLhVsqkG7Upl+6dfOsinDVyVVQ1KnspNHR0ExRMVHt32EqiAKmCbiIHcSW5lT HUIPmJN/HljDz7QT0CGsTROsS6LRDcsUvy6LHUgPI4mTW+1KUdhSgizaiz9kWIc8NK fSm0DCQkzfuz7wqqcUptYw7AGnwrLLb9F1m9NwoszeZql+z3OMXPwIXXPvYTcUoGAG F8C/kOen/G3uK2Pa2h3DJt/eRIrT7/AqAMasVOI7PnHwqp6r2NhczxBHik7mWDFPCg HZOz5Avax6RJUIYlIg/2o8g4IhoEf68oPYRaK29tr5ooD60mb147qp3+8ywClNrauK Y9hwd+ByylpZQ== Received: from de02dwia024.internal.synopsys.com (de02dwia024.internal.synopsys.com [10.225.19.81]) by mailhost.synopsys.com (Postfix) with ESMTP id 28168A0257; Mon, 11 Nov 2019 14:42:57 +0000 (UTC) From: Jose Abreu To: netdev@vger.kernel.org Cc: Joao Pinto , Jose Abreu , Giuseppe Cavallaro , Alexandre Torgue , Jose Abreu , "David S. Miller" , Maxime Coquelin , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 5/6] net: stmmac: Rework stmmac_rx() Date: Mon, 11 Nov 2019 15:42:38 +0100 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This looks over-engineered. Let's use some helpers to get the buffer length and hereby simplify the stmmac_rx() function. No performance drop was seen with the new implementation. Signed-off-by: Jose Abreu --- Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Cc: Jose Abreu Cc: "David S. Miller" Cc: Maxime Coquelin Cc: netdev@vger.kernel.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 146 ++++++++++++++-------- 1 file changed, 94 insertions(+), 52 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 5f40fbb67bac..a2fac7772666 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3443,6 +3443,55 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue); } +static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv, + struct dma_desc *p, + int status, unsigned int len) +{ + int ret, coe = priv->hw->rx_csum; + unsigned int plen = 0, hlen = 0; + + /* Not first descriptor, buffer is always zero */ + if (priv->sph && len) + return 0; + + /* First descriptor, get split header length */ + ret = stmmac_get_rx_header_len(priv, p, &hlen); + if (priv->sph && hlen) { + priv->xstats.rx_split_hdr_pkt_n++; + return hlen; + } + + /* First descriptor, not last descriptor and not split header */ + if (status & rx_not_ls) + return priv->dma_buf_sz; + + plen = stmmac_get_rx_frame_len(priv, p, coe); + + /* First descriptor and last descriptor and not split header */ + return min_t(unsigned int, priv->dma_buf_sz, plen); +} + +static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, + struct dma_desc *p, + int status, unsigned int len) +{ + int coe = priv->hw->rx_csum; + unsigned int plen = 0; + + /* Not split header, buffer is not available */ + if (!priv->sph) + return 0; + + /* Not last descriptor */ + if (status & rx_not_ls) + return priv->dma_buf_sz; + + plen = stmmac_get_rx_frame_len(priv, p, coe); + + /* Last descriptor */ + return plen - len; +} + /** * stmmac_rx - manage the receive process * @priv: driver private structure @@ -3472,11 +3521,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) stmmac_display_ring(priv, rx_head, DMA_RX_SIZE, true); } while (count < limit) { - unsigned int hlen = 0, prev_len = 0; + unsigned int buf1_len = 0, buf2_len = 0; enum pkt_hash_types hash_type; struct stmmac_rx_buffer *buf; struct dma_desc *np, *p; - unsigned int sec_len; int entry; u32 hash; @@ -3495,7 +3543,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) break; read_again: - sec_len = 0; + buf1_len = 0; + buf2_len = 0; entry = next_entry; buf = &rx_q->buf_pool[entry]; @@ -3520,7 +3569,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) np = rx_q->dma_rx + next_entry; prefetch(np); - prefetch(page_address(buf->page)); if (priv->extend_desc) stmmac_rx_extended_status(priv, &priv->dev->stats, @@ -3537,69 +3585,61 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) goto read_again; if (unlikely(error)) { dev_kfree_skb(skb); + skb = NULL; count++; continue; } /* Buffer is good. Go on. */ - if (likely(status & rx_not_ls)) { - len += priv->dma_buf_sz; - } else { - prev_len = len; - len = stmmac_get_rx_frame_len(priv, p, coe); - - /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 - * Type frames (LLC/LLC-SNAP) - * - * llc_snap is never checked in GMAC >= 4, so this ACS - * feature is always disabled and packets need to be - * stripped manually. - */ - if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || - unlikely(status != llc_snap)) - len -= ETH_FCS_LEN; + prefetch(page_address(buf->page)); + if (buf->sec_page) + prefetch(page_address(buf->sec_page)); + + buf1_len = stmmac_rx_buf1_len(priv, p, status, len); + len += buf1_len; + buf2_len = stmmac_rx_buf2_len(priv, p, status, len); + len += buf2_len; + + /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 + * Type frames (LLC/LLC-SNAP) + * + * llc_snap is never checked in GMAC >= 4, so this ACS + * feature is always disabled and packets need to be + * stripped manually. + */ + if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || + unlikely(status != llc_snap)) { + if (buf2_len) + buf2_len -= ETH_FCS_LEN; + else + buf1_len -= ETH_FCS_LEN; + + len -= ETH_FCS_LEN; } if (!skb) { - int ret = stmmac_get_rx_header_len(priv, p, &hlen); - - if (priv->sph && !ret && (hlen > 0)) { - sec_len = len; - if (!(status & rx_not_ls)) - sec_len = sec_len - hlen; - len = hlen; - - prefetch(page_address(buf->sec_page)); - priv->xstats.rx_split_hdr_pkt_n++; - } - - skb = napi_alloc_skb(&ch->rx_napi, len); + skb = napi_alloc_skb(&ch->rx_napi, buf1_len); if (!skb) { priv->dev->stats.rx_dropped++; count++; - continue; + goto drain_data; } - dma_sync_single_for_cpu(priv->device, buf->addr, len, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(priv->device, buf->addr, + buf1_len, DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, page_address(buf->page), - len); - skb_put(skb, len); + buf1_len); + skb_put(skb, buf1_len); /* Data payload copied into SKB, page ready for recycle */ page_pool_recycle_direct(rx_q->page_pool, buf->page); buf->page = NULL; - } else { - unsigned int buf_len = len - prev_len; - - if (likely(status & rx_not_ls)) - buf_len = priv->dma_buf_sz; - + } else if (buf1_len) { dma_sync_single_for_cpu(priv->device, buf->addr, - buf_len, DMA_FROM_DEVICE); + buf1_len, DMA_FROM_DEVICE); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->page, 0, buf_len, + buf->page, 0, buf1_len, priv->dma_buf_sz); /* Data payload appended into SKB */ @@ -3607,22 +3647,23 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) buf->page = NULL; } - if (sec_len > 0) { + if (buf2_len) { dma_sync_single_for_cpu(priv->device, buf->sec_addr, - sec_len, DMA_FROM_DEVICE); + buf2_len, DMA_FROM_DEVICE); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->sec_page, 0, sec_len, + buf->sec_page, 0, buf2_len, priv->dma_buf_sz); - len += sec_len; - /* Data payload appended into SKB */ page_pool_release_page(rx_q->page_pool, buf->sec_page); buf->sec_page = NULL; } +drain_data: if (likely(status & rx_not_ls)) goto read_again; + if (!skb) + continue; /* Got entire packet into SKB. Finish it. */ @@ -3640,13 +3681,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) skb_record_rx_queue(skb, queue); napi_gro_receive(&ch->rx_napi, skb); + skb = NULL; priv->dev->stats.rx_packets++; priv->dev->stats.rx_bytes += len; count++; } - if (status & rx_not_ls) { + if (status & rx_not_ls || skb) { rx_q->state_saved = true; rx_q->state.skb = skb; rx_q->state.error = error; -- 2.7.4