get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2225240,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2225240/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260420165539.85174-2-ja@ssi.bg/",
    "project": {
        "id": 26,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/26/?format=api",
        "name": "Netfilter Development",
        "link_name": "netfilter-devel",
        "list_id": "netfilter-devel.vger.kernel.org",
        "list_email": "netfilter-devel@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260420165539.85174-2-ja@ssi.bg>",
    "date": "2026-04-20T16:55:37",
    "name": "[PATCHv2,net,1/3] ipvs: fixes for the new ip_vs_status info",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "1cdb83e93b264fd2df404220e9ccc75f2888c8ce",
    "submitter": {
        "id": 2825,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/2825/?format=api",
        "name": "Julian Anastasov",
        "email": "ja@ssi.bg"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260420165539.85174-2-ja@ssi.bg/mbox/",
    "series": [
        {
            "id": 500642,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/500642/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/list/?series=500642",
            "date": "2026-04-20T16:55:36",
            "name": "IPVS: fixes after the new hash tables",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/500642/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2225240/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2225240/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <netfilter-devel+bounces-12069-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "netfilter-devel@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (4096-bit key;\n unprotected) header.d=ssi.bg header.i=@ssi.bg header.a=rsa-sha256\n header.s=ssi header.b=VhtWvqvc;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-12069-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (4096-bit key) header.d=ssi.bg header.i=@ssi.bg header.b=\"VhtWvqvc\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=193.238.174.39",
            "smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=ssi.bg",
            "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=ssi.bg"
        ],
        "Received": [
            "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fzsYS6tpgz1yD4\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 03:14:52 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 04E7E316B6AC\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 16:59:21 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 6034032B9B6;\n\tMon, 20 Apr 2026 16:59:20 +0000 (UTC)",
            "from mx.ssi.bg (mx.ssi.bg [193.238.174.39])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id BDF4F184524;\n\tMon, 20 Apr 2026 16:59:16 +0000 (UTC)",
            "from mx.ssi.bg (localhost [127.0.0.1])\n\tby mx.ssi.bg (Potsfix) with ESMTP id 85FA42110F;\n\tMon, 20 Apr 2026 19:59:07 +0300 (EEST)",
            "from box.ssi.bg (box.ssi.bg [193.238.174.46])\n\tby mx.ssi.bg (Potsfix) with ESMTPS;\n\tMon, 20 Apr 2026 19:59:05 +0300 (EEST)",
            "from ja.ssi.bg (unknown [213.16.62.126])\n\tby box.ssi.bg (Potsfix) with ESMTPSA id AF91F60821;\n\tMon, 20 Apr 2026 19:59:05 +0300 (EEST)",
            "from ja.home.ssi.bg (localhost.localdomain [127.0.0.1])\n\tby ja.ssi.bg (8.18.1/8.18.1) with ESMTP id 63KGu4d3085556;\n\tMon, 20 Apr 2026 19:56:04 +0300",
            "(from root@localhost)\n\tby ja.home.ssi.bg (8.18.1/8.18.1/Submit) id 63KGu49J085555;\n\tMon, 20 Apr 2026 19:56:04 +0300"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776704358; cv=none;\n b=UW4cDvKrktXnXCNSG/4WwsevTRaFnhkLfDcm2WmMkQf5KTFJAvnHTm63GeqVBwHgzCK/xBOqKKbyOyTnuEmsEa0wjS+PSHScVLype9Ti7KGaFhaC//r5I9w4f70Hq4ZW5bVEqG56J0Z3pDG4d3VSTUwm79Yng/rIpFEfayyyKUw=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776704358; c=relaxed/simple;\n\tbh=F4lUGPMdS/bvoUN+XN4+UZKi3zTbHNgMNCrxglybtcU=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=qaZRHvabpG/O1uOVuWeFisffujjX5fFMpoJ6M8RdvPjrP/aqv+DR9eMmIyi+g1CYiktSVWa04MKiyyyTnEpGHHA5czpAAkmCqUGwASkzly7ovXcDyTrqdGDII5vbQMeTtHHHyenmfh5Md9x4OpTLsdxG0c8eSrMxbtbCmRuBQ6E=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=ssi.bg;\n spf=pass smtp.mailfrom=ssi.bg;\n dkim=pass (4096-bit key) header.d=ssi.bg header.i=@ssi.bg header.b=VhtWvqvc;\n arc=none smtp.client-ip=193.238.174.39",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=ssi.bg; h=cc:cc\n\t:content-transfer-encoding:date:from:from:in-reply-to:message-id\n\t:mime-version:references:reply-to:subject:subject:to:to; s=ssi;\n\t bh=gsAvRDH20KwST110vB0xZmQ42TWjJ6vjg6gG+LolkGU=; b=VhtWvqvcUPPr\n\tYPcsoZRd9psUzwjnuqvrRWmrFKmXwHn2MjMMRoyTaugE+EpImnRaUUw5TuT1ZhwP\n\t4fbAE8wEOvhof8x473TVmPASz5hjuLBbheIl/FJ1vdCVHY59JOegWdb4Y2/4P37A\n\tgsQ1CfucrzxOA+UecrevtEhT6ZrOpvRfhHn9VsK0pVEQHo3nxm7RV5/RCX3nbBxE\n\tBreIuz/k9+KuaTQ/Q8A4bWtRnZRcg5AN3Tb4OHY5JTn52nadkRbNIE0moilrA3Rc\n\tp98c6cEbrpTvfn1szqsUrlQmZc8UMhk+IYOFl9MzRQ8NlJ4Doo7Eqhi+ybnGuf83\n\ttwSpK7qIMQ/jupETDkonUqteWS2Dto7YoTq4JUZ1RZ9hN75Yfmon1fHhLyfe14oE\n\tLj7V6fxvmBfIsPXlptKDYBTTnjTTV6Tf4cE7mQBXHfuV7Qz69I1xuAja+uaEFKnB\n\tUPKu1MsmDCnO27h+DdPvRufp+c/RE2jKzVTPfTQhPPPwr3QeKC1+ndjBcLYj276/\n\tetynq1dcLCtefoLCEiGYhdoTBImXMJGJMVnGJM21mW/95+y3o0qY/a41NaDaJCzm\n\tpfr91dYjcipJLQrTD1YOXNG0vpbcIg7IWcqg9ICozORIASS/vl1dtgfwshOgpeqN\n\tBWRkoYYBV092lubmGokhjs3tLQGdDbg=",
        "From": "Julian Anastasov <ja@ssi.bg>",
        "To": "Simon Horman <horms@verge.net.au>",
        "Cc": "Pablo Neira Ayuso <pablo@netfilter.org>, Florian Westphal <fw@strlen.de>,\n        lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org",
        "Subject": "[PATCHv2 net 1/3] ipvs: fixes for the new ip_vs_status info",
        "Date": "Mon, 20 Apr 2026 19:55:37 +0300",
        "Message-ID": "<20260420165539.85174-2-ja@ssi.bg>",
        "X-Mailer": "git-send-email 2.53.0",
        "In-Reply-To": "<20260420165539.85174-1-ja@ssi.bg>",
        "References": "<20260420165539.85174-1-ja@ssi.bg>",
        "Precedence": "bulk",
        "X-Mailing-List": "netfilter-devel@vger.kernel.org",
        "List-Id": "<netfilter-devel.vger.kernel.org>",
        "List-Subscribe": "<mailto:netfilter-devel+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:netfilter-devel+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "Sashiko reports some problems for the recently added\n/proc/net/ip_vs_status:\n\n* ip_vs_status_show() as a table reader may run long after the\nconn_tab and svc_table table are released. While ip_vs_conn_flush()\nproperly changes the conn_tab_changes counter when conn_tab is removed,\nip_vs_del_service() and ip_vs_flush() were missing such change for\nthe svc_table_changes counter. As result, readers like\nip_vs_dst_event() and ip_vs_status_show() may continue to use\na freed table after a cond_resched_rcu() call.\n\n* While counting the buckets in ip_vs_status_show() make sure we\ntraverse only the needed number of entries in the chain. This also\nprevents possible overflow of the 'count' variable.\n\n* Add check for 'loops' to prevent infinite loops while restarting\nthe traversal on table change.\n\n* While IP_VS_CONN_TAB_MAX_BITS is 20 on 32-bit platforms and\nthere is no risk to overflow when multiplying the number of\nconn_tab buckets to 100, prefer the div_u64() helper to make\nthe following dividing safer.\n\n* Use 0440 permissions for ip_vs_status to restrict the\ninfo only to root due to the exported information for hash\ndistribution.\n\nLink: https://sashiko.dev/#/patchset/20260410112352.23599-1-fw%40strlen.de\nSigned-off-by: Julian Anastasov <ja@ssi.bg>\n---\n net/netfilter/ipvs/ip_vs_ctl.c | 51 ++++++++++++++++++++++++----------\n 1 file changed, 36 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c\nindex 6632daa87ded..27e50afe9a54 100644\n--- a/net/netfilter/ipvs/ip_vs_ctl.c\n+++ b/net/netfilter/ipvs/ip_vs_ctl.c\n@@ -2032,6 +2032,9 @@ static int ip_vs_del_service(struct ip_vs_service *svc)\n \t\tcancel_delayed_work_sync(&ipvs->svc_resize_work);\n \t\tif (t) {\n \t\t\trcu_assign_pointer(ipvs->svc_table, NULL);\n+\t\t\t/* Inform readers that table is removed */\n+\t\t\tsmp_mb__before_atomic();\n+\t\t\tatomic_inc(&ipvs->svc_table_changes);\n \t\t\twhile (1) {\n \t\t\t\tp = rcu_dereference_protected(t->new_tbl, 1);\n \t\t\t\tcall_rcu(&t->rcu_head, ip_vs_rht_rcu_free);\n@@ -2078,6 +2081,9 @@ static int ip_vs_flush(struct netns_ipvs *ipvs, bool cleanup)\n \tt = rcu_dereference_protected(ipvs->svc_table, 1);\n \tif (t) {\n \t\trcu_assign_pointer(ipvs->svc_table, NULL);\n+\t\t/* Inform readers that table is removed */\n+\t\tsmp_mb__before_atomic();\n+\t\tatomic_inc(&ipvs->svc_table_changes);\n \t\twhile (1) {\n \t\t\tp = rcu_dereference_protected(t->new_tbl, 1);\n \t\t\tcall_rcu(&t->rcu_head, ip_vs_rht_rcu_free);\n@@ -3004,7 +3010,8 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \tint old_gen, new_gen;\n \tu32 counts[8];\n \tu32 bucket;\n-\tint count;\n+\tu32 count;\n+\tint loops;\n \tu32 sum1;\n \tu32 sum;\n \tint i;\n@@ -3020,6 +3027,7 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \tif (!atomic_read(&ipvs->conn_count))\n \t\tgoto after_conns;\n \told_gen = atomic_read(&ipvs->conn_tab_changes);\n+\tloops = 0;\n \n repeat_conn:\n \tsmp_rmb(); /* ipvs->conn_tab and conn_tab_changes */\n@@ -3032,8 +3040,11 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \t\t\tresched_score++;\n \t\t\tip_vs_rht_walk_bucket_rcu(t, bucket, head) {\n \t\t\t\tcount = 0;\n-\t\t\t\thlist_bl_for_each_entry_rcu(hn, e, head, node)\n+\t\t\t\thlist_bl_for_each_entry_rcu(hn, e, head, node) {\n \t\t\t\t\tcount++;\n+\t\t\t\t\tif (count >= ARRAY_SIZE(counts) - 1)\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t}\n \t\t\t}\n \t\t\tresched_score += count;\n \t\t\tif (resched_score >= 100) {\n@@ -3042,37 +3053,41 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \t\t\t\tnew_gen = atomic_read(&ipvs->conn_tab_changes);\n \t\t\t\t/* New table installed ? */\n \t\t\t\tif (old_gen != new_gen) {\n+\t\t\t\t\t/* Too many changes? */\n+\t\t\t\t\tif (++loops >= 5)\n+\t\t\t\t\t\tgoto after_conns;\n \t\t\t\t\told_gen = new_gen;\n \t\t\t\t\tgoto repeat_conn;\n \t\t\t\t}\n \t\t\t}\n-\t\t\tcounts[min(count, (int)ARRAY_SIZE(counts) - 1)]++;\n+\t\t\tcounts[count]++;\n \t\t}\n \t}\n \tfor (sum = 0, i = 0; i < ARRAY_SIZE(counts); i++)\n \t\tsum += counts[i];\n \tsum1 = sum - counts[0];\n-\tseq_printf(seq, \"Conn buckets empty:\\t%u (%lu%%)\\n\",\n-\t\t   counts[0], (unsigned long)counts[0] * 100 / max(sum, 1U));\n+\tseq_printf(seq, \"Conn buckets empty:\\t%u (%llu%%)\\n\",\n+\t\t   counts[0], div_u64((u64)counts[0] * 100U, max(sum, 1U)));\n \tfor (i = 1; i < ARRAY_SIZE(counts); i++) {\n \t\tif (!counts[i])\n \t\t\tcontinue;\n-\t\tseq_printf(seq, \"Conn buckets len-%d:\\t%u (%lu%%)\\n\",\n+\t\tseq_printf(seq, \"Conn buckets len-%d:\\t%u (%llu%%)\\n\",\n \t\t\t   i, counts[i],\n-\t\t\t   (unsigned long)counts[i] * 100 / max(sum1, 1U));\n+\t\t\t   div_u64((u64)counts[i] * 100U, max(sum1, 1U)));\n \t}\n \n after_conns:\n \tt = rcu_dereference(ipvs->svc_table);\n \n \tcount = ip_vs_get_num_services(ipvs);\n-\tseq_printf(seq, \"Services:\\t%d\\n\", count);\n+\tseq_printf(seq, \"Services:\\t%u\\n\", count);\n \tseq_printf(seq, \"Service buckets:\\t%d (%d bits, lfactor %d)\\n\",\n \t\t   t ? t->size : 0, t ? t->bits : 0, t ? t->lfactor : 0);\n \n \tif (!count)\n \t\tgoto after_svc;\n \told_gen = atomic_read(&ipvs->svc_table_changes);\n+\tloops = 0;\n \n repeat_svc:\n \tsmp_rmb(); /* ipvs->svc_table and svc_table_changes */\n@@ -3086,8 +3101,11 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \t\t\tip_vs_rht_walk_bucket_rcu(t, bucket, head) {\n \t\t\t\tcount = 0;\n \t\t\t\thlist_bl_for_each_entry_rcu(svc, e, head,\n-\t\t\t\t\t\t\t    s_list)\n+\t\t\t\t\t\t\t    s_list) {\n \t\t\t\t\tcount++;\n+\t\t\t\t\tif (count >= ARRAY_SIZE(counts) - 1)\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t}\n \t\t\t}\n \t\t\tresched_score += count;\n \t\t\tif (resched_score >= 100) {\n@@ -3096,24 +3114,27 @@ static int ip_vs_status_show(struct seq_file *seq, void *v)\n \t\t\t\tnew_gen = atomic_read(&ipvs->svc_table_changes);\n \t\t\t\t/* New table installed ? */\n \t\t\t\tif (old_gen != new_gen) {\n+\t\t\t\t\t/* Too many changes? */\n+\t\t\t\t\tif (++loops >= 5)\n+\t\t\t\t\t\tgoto after_svc;\n \t\t\t\t\told_gen = new_gen;\n \t\t\t\t\tgoto repeat_svc;\n \t\t\t\t}\n \t\t\t}\n-\t\t\tcounts[min(count, (int)ARRAY_SIZE(counts) - 1)]++;\n+\t\t\tcounts[count]++;\n \t\t}\n \t}\n \tfor (sum = 0, i = 0; i < ARRAY_SIZE(counts); i++)\n \t\tsum += counts[i];\n \tsum1 = sum - counts[0];\n-\tseq_printf(seq, \"Service buckets empty:\\t%u (%lu%%)\\n\",\n-\t\t   counts[0], (unsigned long)counts[0] * 100 / max(sum, 1U));\n+\tseq_printf(seq, \"Service buckets empty:\\t%u (%llu%%)\\n\",\n+\t\t   counts[0], div_u64((u64)counts[0] * 100U, max(sum, 1U)));\n \tfor (i = 1; i < ARRAY_SIZE(counts); i++) {\n \t\tif (!counts[i])\n \t\t\tcontinue;\n-\t\tseq_printf(seq, \"Service buckets len-%d:\\t%u (%lu%%)\\n\",\n+\t\tseq_printf(seq, \"Service buckets len-%d:\\t%u (%llu%%)\\n\",\n \t\t\t   i, counts[i],\n-\t\t\t   (unsigned long)counts[i] * 100 / max(sum1, 1U));\n+\t\t\t   div_u64((u64)counts[i] * 100U, max(sum1, 1U)));\n \t}\n \n after_svc:\n@@ -5039,7 +5060,7 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs)\n \t\t\t\t    ipvs->net->proc_net,\n \t\t\t\t    ip_vs_stats_percpu_show, NULL))\n \t\tgoto err_percpu;\n-\tif (!proc_create_net_single(\"ip_vs_status\", 0, ipvs->net->proc_net,\n+\tif (!proc_create_net_single(\"ip_vs_status\", 0440, ipvs->net->proc_net,\n \t\t\t\t    ip_vs_status_show, NULL))\n \t\tgoto err_status;\n #endif\n",
    "prefixes": [
        "PATCHv2",
        "net",
        "1/3"
    ]
}