From patchwork Thu Jul 25 14:42:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Henriques X-Patchwork-Id: 261749 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 7E29F2C00D5 for ; Fri, 26 Jul 2013 00:45:09 +1000 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1V2Mmt-00041D-3a; Thu, 25 Jul 2013 14:45:03 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1V2MkB-0003Bo-Dr for kernel-team@lists.ubuntu.com; Thu, 25 Jul 2013 14:42:15 +0000 Received: from bl16-85-105.dsl.telepac.pt ([188.81.85.105] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1V2MkA-0005nD-Ji; Thu, 25 Jul 2013 14:42:14 +0000 From: Luis Henriques To: Neil Horman Subject: [ 3.5.y.z extended stable ] Patch "atl1e: unmap partially mapped skb on dma error and free skb" has been added to staging queue Date: Thu, 25 Jul 2013 15:42:13 +0100 Message-Id: <1374763333-18417-1-git-send-email-luis.henriques@canonical.com> X-Mailer: git-send-email 1.8.1.2 X-Extended-Stable: 3.5 Cc: Jay Cliburn , Chris Snook , kernel-team@lists.ubuntu.com, Ben Hutchings , "David S. Miller" 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 This is a note to let you know that I have just added a patch titled atl1e: unmap partially mapped skb on dma error and free skb to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.5.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Luis ------ From 358e8743a4b50131b69e2f45094ab8963865a924 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 16 Jul 2013 10:49:41 -0400 Subject: [PATCH] atl1e: unmap partially mapped skb on dma error and free skb commit 584ec4355355ffac43571b02a314d43eb2f7fcbf upstream. Ben Hutchings pointed out that my recent update to atl1e in commit 352900b583b2852152a1e05ea0e8b579292e731e ("atl1e: fix dma mapping warnings") was missing a bit of code. Specifically it reset the hardware tx ring to its origional state when we hit a dma error, but didn't unmap any exiting mappings from the operation. This patch fixes that up. It also remembers to free the skb in the event that an error occurs, so we don't leak. Untested, as I don't have hardware. I think its pretty straightforward, but please review closely. Signed-off-by: Neil Horman CC: Ben Hutchings CC: Jay Cliburn CC: Chris Snook CC: "David S. Miller" Signed-off-by: David S. Miller Signed-off-by: Luis Henriques --- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) -- 1.8.1.2 diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 1dfe5f7..05e72c8 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1701,6 +1701,7 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, u16 f; int segment; int ring_start = adapter->tx_ring.next_to_use; + int ring_end; nr_frags = skb_shinfo(skb)->nr_frags; segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; @@ -1744,6 +1745,15 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, map_len, PCI_DMA_TODEVICE); if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { + /* We need to unwind the mappings we've done */ + ring_end = adapter->tx_ring.next_to_use; + adapter->tx_ring.next_to_use = ring_start; + while (adapter->tx_ring.next_to_use != ring_end) { + tpd = atl1e_get_tpd(adapter); + tx_buffer = atl1e_get_tx_buffer(adapter, tpd); + pci_unmap_single(adapter->pdev, tx_buffer->dma, + tx_buffer->length, PCI_DMA_TODEVICE); + } /* Reset the tx rings next pointer */ adapter->tx_ring.next_to_use = ring_start; return -ENOSPC; @@ -1786,6 +1796,16 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, DMA_TO_DEVICE); if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { + /* We need to unwind the mappings we've done */ + ring_end = adapter->tx_ring.next_to_use; + adapter->tx_ring.next_to_use = ring_start; + while (adapter->tx_ring.next_to_use != ring_end) { + tpd = atl1e_get_tpd(adapter); + tx_buffer = atl1e_get_tx_buffer(adapter, tpd); + dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma, + tx_buffer->length, DMA_TO_DEVICE); + } + /* Reset the ring next to use pointer */ adapter->tx_ring.next_to_use = ring_start; return -ENOSPC; @@ -1876,8 +1896,10 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } - if (atl1e_tx_map(adapter, skb, tpd)) + if (atl1e_tx_map(adapter, skb, tpd)) { + dev_kfree_skb_any(skb); goto out; + } atl1e_tx_queue(adapter, tpd_req, tpd);