From patchwork Tue Feb 9 15:20:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Kochetkov X-Patchwork-Id: 580892 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B8D141402D2 for ; Wed, 10 Feb 2016 02:21:51 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=SGG+DhiB; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932698AbcBIPVQ (ORCPT ); Tue, 9 Feb 2016 10:21:16 -0500 Received: from mail-lb0-f195.google.com ([209.85.217.195]:35262 "EHLO mail-lb0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932505AbcBIPVM (ORCPT ); Tue, 9 Feb 2016 10:21:12 -0500 Received: by mail-lb0-f195.google.com with SMTP id dx9so5662249lbc.2; Tue, 09 Feb 2016 07:21:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KB4OsoZv1jazSCe2SfQweZdcH+uW0gwSIziRa8LdmCM=; b=SGG+DhiBiUh7O6iS+peH3gjVMJZw30eqMFT6eSw+U/Hgv9o9PoDbfuBHXELwKcOh3B cHlFJ8U21xfe7hQoZRukFOzpHJA7Tv08tk0OhLcbLrPr3j0+iSrvHVn3BxyF7eQJjPcE A42cuIHrvKXI6JMvxOR0nGhuBRCBqThp4fjUAM0jYo657tVIHFEaf3VxC53N1qvzTCRz rfrC38N6ysdbyAl6vzuzJbT72aFDA/xgeyZcXzN+R5o5dTUqKaDX4b1mAVuGm75JTOak pZnTYk7iizsr4K9Ny7jLCkvpgHVJo0GPajbBj1Ob6yaSNS/28Dir/UaOHa+N//rK1fUc 2T0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KB4OsoZv1jazSCe2SfQweZdcH+uW0gwSIziRa8LdmCM=; b=bWkPojXIQGP36fhzzH5TnPbVWXDnfIBHGrHmFkkIpkTGD5MrXhoFX++/h35t5DD054 R+C+uHYucsC+N7Fx/IE+PjaKeFZiSAm9i7QEzkFmpWHaPK359zscphAuOJus6q8Rm+AN bvFSQ1b7ZwdBOO8HpTzrJ/puNxnAO0RXStVIc0TzDIeCX0fOuS+gCHGXF58TDJq3ag7V r2O9CfTTXkxHk1BiTkmyMoe2+iihuKLhZ+DU5JGzuSs1n/NgEKLzOZ6zY5SmNKUKQexY hxGY+KWTaDJSSRYl4h2jhT4tRpB5rMafRqSzp6DwoUjEjS8zi6zFNRok9TXdz3sAmzNc MWjQ== X-Gm-Message-State: AG10YOTjB/LvZDd6Q/zXP6zsCa4ofK0z8ehyx4x7Vfy1R10EzcrmdJewqA+yTfL+1rhnRA== X-Received: by 10.112.140.1 with SMTP id rc1mr13903723lbb.112.1455031271402; Tue, 09 Feb 2016 07:21:11 -0800 (PST) Received: from ubuntu.lintech.ru ([185.35.119.87]) by smtp.gmail.com with ESMTPSA id l66sm3861832lfb.16.2016.02.09.07.21.10 (version=TLS1_1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 Feb 2016 07:21:10 -0800 (PST) From: Alexander Kochetkov To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, "'David S. Miller'" , Alexander Kochetkov Subject: [PATCH 3/3] net: arc_emac: fix sk_buff leak Date: Tue, 9 Feb 2016 18:20:40 +0300 Message-Id: <1455031240-29385-4-git-send-email-al.kochet@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1455031240-29385-1-git-send-email-al.kochet@gmail.com> References: <1455031240-29385-1-git-send-email-al.kochet@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org EMAC could be disabled, while there is some sb_buff in use. That buffers got lost for linux. In order to reproduce run on device during active ethernet work: ifconfig eth0 down Signed-off-by: Alexander Kochetkov --- CC: stable@vger.kernel.org # 3.18.x- --- drivers/net/ethernet/arc/emac_main.c | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index 4f6e5be..6446af1 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c @@ -518,6 +518,64 @@ static void arc_emac_set_rx_mode(struct net_device *ndev) } /** + * arc_free_tx_queue - free skb from tx queue + * @ndev: Pointer to the network device. + * + * This function must be called while EMAC disable + */ +static void arc_free_tx_queue(struct net_device *ndev) +{ + struct arc_emac_priv *priv = netdev_priv(ndev); + unsigned int i; + + for (i = 0; i < TX_BD_NUM; i++) { + struct arc_emac_bd *txbd = &priv->txbd[i]; + struct buffer_state *tx_buff = &priv->tx_buff[i]; + + if (tx_buff->skb) { + dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr), + dma_unmap_len(tx_buff, len), DMA_TO_DEVICE); + + /* return the sk_buff to system */ + dev_kfree_skb_irq(tx_buff->skb); + } + + txbd->info = 0; + txbd->data = 0; + tx_buff->skb = NULL; + } +} + +/** + * arc_free_rx_queue - free skb from rx queue + * @ndev: Pointer to the network device. + * + * This function must be called while EMAC disable + */ +static void arc_free_rx_queue(struct net_device *ndev) +{ + struct arc_emac_priv *priv = netdev_priv(ndev); + unsigned int i; + + for (i = 0; i < RX_BD_NUM; i++) { + struct arc_emac_bd *rxbd = &priv->rxbd[i]; + struct buffer_state *rx_buff = &priv->rx_buff[i]; + + if (rx_buff->skb) { + dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); + + /* return the sk_buff to system */ + dev_kfree_skb_irq(rx_buff->skb); + } + + rxbd->info = 0; + rxbd->data = 0; + rx_buff->skb = NULL; + } +} + +/** * arc_emac_stop - Close the network device. * @ndev: Pointer to the network device. * @@ -538,6 +596,10 @@ static int arc_emac_stop(struct net_device *ndev) /* Disable EMAC */ arc_reg_clr(priv, R_CTRL, EN_MASK); + /* Return the sk_buff to system */ + arc_free_tx_queue(ndev); + arc_free_rx_queue(ndev); + return 0; }