get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1053,
    "url": "http://patchwork.ozlabs.org/api/patches/1053/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/48D8DC28.1020001@iki.fi/",
    "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": "<48D8DC28.1020001@iki.fi>",
    "list_archive_url": null,
    "date": "2008-09-23T12:08:08",
    "name": "xfrm_state locking regression...",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "38c11aafa06616555d1809453d99940ec419d576",
    "submitter": {
        "id": 393,
        "url": "http://patchwork.ozlabs.org/api/people/393/?format=api",
        "name": "Timo Teras",
        "email": "timo.teras@iki.fi"
    },
    "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/48D8DC28.1020001@iki.fi/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/1053/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1053/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 003C2DDE09\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 23 Sep 2008 22:08:38 +1000 (EST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751279AbYIWMIU (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tTue, 23 Sep 2008 08:08:20 -0400",
            "(majordomo@vger.kernel.org) by vger.kernel.org id S1752539AbYIWMIT\n\t(ORCPT <rfc822; netdev-outgoing>); Tue, 23 Sep 2008 08:08:19 -0400",
            "from ug-out-1314.google.com ([66.249.92.173]:63049 \"EHLO\n\tug-out-1314.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752174AbYIWMIQ (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Tue, 23 Sep 2008 08:08:16 -0400",
            "by ug-out-1314.google.com with SMTP id k3so1590130ugf.37\n\tfor <netdev@vger.kernel.org>; Tue, 23 Sep 2008 05:08:14 -0700 (PDT)",
            "by 10.67.115.3 with SMTP id s3mr664927ugm.68.1222171694560;\n\tTue, 23 Sep 2008 05:08:14 -0700 (PDT)",
            "from ?10.254.3.100? (xdsl-83-150-94-239.nebulazone.fi\n\t[83.150.94.239])\n\tby mx.google.com with ESMTPS id 5sm143327nfv.15.2008.09.23.05.08.12\n\t(version=SSLv3 cipher=RC4-MD5);\n\tTue, 23 Sep 2008 05:08:13 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\n\th=domainkey-signature:received:received:message-id:date:from\n\t:user-agent:mime-version:to:cc:subject:references:in-reply-to\n\t:x-enigmail-version:content-type:content-transfer-encoding:sender;\n\tbh=6fMkbw14DO1x9oOa/RsYfokap19QP2ZSbULjBmbfN8U=;\n\tb=UZhMhm8wgBv63teZiZgiVLJ3zPAplzITo4DdtyJHn2fspKwuV2D8xfTtBrcs09KDfr\n\tPFQJaydKsNQAJijwZgdplh9LyhyT2WmyQSYNVAAtip1ZPjwv8K3Pzqg+AaAJTT3/EPs6\n\tefVnR3FSUO36abjtpzZzKxd/+6RF5dvnGyICo=",
        "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;\n\th=message-id:date:from:user-agent:mime-version:to:cc:subject\n\t:references:in-reply-to:x-enigmail-version:content-type\n\t:content-transfer-encoding:sender;\n\tb=bQt1+jVgg/jc0+98Bb0VSIGW0EiBtdXGb//X8hKg1/1stEPOMwg/bBs7mcrxGL+B/n\n\t5x8mAQJRicafFGyVu1BBxi4qZ0IZs7CmhC9FUxMOc7UFMizHIxSEuQqGR8gUKZ9wIW24\n\t6K6WycCodbnAjxR+H8p8/SBisy3R54g9aqVho=",
        "Message-ID": "<48D8DC28.1020001@iki.fi>",
        "Date": "Tue, 23 Sep 2008 15:08:08 +0300",
        "From": "=?ISO-8859-1?Q?Timo_Ter=E4s?= <timo.teras@iki.fi>",
        "User-Agent": "Thunderbird 2.0.0.16 (X11/20080724)",
        "MIME-Version": "1.0",
        "To": "Herbert Xu <herbert@gondor.apana.org.au>",
        "CC": "David Miller <davem@davemloft.net>, netdev@vger.kernel.org",
        "Subject": "Re: xfrm_state locking regression...",
        "References": "<20080922114256.GA27055@gondor.apana.org.au>\n\t<48D7971A.5050107@iki.fi>\n\t<20080922235012.GA23658@gondor.apana.org.au>\n\t<48D8763E.4030607@iki.fi>\n\t<20080923045951.GA26048@gondor.apana.org.au>\n\t<48D87BDA.8040804@iki.fi>\n\t<20080923052239.GA26233@gondor.apana.org.au>\n\t<48D88BCC.5030806@iki.fi>\n\t<20080923064707.GA26836@gondor.apana.org.au>\n\t<48D8B967.8000107@iki.fi>\n\t<20080923112416.GA28946@gondor.apana.org.au>",
        "In-Reply-To": "<20080923112416.GA28946@gondor.apana.org.au>",
        "X-Enigmail-Version": "0.95.0",
        "Content-Type": "text/plain; charset=ISO-8859-1",
        "Content-Transfer-Encoding": "8bit",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "Herbert Xu wrote:\n> On Tue, Sep 23, 2008 at 12:39:51PM +0300, Timo Teräs wrote:\n>> This would make it possibly to reclaim the deleted entries right\n>> away.\n>>\n>> Does this sound better?\n> \n> Yep this sounds pretty good to me.\n> \n> Thanks,\n\nSo the patch would look something like this. Compile tested.\nWill test later when it becomes possible to reboot my box.\n\nCheers,\n Timo\n\nipsec: Fix up xfrm_state_walk.state on node deletion\n\nNow that we track xfrm_state_walks, it makes more sense to\nfix up the state pointer on deletion of the node if needed.\n\nThis allows accurately to delete all entries immediately,\ninstead of possibly waiting for userland.\n\nAlso fixed locking of xfrm_state_walks list handling.\n\nSigned-off-by: Timo Teras <timo.teras@iki.fi>\n---\n include/linux/netlink.h |    2 +-\n include/net/xfrm.h      |    3 +-\n net/xfrm/xfrm_state.c   |   77 +++++++++++++++++-----------------------------\n 3 files changed, 31 insertions(+), 51 deletions(-)",
    "diff": "diff --git a/include/linux/netlink.h b/include/linux/netlink.h\nindex cbba776..9ff1b54 100644\n--- a/include/linux/netlink.h\n+++ b/include/linux/netlink.h\n@@ -220,7 +220,7 @@ struct netlink_callback\n \tint\t\t(*dump)(struct sk_buff * skb, struct netlink_callback *cb);\n \tint\t\t(*done)(struct netlink_callback *cb);\n \tint\t\tfamily;\n-\tlong\t\targs[7];\n+\tlong\t\targs[6];\n };\n \n struct netlink_notify\ndiff --git a/include/net/xfrm.h b/include/net/xfrm.h\nindex 48630b2..7f787c7 100644\n--- a/include/net/xfrm.h\n+++ b/include/net/xfrm.h\n@@ -122,7 +122,7 @@ struct xfrm_state\n {\n \tstruct list_head\tall;\n \tunion {\n-\t\tstruct list_head\tgclist;\n+\t\tstruct hlist_node\tgclist;\n \t\tstruct hlist_node\tbydst;\n \t};\n \tstruct hlist_node\tbysrc;\n@@ -1247,7 +1247,6 @@ struct xfrm6_tunnel {\n \n struct xfrm_state_walk {\n \tstruct list_head list;\n-\tunsigned long genid;\n \tstruct xfrm_state *state;\n \tint count;\n \tu8 proto;\ndiff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c\nindex 053970e..636f7ee 100644\n--- a/net/xfrm/xfrm_state.c\n+++ b/net/xfrm/xfrm_state.c\n@@ -59,11 +59,6 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;\n static unsigned int xfrm_state_num;\n static unsigned int xfrm_state_genid;\n \n-/* Counter indicating ongoing walk, protected by xfrm_state_lock. */\n-static unsigned long xfrm_state_walk_ongoing;\n-/* Counter indicating walk completion, protected by xfrm_cfg_mutex. */\n-static unsigned long xfrm_state_walk_completed;\n-\n /* List of outstanding state walks used to set the completed counter.  */\n static LIST_HEAD(xfrm_state_walks);\n \n@@ -199,8 +194,7 @@ static DEFINE_RWLOCK(xfrm_state_afinfo_lock);\n static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];\n \n static struct work_struct xfrm_state_gc_work;\n-static LIST_HEAD(xfrm_state_gc_leftovers);\n-static LIST_HEAD(xfrm_state_gc_list);\n+static HLIST_HEAD(xfrm_state_gc_list);\n static DEFINE_SPINLOCK(xfrm_state_gc_lock);\n \n int __xfrm_state_delete(struct xfrm_state *x);\n@@ -412,23 +406,16 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)\n \n static void xfrm_state_gc_task(struct work_struct *data)\n {\n-\tstruct xfrm_state *x, *tmp;\n-\tunsigned long completed;\n+\tstruct xfrm_state *x;\n+\tstruct hlist_node *entry, *tmp;\n+\tstruct hlist_head gc_list;\n \n-\tmutex_lock(&xfrm_cfg_mutex);\n \tspin_lock_bh(&xfrm_state_gc_lock);\n-\tlist_splice_tail_init(&xfrm_state_gc_list, &xfrm_state_gc_leftovers);\n+\thlist_move_list(&xfrm_state_gc_list, &gc_list);\n \tspin_unlock_bh(&xfrm_state_gc_lock);\n \n-\tcompleted = xfrm_state_walk_completed;\n-\tmutex_unlock(&xfrm_cfg_mutex);\n-\n-\tlist_for_each_entry_safe(x, tmp, &xfrm_state_gc_leftovers, gclist) {\n-\t\tif ((long)(x->lastused - completed) > 0)\n-\t\t\tbreak;\n-\t\tlist_del(&x->gclist);\n+\thlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)\n \t\txfrm_state_gc_destroy(x);\n-\t}\n \n \twake_up(&km_waitq);\n }\n@@ -556,7 +543,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)\n \tWARN_ON(x->km.state != XFRM_STATE_DEAD);\n \n \tspin_lock_bh(&xfrm_state_gc_lock);\n-\tlist_add_tail(&x->gclist, &xfrm_state_gc_list);\n+\thlist_add_head(&x->gclist, &xfrm_state_gc_list);\n \tspin_unlock_bh(&xfrm_state_gc_lock);\n \tschedule_work(&xfrm_state_gc_work);\n }\n@@ -564,13 +551,22 @@ EXPORT_SYMBOL(__xfrm_state_destroy);\n \n int __xfrm_state_delete(struct xfrm_state *x)\n {\n+\tstruct xfrm_state_walk *walk;\n+\tstruct xfrm_state *next;\n \tint err = -ESRCH;\n \n \tif (x->km.state != XFRM_STATE_DEAD) {\n \t\tx->km.state = XFRM_STATE_DEAD;\n \t\tspin_lock(&xfrm_state_lock);\n-\t\tx->lastused = xfrm_state_walk_ongoing;\n-\t\tlist_del_rcu(&x->all);\n+\t\tif (list_is_last(&x->all, &xfrm_state_walks))\n+\t\t\tnext = NULL;\n+\t\telse\n+\t\t\tnext = container_of(x->all.next, struct xfrm_state, all);\n+\t\tlist_for_each_entry(walk, &xfrm_state_walks, list) {\n+\t\t\tif (walk->state == x)\n+\t\t\t\twalk->state = next;\n+\t\t}\n+\t\tlist_del(&x->all);\n \t\thlist_del(&x->bydst);\n \t\thlist_del(&x->bysrc);\n \t\tif (x->id.spi)\n@@ -1566,15 +1562,16 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,\n \t\t    int (*func)(struct xfrm_state *, int, void*),\n \t\t    void *data)\n {\n-\tstruct xfrm_state *old, *x, *last = NULL;\n+\tstruct xfrm_state *x, *last = NULL;\n \tint err = 0;\n \n \tif (walk->state == NULL && walk->count != 0)\n \t\treturn 0;\n \n-\told = x = walk->state;\n-\twalk->state = NULL;\n \tspin_lock_bh(&xfrm_state_lock);\n+\tx = walk->state;\n+\twalk->state = NULL;\n+\n \tif (x == NULL)\n \t\tx = list_first_entry(&xfrm_state_all, struct xfrm_state, all);\n \tlist_for_each_entry_from(x, &xfrm_state_all, all) {\n@@ -1585,7 +1582,6 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,\n \t\tif (last) {\n \t\t\terr = func(last, walk->count, data);\n \t\t\tif (err) {\n-\t\t\t\txfrm_state_hold(last);\n \t\t\t\twalk->state = last;\n \t\t\t\tgoto out;\n \t\t\t}\n@@ -1601,8 +1597,7 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,\n \t\terr = func(last, 0, data);\n out:\n \tspin_unlock_bh(&xfrm_state_lock);\n-\tif (old != NULL)\n-\t\txfrm_state_put(old);\n+\n \treturn err;\n }\n EXPORT_SYMBOL(xfrm_state_walk);\n@@ -1612,33 +1607,19 @@ void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)\n \twalk->proto = proto;\n \twalk->state = NULL;\n \twalk->count = 0;\n+\n+\tspin_lock_bh(&xfrm_state_lock);\n \tlist_add_tail(&walk->list, &xfrm_state_walks);\n-\twalk->genid = ++xfrm_state_walk_ongoing;\n+\tspin_unlock_bh(&xfrm_state_lock);\n }\n EXPORT_SYMBOL(xfrm_state_walk_init);\n \n void xfrm_state_walk_done(struct xfrm_state_walk *walk)\n {\n-\tstruct list_head *prev;\n-\n-\tif (walk->state != NULL) {\n-\t\txfrm_state_put(walk->state);\n-\t\twalk->state = NULL;\n-\t}\n-\n-\tprev = walk->list.prev;\n+\tspin_lock_bh(&xfrm_state_lock);\n \tlist_del(&walk->list);\n-\n-\tif (prev != &xfrm_state_walks) {\n-\t\tlist_entry(prev, struct xfrm_state_walk, list)->genid =\n-\t\t\twalk->genid;\n-\t\treturn;\n-\t}\n-\n-\txfrm_state_walk_completed = walk->genid;\n-\n-\tif (!list_empty(&xfrm_state_gc_leftovers))\n-\t\tschedule_work(&xfrm_state_gc_work);\n+\tspin_unlock_bh(&xfrm_state_lock);\n+\twalk->state = NULL;\n }\n EXPORT_SYMBOL(xfrm_state_walk_done);\n \n",
    "prefixes": []
}