get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/806044/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 806044,
    "url": "http://patchwork.ozlabs.org/api/patches/806044/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1503699810-12803-3-git-send-email-isubramanian@apm.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1503699810-12803-3-git-send-email-isubramanian@apm.com>",
    "list_archive_url": null,
    "date": "2017-08-25T22:23:30",
    "name": "[2/2] drivers: net: xgene: Clean up all outstanding tx descriptors",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "3771c4f40c85cf2344a91cd734e9dadcfb8d68d9",
    "submitter": {
        "id": 47568,
        "url": "http://patchwork.ozlabs.org/api/people/47568/?format=api",
        "name": "Iyappan Subramanian",
        "email": "isubramanian@apm.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1503699810-12803-3-git-send-email-isubramanian@apm.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/806044/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/806044/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=apm.com header.i=@apm.com header.b=\"Vue2DtTD\";\n\tdkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xfG0X3CRnz9t3k\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat, 26 Aug 2017 08:23:56 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S935034AbdHYWXy (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 25 Aug 2017 18:23:54 -0400",
            "from mail-pg0-f41.google.com ([74.125.83.41]:32969 \"EHLO\n\tmail-pg0-f41.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S933777AbdHYWXw (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 25 Aug 2017 18:23:52 -0400",
            "by mail-pg0-f41.google.com with SMTP id t3so5784955pgt.0\n\tfor <netdev@vger.kernel.org>; Fri, 25 Aug 2017 15:23:51 -0700 (PDT)",
            "from isubrama-dev.amcc.com ([206.80.4.98])\n\tby smtp.gmail.com with ESMTPSA id\n\tc80sm13889519pfj.26.2017.08.25.15.23.48\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 25 Aug 2017 15:23:49 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=apm.com; s=apm;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=mtF2T8a0fjnWX6sNOENsoKt5WUt+PwmlWUHFcxlIKyU=;\n\tb=Vue2DtTDVjeMgpi+qV79tTEa9moKGp25HDx3N8yPgXQ5aQkO6+3VYloqDphPvxNpGu\n\tMFbo/67g93xB0iop5cG7B+r/6e0nVc+Z71z9Ewjs/8vlux3O6lOmhACDk8Ym9is7+ODc\n\twxnCUOcB4Vznguv7ekHeIAD9qSbNQKcG6RyMs=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=mtF2T8a0fjnWX6sNOENsoKt5WUt+PwmlWUHFcxlIKyU=;\n\tb=k69mdlsFYwcTgwC+aowAdo4Ar1xUR1LgEsHqMh5VtvkSUIA+vYxVikj+ILqHe12+Kv\n\tZnTRdO9+jubcgAtdPxE+iGk2g20BO4mGF//7bmhi65V6ZN6InQF7EHyVvtJQfezQmrpY\n\tvTAH+KctHx4z+9RP9BxpzkFGW6QwK26Rry5VTewqq49c3RAbRwESE18PD3WeeINCmDCV\n\tc5QQGnx4tlMwV2YMmAqIz3tFLkmL7SWpdTwrMjTVRX95xgX1Jru3ibSpOi8OK/LDzvr4\n\tgvO2FO7R3zJBRGtghzqUm0SX3kmJA6RH/LsN81aSMqHtx+79JsfASRl7i1NDS9gblPPj\n\tOrrg==",
        "X-Gm-Message-State": "AHYfb5i2ape1+lXJ+PyCwOBP9TaNfxyOPXjNPVvcTfnxEO0yAu7QXrsU\n\tfLA4uB9ROGwoZNCc",
        "X-Received": "by 10.98.71.88 with SMTP id u85mr11358275pfa.185.1503699831218; \n\tFri, 25 Aug 2017 15:23:51 -0700 (PDT)",
        "From": "Iyappan Subramanian <isubramanian@apm.com>",
        "To": "davem@davemloft.net, netdev@vger.kernel.org",
        "Cc": "linux-arm-kernel@lists.infradead.org, dnelson@redhat.com,\n\tqnguyen@apm.com, patches@apm.com,\n\tIyappan Subramanian <isubramanian@apm.com>",
        "Subject": "[PATCH 2/2] drivers: net: xgene: Clean up all outstanding tx\n\tdescriptors",
        "Date": "Fri, 25 Aug 2017 15:23:30 -0700",
        "Message-Id": "<1503699810-12803-3-git-send-email-isubramanian@apm.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1503699810-12803-1-git-send-email-isubramanian@apm.com>",
        "References": "<1503699810-12803-1-git-send-email-isubramanian@apm.com>",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "When xgene_enet is rmmod'd and there are still outstanding tx descriptors\nthat have been setup but have not completed, it is possible on the next\nmodprobe of the driver to receive the oldest of such tx descriptors. This\nresults in a kernel NULL pointer dereference.\n\nThis patch attempts to clean up (by tearing down) all outstanding tx\ndescriptors when the xgene_enet driver is being rmmod'd.\n\nGiven that, on the next modprobe it should be safe to ignore any such tx\ndescriptors received that map to a NULL skb pointer.\n\nAdditionally this patch removes redundant call to dev_kfree_skb_any() from\nxgene_enet_setup_tx_desc(). The only caller of xgene_enet_setup_tx_desc()\nwill call dev_kfree_skb_any() upon return of an error. Nothing is gained by\ncalling it twice in a row.\n\nSigned-off-by: Iyappan Subramanian <isubramanian@apm.com>\nSigned-off-by: Dean Nelson <dnelson@redhat.com>\nTested-by: Quan Nguyen <qnguyen@apm.com>\n---\n drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 120 +++++++++++++++++------\n 1 file changed, 89 insertions(+), 31 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c\nindex 6e253d9..76e2903 100644\n--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c\n+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c\n@@ -237,22 +237,24 @@ static irqreturn_t xgene_enet_rx_irq(const int irq, void *data)\n \treturn IRQ_HANDLED;\n }\n \n-static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,\n-\t\t\t\t    struct xgene_enet_raw_desc *raw_desc)\n+static dma_addr_t *xgene_get_frag_dma_array(struct xgene_enet_desc_ring *ring,\n+\t\t\t\t\t    u16 skb_index)\n {\n-\tstruct xgene_enet_pdata *pdata = netdev_priv(cp_ring->ndev);\n-\tstruct sk_buff *skb;\n+\treturn &ring->frag_dma_addr[skb_index * MAX_SKB_FRAGS];\n+}\n+\n+static void xgene_enet_teardown_tx_desc(struct xgene_enet_desc_ring *cp_ring,\n+\t\t\t\t\tstruct xgene_enet_raw_desc *raw_desc,\n+\t\t\t\t\tstruct xgene_enet_raw_desc *exp_desc,\n+\t\t\t\t\tstruct sk_buff *skb,\n+\t\t\t\t\tu16 skb_index)\n+{\n+\tdma_addr_t dma_addr, *frag_dma_addr;\n \tstruct device *dev;\n \tskb_frag_t *frag;\n-\tdma_addr_t *frag_dma_addr;\n-\tu16 skb_index;\n-\tu8 mss_index;\n-\tu8 status;\n \tint i;\n \n-\tskb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));\n-\tskb = cp_ring->cp_skb[skb_index];\n-\tfrag_dma_addr = &cp_ring->frag_dma_addr[skb_index * MAX_SKB_FRAGS];\n+\tfrag_dma_addr = xgene_get_frag_dma_array(cp_ring, skb_index);\n \n \tdev = ndev_to_dev(cp_ring->ndev);\n \tdma_unmap_single(dev, GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1)),\n@@ -265,6 +267,36 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,\n \t\t\t       DMA_TO_DEVICE);\n \t}\n \n+\tif (exp_desc && GET_VAL(LL_BYTES_LSB, le64_to_cpu(raw_desc->m2))) {\n+\t\tdma_addr = GET_VAL(DATAADDR, le64_to_cpu(exp_desc->m2));\n+\t\tdma_unmap_single(dev, dma_addr, sizeof(u64) * MAX_EXP_BUFFS,\n+\t\t\t\t DMA_TO_DEVICE);\n+\t}\n+\n+\tdev_kfree_skb_any(skb);\n+}\n+\n+static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,\n+\t\t\t\t    struct xgene_enet_raw_desc *raw_desc,\n+\t\t\t\t    struct xgene_enet_raw_desc *exp_desc)\n+{\n+\tstruct xgene_enet_pdata *pdata = netdev_priv(cp_ring->ndev);\n+\tstruct sk_buff *skb;\n+\tu16 skb_index;\n+\tu8 status;\n+\tu8 mss_index;\n+\n+\tskb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));\n+\tskb = cp_ring->cp_skb[skb_index];\n+\tif (unlikely(!skb)) {\n+\t\tnetdev_err(cp_ring->ndev, \"completion skb is NULL\\n\");\n+\t\treturn -EIO;\n+\t}\n+\tcp_ring->cp_skb[skb_index] = NULL;\n+\n+\txgene_enet_teardown_tx_desc(cp_ring, raw_desc, exp_desc, skb,\n+\t\t\t\t    skb_index);\n+\n \tif (GET_BIT(ET, le64_to_cpu(raw_desc->m3))) {\n \t\tmss_index = GET_VAL(MSS, le64_to_cpu(raw_desc->m3));\n \t\tspin_lock(&pdata->mss_lock);\n@@ -279,12 +311,6 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,\n \t\tcp_ring->tx_errors++;\n \t}\n \n-\tif (likely(skb)) {\n-\t\tdev_kfree_skb_any(skb);\n-\t} else {\n-\t\tnetdev_err(cp_ring->ndev, \"completion skb is NULL\\n\");\n-\t}\n-\n \treturn 0;\n }\n \n@@ -412,11 +438,6 @@ static __le64 *xgene_enet_get_exp_bufs(struct xgene_enet_desc_ring *ring)\n \treturn exp_bufs;\n }\n \n-static dma_addr_t *xgene_get_frag_dma_array(struct xgene_enet_desc_ring *ring)\n-{\n-\treturn &ring->cp_ring->frag_dma_addr[ring->tail * MAX_SKB_FRAGS];\n-}\n-\n static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,\n \t\t\t\t    struct sk_buff *skb)\n {\n@@ -473,7 +494,8 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,\n \tfor (i = nr_frags; i < 4 ; i++)\n \t\texp_desc[i ^ 1] = cpu_to_le64(LAST_BUFFER);\n \n-\tfrag_dma_addr = xgene_get_frag_dma_array(tx_ring);\n+\tfrag_dma_addr = xgene_get_frag_dma_array(tx_ring->cp_ring,\n+\t\t\t\t\t\t tx_ring->tail);\n \n \tfor (i = 0, fidx = 0; split || (fidx < nr_frags); i++) {\n \t\tif (!split) {\n@@ -484,7 +506,7 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,\n \t\t\tpbuf_addr = skb_frag_dma_map(dev, frag, 0, size,\n \t\t\t\t\t\t     DMA_TO_DEVICE);\n \t\t\tif (dma_mapping_error(dev, pbuf_addr))\n-\t\t\t\treturn -EINVAL;\n+\t\t\t\tgoto err;\n \n \t\t\tfrag_dma_addr[fidx] = pbuf_addr;\n \t\t\tfidx++;\n@@ -539,10 +561,9 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,\n \t\tdma_addr = dma_map_single(dev, exp_bufs,\n \t\t\t\t\t  sizeof(u64) * MAX_EXP_BUFFS,\n \t\t\t\t\t  DMA_TO_DEVICE);\n-\t\tif (dma_mapping_error(dev, dma_addr)) {\n-\t\t\tdev_kfree_skb_any(skb);\n-\t\t\treturn -EINVAL;\n-\t\t}\n+\t\tif (dma_mapping_error(dev, dma_addr))\n+\t\t\tgoto err;\n+\n \t\ti = ell_bytes >> LL_BYTES_LSB_LEN;\n \t\texp_desc[2] = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |\n \t\t\t\t\t  SET_VAL(LL_BYTES_MSB, i) |\n@@ -558,6 +579,19 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,\n \ttx_ring->tail = tail;\n \n \treturn count;\n+\n+err:\n+\tdma_unmap_single(dev, GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1)),\n+\t\t\t skb_headlen(skb),\n+\t\t\t DMA_TO_DEVICE);\n+\n+\tfor (i = 0; i < fidx; i++) {\n+\t\tfrag = &skb_shinfo(skb)->frags[i];\n+\t\tdma_unmap_page(dev, frag_dma_addr[i], skb_frag_size(frag),\n+\t\t\t       DMA_TO_DEVICE);\n+\t}\n+\n+\treturn -EINVAL;\n }\n \n static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,\n@@ -828,7 +862,8 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,\n \t\tif (is_rx_desc(raw_desc)) {\n \t\t\tret = xgene_enet_rx_frame(ring, raw_desc, exp_desc);\n \t\t} else {\n-\t\t\tret = xgene_enet_tx_completion(ring, raw_desc);\n+\t\t\tret = xgene_enet_tx_completion(ring, raw_desc,\n+\t\t\t\t\t\t       exp_desc);\n \t\t\tis_completion = true;\n \t\t}\n \t\txgene_enet_mark_desc_slot_empty(raw_desc);\n@@ -1071,18 +1106,41 @@ static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata)\n {\n \tstruct xgene_enet_desc_ring *buf_pool, *page_pool;\n \tstruct xgene_enet_desc_ring *ring;\n-\tint i;\n+\tstruct xgene_enet_raw_desc *raw_desc, *exp_desc;\n+\tstruct sk_buff *skb;\n+\tint i, j, k;\n \n \tfor (i = 0; i < pdata->txq_cnt; i++) {\n \t\tring = pdata->tx_ring[i];\n \t\tif (ring) {\n+\t\t\t/*\n+\t\t\t * Find any tx descriptors that were setup but never\n+\t\t\t * completed, and teardown the setup.\n+\t\t\t */\n+\t\t\tfor (j = 0; j < ring->slots; j++) {\n+\t\t\t\tskb = ring->cp_ring->cp_skb[j];\n+\t\t\t\tif (likely(!skb))\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\traw_desc = &ring->raw_desc[j];\n+\t\t\t\texp_desc = NULL;\n+\t\t\t\tif (GET_BIT(NV, le64_to_cpu(raw_desc->m0))) {\n+\t\t\t\t\tk = (j + 1) & (ring->slots - 1);\n+\t\t\t\t\texp_desc = &ring->raw_desc[k];\n+\t\t\t\t}\n+\n+\t\t\t\txgene_enet_teardown_tx_desc(ring->cp_ring,\n+\t\t\t\t\t\t\t    raw_desc, exp_desc,\n+\t\t\t\t\t\t\t    skb, j);\n+\t\t\t}\n+\n \t\t\txgene_enet_delete_ring(ring);\n \t\t\tpdata->port_ops->clear(pdata, ring);\n+\n \t\t\tif (pdata->cq_cnt)\n \t\t\t\txgene_enet_delete_ring(ring->cp_ring);\n \t\t\tpdata->tx_ring[i] = NULL;\n \t\t}\n-\n \t}\n \n \tfor (i = 0; i < pdata->rxq_cnt; i++) {\n",
    "prefixes": [
        "2/2"
    ]
}