Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752209AbdLGIuF (ORCPT ); Thu, 7 Dec 2017 03:50:05 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:50315 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750781AbdLGIuD (ORCPT ); Thu, 7 Dec 2017 03:50:03 -0500 From: Antoine Tenart To: davem@davemloft.net Cc: Antoine Tenart , gregory.clement@free-electrons.com, thomas.petazzoni@free-electrons.com, miquel.raynal@free-electrons.com, nadavh@marvell.com, mw@semihalf.com, stefanc@marvell.com, ymarkman@marvell.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 2/6] net: mvpp2: disable TSO if its buffers cannot be allocated Date: Thu, 7 Dec 2017 09:48:59 +0100 Message-Id: <20171207084903.27144-3-antoine.tenart@free-electrons.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171207084903.27144-1-antoine.tenart@free-electrons.com> References: <20171207084903.27144-1-antoine.tenart@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2216 Lines: 71 This patch changes the PPv2 behaviour when the TSO specific headers cannot be allocated. In such cases the driver was previously failing and the interface wasn't enabled while only the TSO feature is disabled now and a warning message is shown. Such memory allocation failures can happen when DMA_CMA is enabled and CMA_SIZE_MBYTES is too small (ie. its default value). Signed-off-by: Antoine Tenart --- drivers/net/ethernet/marvell/mvpp2.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index d67f40ee63b3..2f86358614a6 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -5735,6 +5735,8 @@ static int mvpp2_txq_init(struct mvpp2_port *port, u32 val; int cpu, desc, desc_per_txq, tx_port_num; struct mvpp2_txq_pcpu *txq_pcpu; + struct net_device *dev = port->dev; + bool tso = dev->features & NETIF_F_TSO; txq->size = port->tx_ring_size; @@ -5807,13 +5809,41 @@ static int mvpp2_txq_init(struct mvpp2_port *port, txq_pcpu->stop_threshold = txq->size - MVPP2_MAX_SKB_DESCS; txq_pcpu->wake_threshold = txq_pcpu->stop_threshold / 2; + if (!tso) + continue; + txq_pcpu->tso_headers = dma_alloc_coherent(port->dev->dev.parent, txq_pcpu->size * TSO_HEADER_SIZE, &txq_pcpu->tso_headers_dma, GFP_KERNEL); if (!txq_pcpu->tso_headers) - return -ENOMEM; + tso = false; + } + + /* TSO was enabled but not enough memory is available to allocate the + * TSO specific buffers. Free the successfully allocated buffers, warn + * the user and disable TSO. + */ + if ((dev->features & NETIF_F_TSO) && !tso) + goto cleanup_tso; + + return 0; + +cleanup_tso: + dev->features &= ~NETIF_F_TSO; + netdev_warn(dev, "TSO disabled\n"); + + for_each_present_cpu(cpu) { + txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); + + if (txq_pcpu->tso_headers) + dma_free_coherent(port->dev->dev.parent, + txq_pcpu->size * TSO_HEADER_SIZE, + txq_pcpu->tso_headers, + txq_pcpu->tso_headers_dma); + + txq_pcpu->tso_headers = NULL; } return 0; -- 2.14.3