get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 812662,
    "url": "http://patchwork.ozlabs.org/api/patches/812662/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170911233332.7594-3-xiyou.wangcong@gmail.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": "<20170911233332.7594-3-xiyou.wangcong@gmail.com>",
    "list_archive_url": null,
    "date": "2017-09-11T23:33:31",
    "name": "[net,v3,2/3] net_sched: fix reference counting of tc filter chain",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "eea29ece52fbdd15204f0f038abc117a5cec473a",
    "submitter": {
        "id": 211,
        "url": "http://patchwork.ozlabs.org/api/people/211/?format=api",
        "name": "Cong Wang",
        "email": "xiyou.wangcong@gmail.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/20170911233332.7594-3-xiyou.wangcong@gmail.com/mbox/",
    "series": [
        {
            "id": 2596,
            "url": "http://patchwork.ozlabs.org/api/series/2596/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=2596",
            "date": "2017-09-11T23:33:29",
            "name": "net_sched: fix filter chain reference counting",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/2596/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/812662/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/812662/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 (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"nKl/Aamo\"; dkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xrkld6zVnz9s7F\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 12 Sep 2017 09:34:05 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751258AbdIKXeE (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 11 Sep 2017 19:34:04 -0400",
            "from mail-pg0-f67.google.com ([74.125.83.67]:33255 \"EHLO\n\tmail-pg0-f67.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751105AbdIKXdx (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 11 Sep 2017 19:33:53 -0400",
            "by mail-pg0-f67.google.com with SMTP id i130so3326429pgc.0\n\tfor <netdev@vger.kernel.org>; Mon, 11 Sep 2017 16:33:53 -0700 (PDT)",
            "from tw-172-25-30-113.office.twttr.net ([8.25.197.25])\n\tby smtp.gmail.com with ESMTPSA id\n\tf5sm15676526pga.30.2017.09.11.16.33.51\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tMon, 11 Sep 2017 16:33:52 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=Bd8JlfiSIDgjQ1ftLmQbOHuesEBbhhBdHlJ+rgnug/A=;\n\tb=nKl/AamoLwu2XXwi9ZJV3VwLw4GVJGG8IpYwS7hbFg/YSDNmEWZXGVhDhKAwlDWgiW\n\tlx7J9DT8rVUeQSYxzBolod4eZqHRd+v+MceU4QEsjaoj2xNP9qUqAms4Gh9ElKyMxGdx\n\tbGkSFoA2ZUDDthCWh18T4P/ABCKyQUqHD8pHKgoP7D2otHtWvbsTCTzaArp3CzejCnnI\n\tWdtnAyGExwvi8P9FAfNM3TIRt+wO+oFe8jw2cOLcW0X4UmsXSjGaMps0qYf9WuW07lUE\n\tW/vr8JkjOFYBxlinQDwGGKRYrK8QdPdtu9txPc3FqxvC3N1E6u/a02K+T4Eu/gEhI/Kv\n\t0joQ==",
        "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=Bd8JlfiSIDgjQ1ftLmQbOHuesEBbhhBdHlJ+rgnug/A=;\n\tb=q+xdlZH6XiwQzqXn2Oq81kXVOwHJafIy3b7nN0wCkOODbE0IYn8xT0z6cQh2/+5yAQ\n\tChTZ4rYN7rE9uPnkstjZouquHXknTnVLpJ1vehoctTF+OtZHYnuA97dGRobyRleVTzd9\n\t1CekqOhxX+Jc10V0QB2HiXHWXlkSr6eV24hpbThkWdiobvSVjEeduaFq9iWtspiCpPhz\n\tla0M0ckZJhHKIdgGDqUN9dOqami2eCLC3YsZ0GUGUegcdljiTodyjFoHSbyhGsxZYQf7\n\t23X2834mz3In7JarY8miqZGErsbLsGIlHyUyGCSMN/NYtlFVXtprUaZa1Il5lsx0AlBO\n\tQ0VA==",
        "X-Gm-Message-State": "AHPjjUjjiri4YBPUE1cVEsRxx+gwr24qpPXEGK4mAKWUYVAgr/O7mHoE\n\tz9W20/rwoaH/xVxP1Eo=",
        "X-Google-Smtp-Source": "ADKCNb6BoGaVXSSRG0W2pYU0ZdF2uol7I7EAdR4ivpjjAtIShki4K94cgYauFkD7mOgrP9dl0KmKCw==",
        "X-Received": "by 10.84.210.7 with SMTP id z7mr14898327plh.371.1505172832739;\n\tMon, 11 Sep 2017 16:33:52 -0700 (PDT)",
        "From": "Cong Wang <xiyou.wangcong@gmail.com>",
        "To": "netdev@vger.kernel.org",
        "Cc": "jiri@mellanox.com, jakub.kicinski@netronome.com, jhs@mojatatu.com,\n\tCong Wang <xiyou.wangcong@gmail.com>",
        "Subject": "[Patch net v3 2/3] net_sched: fix reference counting of tc filter\n\tchain",
        "Date": "Mon, 11 Sep 2017 16:33:31 -0700",
        "Message-Id": "<20170911233332.7594-3-xiyou.wangcong@gmail.com>",
        "X-Mailer": "git-send-email 2.9.4",
        "In-Reply-To": "<20170911233332.7594-1-xiyou.wangcong@gmail.com>",
        "References": "<20170911233332.7594-1-xiyou.wangcong@gmail.com>",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "This patch fixes the following ugliness of tc filter chain refcnt:\n\na) tp proto should hold a refcnt to the chain too. This significantly\n   simplifies the logic.\n\nb) Chain 0 is no longer special, it is created with refcnt=1 like any\n   other chains. All the ugliness in tcf_chain_put() can be gone!\n\nc) No need to handle the flushing oddly, because block still holds\n   chain 0, it can not be released, this guarantees block is the last\n   user.\n\nd) The race condition with RCU callbacks is easier to handle with just\n   a rcu_barrier(). Much easier to understand, nothing to hide. Thanks\n   to the previous patch. Please see also the comments in code.\n\ne) Make the code understandable by humans, much less error-prone.\n\nFixes: 744a4cf63e52 (\"net: sched: fix use after free when tcf_chain_destroy is called multiple times\")\nFixes: 5bc1701881e3 (\"net: sched: introduce multichain support for filters\")\nCc: Jiri Pirko <jiri@mellanox.com>\nCc: Jamal Hadi Salim <jhs@mojatatu.com>\nSigned-off-by: Cong Wang <xiyou.wangcong@gmail.com>\n---\n net/sched/cls_api.c | 47 ++++++++++++++++++++++++++---------------------\n 1 file changed, 26 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c\nindex c743f03cfebd..d29e79d98a69 100644\n--- a/net/sched/cls_api.c\n+++ b/net/sched/cls_api.c\n@@ -182,7 +182,7 @@ static struct tcf_chain *tcf_chain_create(struct tcf_block *block,\n \tlist_add_tail(&chain->list, &block->chain_list);\n \tchain->block = block;\n \tchain->index = chain_index;\n-\tchain->refcnt = 0;\n+\tchain->refcnt = 1;\n \treturn chain;\n }\n \n@@ -194,21 +194,20 @@ static void tcf_chain_flush(struct tcf_chain *chain)\n \t\tRCU_INIT_POINTER(*chain->p_filter_chain, NULL);\n \twhile ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {\n \t\tRCU_INIT_POINTER(chain->filter_chain, tp->next);\n+\t\ttcf_chain_put(chain);\n \t\ttcf_proto_destroy(tp);\n \t}\n }\n \n static void tcf_chain_destroy(struct tcf_chain *chain)\n {\n-\t/* May be already removed from the list by the previous call. */\n-\tif (!list_empty(&chain->list))\n-\t\tlist_del_init(&chain->list);\n+\tlist_del(&chain->list);\n+\tkfree(chain);\n+}\n \n-\t/* There might still be a reference held when we got here from\n-\t * tcf_block_put. Wait for the user to drop reference before free.\n-\t */\n-\tif (!chain->refcnt)\n-\t\tkfree(chain);\n+static void tcf_chain_hold(struct tcf_chain *chain)\n+{\n+\t++chain->refcnt;\n }\n \n struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,\n@@ -217,24 +216,19 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,\n \tstruct tcf_chain *chain;\n \n \tlist_for_each_entry(chain, &block->chain_list, list) {\n-\t\tif (chain->index == chain_index)\n-\t\t\tgoto incref;\n+\t\tif (chain->index == chain_index) {\n+\t\t\ttcf_chain_hold(chain);\n+\t\t\treturn chain;\n+\t\t}\n \t}\n-\tchain = create ? tcf_chain_create(block, chain_index) : NULL;\n \n-incref:\n-\tif (chain)\n-\t\tchain->refcnt++;\n-\treturn chain;\n+\treturn create ? tcf_chain_create(block, chain_index) : NULL;\n }\n EXPORT_SYMBOL(tcf_chain_get);\n \n void tcf_chain_put(struct tcf_chain *chain)\n {\n-\t/* Destroy unused chain, with exception of chain 0, which is the\n-\t * default one and has to be always present.\n-\t */\n-\tif (--chain->refcnt == 0 && !chain->filter_chain && chain->index != 0)\n+\tif (--chain->refcnt == 0)\n \t\ttcf_chain_destroy(chain);\n }\n EXPORT_SYMBOL(tcf_chain_put);\n@@ -279,10 +273,19 @@ void tcf_block_put(struct tcf_block *block)\n \tif (!block)\n \t\treturn;\n \n+\t/* XXX: Standalone actions are not allowed to jump to any chain, and\n+\t * bound actions should be all removed after flushing. However,\n+\t * filters are destroyed in RCU callbacks, we have to flush and wait\n+\t * for them inside the loop, otherwise we race with RCU callbacks on\n+\t * this list.\n+\t */\n \tlist_for_each_entry_safe(chain, tmp, &block->chain_list, list) {\n \t\ttcf_chain_flush(chain);\n-\t\ttcf_chain_destroy(chain);\n+\t\trcu_barrier();\n \t}\n+\n+\tlist_for_each_entry_safe(chain, tmp, &block->chain_list, list)\n+\t\ttcf_chain_put(chain);\n \tkfree(block);\n }\n EXPORT_SYMBOL(tcf_block_put);\n@@ -360,6 +363,7 @@ static void tcf_chain_tp_insert(struct tcf_chain *chain,\n \t\trcu_assign_pointer(*chain->p_filter_chain, tp);\n \tRCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain_info));\n \trcu_assign_pointer(*chain_info->pprev, tp);\n+\ttcf_chain_hold(chain);\n }\n \n static void tcf_chain_tp_remove(struct tcf_chain *chain,\n@@ -371,6 +375,7 @@ static void tcf_chain_tp_remove(struct tcf_chain *chain,\n \tif (chain->p_filter_chain && tp == chain->filter_chain)\n \t\tRCU_INIT_POINTER(*chain->p_filter_chain, next);\n \tRCU_INIT_POINTER(*chain_info->pprev, next);\n+\ttcf_chain_put(chain);\n }\n \n static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,\n",
    "prefixes": [
        "net",
        "v3",
        "2/3"
    ]
}