Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2194815/?format=api
{ "id": 2194815, "url": "http://patchwork.ozlabs.org/api/patches/2194815/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260210014702.3126-3-gerald.yang@canonical.com/", "project": { "id": 15, "url": "http://patchwork.ozlabs.org/api/projects/15/?format=api", "name": "Ubuntu Kernel", "link_name": "ubuntu-kernel", "list_id": "kernel-team.lists.ubuntu.com", "list_email": "kernel-team@lists.ubuntu.com", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260210014702.3126-3-gerald.yang@canonical.com>", "list_archive_url": null, "date": "2026-02-10T01:46:57", "name": "[SRU,N,2/2] netfilter: conntrack: rework offload nf_conn timeout extension logic", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "08d5f169846eaa02cfd7e251a69c8720a51ec8eb", "submitter": { "id": 77781, "url": "http://patchwork.ozlabs.org/api/people/77781/?format=api", "name": "Gerald Yang", "email": "gerald.yang@canonical.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/ubuntu-kernel/patch/20260210014702.3126-3-gerald.yang@canonical.com/mbox/", "series": [ { "id": 491588, "url": "http://patchwork.ozlabs.org/api/series/491588/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ubuntu-kernel/list/?series=491588", "date": "2026-02-10T01:46:56", "name": "[SRU,N,1/2] netfilter: conntrack: remove skb argument from nf_ct_refresh", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/491588/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2194815/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2194815/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<kernel-team-bounces@lists.ubuntu.com>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (4096-bit key;\n unprotected) header.d=canonical.com header.i=@canonical.com\n header.a=rsa-sha256 header.s=20251003 header.b=CSAsfrrm;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com\n (client-ip=185.125.189.65; helo=lists.ubuntu.com;\n envelope-from=kernel-team-bounces@lists.ubuntu.com;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f94F96hr3z1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 12:47:25 +1100 (AEDT)", "from localhost ([127.0.0.1] helo=lists.ubuntu.com)\n\tby lists.ubuntu.com with esmtp (Exim 4.86_2)\n\t(envelope-from <kernel-team-bounces@lists.ubuntu.com>)\n\tid 1vpcqQ-00071l-I8; Tue, 10 Feb 2026 01:47:14 +0000", "from smtp-relay-internal-1.internal ([10.131.114.114]\n helo=smtp-relay-internal-1.canonical.com)\n by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.86_2) (envelope-from <gerald.yang@canonical.com>)\n id 1vpcqO-00070w-Vw\n for kernel-team@lists.ubuntu.com; Tue, 10 Feb 2026 01:47:13 +0000", "from mail-pg1-f200.google.com (mail-pg1-f200.google.com\n [209.85.215.200])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id C8BFF3F181\n for <kernel-team@lists.ubuntu.com>; Tue, 10 Feb 2026 01:47:12 +0000 (UTC)", "by mail-pg1-f200.google.com with SMTP id\n 41be03b00d2f7-c6dde310601so1811993a12.1\n for <kernel-team@lists.ubuntu.com>; Mon, 09 Feb 2026 17:47:12 -0800 (PST)", "from noble-c.lxd (118-163-61-247.hinet-ip.hinet.net.\n [118.163.61.247]) by smtp.gmail.com with ESMTPSA id\n 41be03b00d2f7-c6dcb5e5f98sm12200413a12.17.2026.02.09.17.47.08\n for <kernel-team@lists.ubuntu.com>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 09 Feb 2026 17:47:09 -0800 (PST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com;\n s=20251003; t=1770688032;\n bh=BYLmFcJI3YgGHi9vP+3d99J72MNs00u9jL0PhvTfLRk=;\n h=From:To:Subject:Date:Message-ID:In-Reply-To:References:\n MIME-Version;\n b=CSAsfrrmQ1REMC2YDgW0JCiDlveEgOf5O43QSBJN7c0tQIQdl9NE7FWeaeGWC+2MU\n 1x6wNir8/89wv6C0phrMBgLIDb88bNu7r4RIzx7rofY1ehveDd30KNqZm3Ga7UODQ1\n MZ7LY6XW2BKQ7/JeQhMqKJ3iyeNpjHrRkkQ1azExFe+Z6ILvfCU6HEyuWxjTsAI34w\n HTJ91LIYOBZT/OtxflEemMAsIjhvYr6CLp8JQ0naVa4clvGC/L4jxi/4Y9aqqZKvhv\n eK93xdlKkAVbJ+tOaeoFn9btPz+mrNE6FD5xgoiF83XZx5BHjVZ8BiNOdtwVu70ZFg\n fzWfbmvJudzW3TUb++SOroZVkpF9LsGQqFtpj5rIO3Oc5rzU1rK7na2yD+nEtdfUA7\n KF3PZq6lIltK/absx2kfVA89aOAJ6J1aV9YHb5YCrzkvCu6O6sG12266STLbuuf7Lh\n 98HL+u6WJNUOvzVJWrz9sJerbMHUTZmZkkMse7bEPUK0OXGYfoMGBxE1R4chr39MIL\n GI0OETgIAlhjm1GDVddJ0tEYc4Iwq+/EUg+oXYcA2Fka/bXaXygMaJiOlZnCpygrF0\n SV2Bd7Zi8UcH5KKQfxAGtsaId2w0yVpJDmTQ/ytOA+62y7JIOOKizlwC0gn8lkGHOW\n 0EH0QKwkOTlPFIu9z5PF/IsY=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1770688031; x=1771292831;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=BYLmFcJI3YgGHi9vP+3d99J72MNs00u9jL0PhvTfLRk=;\n b=lDwYDcrklRZcZcMGNlmEMAOc/xM5ks6KtIo9E8LuSuikXL0GnG4RTD7B3bmcTH/nFo\n Bu/fqzSXLfsVQ1qOMc62yeHlk2v5xc1O8gONmYTQLWk6RLtHAD4rNTb/f6+zedlB9bFr\n UNK68nOVVE4tp+/CqdjHmZIcxJ67hfJ4udrLdZk89fFC3pT4G77Oefek2vcyu2BT1QBz\n gzd0jL+Z2oBB8A1LkvyPheRiA3ry0OZpqk2B06WLxhPfDr/Sgg+fQfKH3NDxG/Vmb4xj\n 7jmyjeo/9luGzTcW/l3HTzTPhFrMosiI0HYMbQbqYjce76PJLT+a6+kyDqQbWLjyFDMl\n cPjw==", "X-Gm-Message-State": "AOJu0Yw2QNYc3lyevpHRaiAUXxwtTO6FciYp6WWDnlB0wbkVhGWjc69Z\n wgtpnz+NcNHPr8RLsT9NNdplDt4wD0MJLaycrjWCx29501sC3pQflDzE2Ff3kBrbCb3MYbw9N7i\n O3XTC0vAci5yNNA3pMIKQOZkRtp8fnE3WJH3MmUICIOWElLCcw+Pz0jKXcoX2+vGkbQZuadrx0J\n QIGYI1zEU08d9Yaw==", "X-Gm-Gg": "AZuq6aK7NcS3rQazCp3Q13bLfT+JZMzDmqdW9P302QPopCw4rccJ9rXFNFH9ovUEBe+\n oCQQ7DewlfbHYk0Asa1/89j4b/m8bP/xpSW5WVBVhJMxOM9sL+3jlSI0Q6ZRLH07ScRWvmrQdko\n Rejhx85HbIQ/IPrIovwNQQj+jbWd7Q2B7BSIDiMg1DaPKftJPMkgs/YEkdzv5r4OMpmoR9oIdZ5\n U8FF9w0jz+1SjALHnz96OF7lpNab2BinaXZYPNEv8Pq9OgYZsME4GEY3nHxwT0N2NYAWUxCBYtM\n zVbWgst6Y47TwNOFtvpOsUn4RYD3VB7IrKNt5fr9K1bi8PY99YPV8Wqdbc0hoer/XN/nUpojEWi\n LrqhESOXq3C+n309sdb4D8ROQhb4PYVgeAnHIcZsI2z2iUK8z4tWOIUxHn1T9s6TWFA==", "X-Received": [ "by 2002:a05:6a21:a4a:b0:366:1880:7e06 with SMTP id\n adf61e73a8af0-393aea9ea9bmr13155078637.0.1770688030713;\n Mon, 09 Feb 2026 17:47:10 -0800 (PST)", "by 2002:a05:6a21:a4a:b0:366:1880:7e06 with SMTP id\n adf61e73a8af0-393aea9ea9bmr13155047637.0.1770688030219;\n Mon, 09 Feb 2026 17:47:10 -0800 (PST)" ], "From": "Gerald Yang <gerald.yang@canonical.com>", "To": "kernel-team@lists.ubuntu.com", "Subject": "[SRU][N][PATCH 2/2] netfilter: conntrack: rework offload nf_conn\n timeout extension logic", "Date": "Tue, 10 Feb 2026 01:46:57 +0000", "Message-ID": "<20260210014702.3126-3-gerald.yang@canonical.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260210014702.3126-1-gerald.yang@canonical.com>", "References": "<20260210014702.3126-1-gerald.yang@canonical.com>", "MIME-Version": "1.0", "X-BeenThere": "kernel-team@lists.ubuntu.com", "X-Mailman-Version": "2.1.20", "Precedence": "list", "List-Id": "Kernel team discussions <kernel-team.lists.ubuntu.com>", "List-Unsubscribe": "<https://lists.ubuntu.com/mailman/options/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=unsubscribe>", "List-Archive": "<https://lists.ubuntu.com/archives/kernel-team>", "List-Post": "<mailto:kernel-team@lists.ubuntu.com>", "List-Help": "<mailto:kernel-team-request@lists.ubuntu.com?subject=help>", "List-Subscribe": "<https://lists.ubuntu.com/mailman/listinfo/kernel-team>,\n <mailto:kernel-team-request@lists.ubuntu.com?subject=subscribe>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "kernel-team-bounces@lists.ubuntu.com", "Sender": "\"kernel-team\" <kernel-team-bounces@lists.ubuntu.com>" }, "content": "From: Florian Westphal <fw@strlen.de>\n\nBugLink: https://bugs.launchpad.net/bugs/2139322\n\nOffload nf_conn entries may not see traffic for a very long time.\n\nTo prevent incorrect 'ct is stale' checks during nf_conntrack table\nlookup, the gc worker extends the timeout nf_conn entries marked for\noffload to a large value.\n\nThe existing logic suffers from a few problems.\n\nGarbage collection runs without locks, its unlikely but possible\nthat @ct is removed right after the 'offload' bit test.\n\nIn that case, the timeout of a new/reallocated nf_conn entry will\nbe increased.\n\nPrevent this by obtaining a reference count on the ct object and\nre-check of the confirmed and offload bits.\n\nIf those are not set, the ct is being removed, skip the timeout\nextension in this case.\n\nParallel teardown is also problematic:\n cpu1 cpu2\n gc_worker\n calls flow_offload_teardown()\n tests OFFLOAD bit, set\n clear OFFLOAD bit\n ct->timeout is repaired (e.g. set to timeout[UDP_CT_REPLIED])\n nf_ct_offload_timeout() called\n expire value is fetched\n <INTERRUPT>\n-> NF_CT_DAY timeout for flow that isn't offloaded\n(and might not see any further packets).\n\nUse cmpxchg: if ct->timeout was repaired after the 2nd 'offload bit' test\npassed, then ct->timeout will only be updated of ct->timeout was not\naltered in between.\n\nAs we already have a gc worker for flowtable entries, ct->timeout repair\ncan be handled from the flowtable gc worker.\n\nThis avoids having flowtable specific logic in the conntrack core\nand avoids checking entries that were never offloaded.\n\nThis allows to remove the nf_ct_offload_timeout helper.\nIts safe to use in the add case, but not on teardown.\n\nSigned-off-by: Florian Westphal <fw@strlen.de>\nSigned-off-by: Pablo Neira Ayuso <pablo@netfilter.org>\n(cherry picked from commit 03428ca5cee9f0792edc996c06ce4514816af1fb)\nSigned-off-by: Gerald Yang <gerald.yang@canonical.com>\n---\n include/net/netfilter/nf_conntrack.h | 10 ---\n net/netfilter/nf_conntrack_core.c | 6 --\n net/netfilter/nf_flow_table_core.c | 105 ++++++++++++++++++++++++++-\n 3 files changed, 103 insertions(+), 18 deletions(-)", "diff": "diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h\nindex a85051121af8..ca26274196b9 100644\n--- a/include/net/netfilter/nf_conntrack.h\n+++ b/include/net/netfilter/nf_conntrack.h\n@@ -323,16 +323,6 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)\n \n #define\tNF_CT_DAY\t(86400 * HZ)\n \n-/* Set an arbitrary timeout large enough not to ever expire, this save\n- * us a check for the IPS_OFFLOAD_BIT from the packet path via\n- * nf_ct_is_expired().\n- */\n-static inline void nf_ct_offload_timeout(struct nf_conn *ct)\n-{\n-\tif (nf_ct_expires(ct) < NF_CT_DAY / 2)\n-\t\tWRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);\n-}\n-\n struct kernel_param;\n \n int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp);\ndiff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c\nindex 299987f306c6..fd0f6397da9d 100644\n--- a/net/netfilter/nf_conntrack_core.c\n+++ b/net/netfilter/nf_conntrack_core.c\n@@ -1514,12 +1514,6 @@ static void gc_worker(struct work_struct *work)\n \n \t\t\ttmp = nf_ct_tuplehash_to_ctrack(h);\n \n-\t\t\tif (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) {\n-\t\t\t\tnf_ct_offload_timeout(tmp);\n-\t\t\t\tif (!nf_conntrack_max95)\n-\t\t\t\t\tcontinue;\n-\t\t\t}\n-\n \t\t\tif (expired_count > GC_SCAN_EXPIRED_MAX) {\n \t\t\t\trcu_read_unlock();\n \ndiff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c\nindex 5c1ff07eaee0..96f29f80d1bd 100644\n--- a/net/netfilter/nf_flow_table_core.c\n+++ b/net/netfilter/nf_flow_table_core.c\n@@ -294,7 +294,7 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)\n \t\treturn err;\n \t}\n \n-\tnf_ct_offload_timeout(flow->ct);\n+\tnf_ct_refresh(flow->ct, NF_CT_DAY);\n \n \tif (nf_flowtable_hw_offload(flow_table)) {\n \t\t__set_bit(NF_FLOW_HW, &flow->flags);\n@@ -414,15 +414,116 @@ static bool nf_flow_custom_gc(struct nf_flowtable *flow_table,\n \treturn flow_table->type->gc && flow_table->type->gc(flow);\n }\n \n+/**\n+ * nf_flow_table_tcp_timeout() - new timeout of offloaded tcp entry\n+ * @ct:\t\tFlowtable offloaded tcp ct\n+ *\n+ * Return: number of seconds when ct entry should expire.\n+ */\n+static u32 nf_flow_table_tcp_timeout(const struct nf_conn *ct)\n+{\n+\tu8 state = READ_ONCE(ct->proto.tcp.state);\n+\n+\tswitch (state) {\n+\tcase TCP_CONNTRACK_SYN_SENT:\n+\tcase TCP_CONNTRACK_SYN_RECV:\n+\t\treturn 0;\n+\tcase TCP_CONNTRACK_ESTABLISHED:\n+\t\treturn NF_CT_DAY;\n+\tcase TCP_CONNTRACK_FIN_WAIT:\n+\tcase TCP_CONNTRACK_CLOSE_WAIT:\n+\tcase TCP_CONNTRACK_LAST_ACK:\n+\tcase TCP_CONNTRACK_TIME_WAIT:\n+\t\treturn 5 * 60 * HZ;\n+\tcase TCP_CONNTRACK_CLOSE:\n+\t\treturn 0;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * nf_flow_table_extend_ct_timeout() - Extend ct timeout of offloaded conntrack entry\n+ * @ct:\t\tFlowtable offloaded ct\n+ *\n+ * Datapath lookups in the conntrack table will evict nf_conn entries\n+ * if they have expired.\n+ *\n+ * Once nf_conn entries have been offloaded, nf_conntrack might not see any\n+ * packets anymore. Thus ct->timeout is no longer refreshed and ct can\n+ * be evicted.\n+ *\n+ * To avoid the need for an additional check on the offload bit for every\n+ * packet processed via nf_conntrack_in(), set an arbitrary timeout large\n+ * enough not to ever expire, this save us a check for the IPS_OFFLOAD_BIT\n+ * from the packet path via nf_ct_is_expired().\n+ */\n+static void nf_flow_table_extend_ct_timeout(struct nf_conn *ct)\n+{\n+\tstatic const u32 min_timeout = 5 * 60 * HZ;\n+\tu32 expires = nf_ct_expires(ct);\n+\n+\t/* normal case: large enough timeout, nothing to do. */\n+\tif (likely(expires >= min_timeout))\n+\t\treturn;\n+\n+\t/* must check offload bit after this, we do not hold any locks.\n+\t * flowtable and ct entries could have been removed on another CPU.\n+\t */\n+\tif (!refcount_inc_not_zero(&ct->ct_general.use))\n+\t\treturn;\n+\n+\t/* load ct->status after refcount increase */\n+\tsmp_acquire__after_ctrl_dep();\n+\n+\tif (nf_ct_is_confirmed(ct) &&\n+\t test_bit(IPS_OFFLOAD_BIT, &ct->status)) {\n+\t\tu8 l4proto = nf_ct_protonum(ct);\n+\t\tu32 new_timeout = true;\n+\n+\t\tswitch (l4proto) {\n+\t\tcase IPPROTO_UDP:\n+\t\t\tnew_timeout = NF_CT_DAY;\n+\t\t\tbreak;\n+\t\tcase IPPROTO_TCP:\n+\t\t\tnew_timeout = nf_flow_table_tcp_timeout(ct);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tWARN_ON_ONCE(1);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Update to ct->timeout from nf_conntrack happens\n+\t\t * without holding ct->lock.\n+\t\t *\n+\t\t * Use cmpxchg to ensure timeout extension doesn't\n+\t\t * happen when we race with conntrack datapath.\n+\t\t *\n+\t\t * The inverse -- datapath updating ->timeout right\n+\t\t * after this -- is fine, datapath is authoritative.\n+\t\t */\n+\t\tif (new_timeout) {\n+\t\t\tnew_timeout += nfct_time_stamp;\n+\t\t\tcmpxchg(&ct->timeout, expires, new_timeout);\n+\t\t}\n+\t}\n+\n+\tnf_ct_put(ct);\n+}\n+\n static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,\n \t\t\t\t struct flow_offload *flow, void *data)\n {\n+\tbool teardown = test_bit(NF_FLOW_TEARDOWN, &flow->flags);\n+\n \tif (nf_flow_has_expired(flow) ||\n \t nf_ct_is_dying(flow->ct) ||\n \t nf_flow_custom_gc(flow_table, flow))\n \t\tflow_offload_teardown(flow);\n+\telse if (!teardown)\n+\t\tnf_flow_table_extend_ct_timeout(flow->ct);\n \n-\tif (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {\n+\tif (teardown) {\n \t\tif (test_bit(NF_FLOW_HW, &flow->flags)) {\n \t\t\tif (!test_bit(NF_FLOW_HW_DYING, &flow->flags))\n \t\t\t\tnf_flow_offload_del(flow_table, flow);\n", "prefixes": [ "SRU", "N", "2/2" ] }