Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2215696/?format=api
{ "id": 2215696, "url": "http://patchwork.ozlabs.org/api/patches/2215696/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/4019cfba3ffd6f91aee24713d2adc778f858b4c4.1774410440.git.lucien.xin@gmail.com/", "project": { "id": 12, "url": "http://patchwork.ozlabs.org/api/projects/12/?format=api", "name": "Linux CIFS Client", "link_name": "linux-cifs-client", "list_id": "linux-cifs.vger.kernel.org", "list_email": "linux-cifs@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<4019cfba3ffd6f91aee24713d2adc778f858b4c4.1774410440.git.lucien.xin@gmail.com>", "list_archive_url": null, "date": "2026-03-25T03:47:18", "name": "[net-next,v11,13/15] quic: add timer management", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "abc3b4ba94e7aa852c0a1fd39e81c6a8f8050705", "submitter": { "id": 61073, "url": "http://patchwork.ozlabs.org/api/people/61073/?format=api", "name": "Xin Long", "email": "lucien.xin@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/4019cfba3ffd6f91aee24713d2adc778f858b4c4.1774410440.git.lucien.xin@gmail.com/mbox/", "series": [ { "id": 497380, "url": "http://patchwork.ozlabs.org/api/series/497380/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=497380", "date": "2026-03-25T03:47:06", "name": "net: introduce QUIC infrastructure and core subcomponents", "version": 11, "mbox": "http://patchwork.ozlabs.org/series/497380/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2215696/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2215696/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-cifs+bounces-10515-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-cifs@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=c6/eXWDJ;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=104.64.211.4; helo=sin.lore.kernel.org;\n envelope-from=linux-cifs+bounces-10515-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"c6/eXWDJ\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.160.174", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com" ], "Received": [ "from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgY1C6MXPz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 14:53:51 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id 03D1B3043956\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 03:50:04 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 075801B983F;\n\tWed, 25 Mar 2026 03:49:59 +0000 (UTC)", "from mail-qt1-f174.google.com (mail-qt1-f174.google.com\n [209.85.160.174])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 3BFE82E6CA8\n\tfor <linux-cifs@vger.kernel.org>; Wed, 25 Mar 2026 03:49:57 +0000 (UTC)", "by mail-qt1-f174.google.com with SMTP id\n d75a77b69052e-50b266413fbso49554661cf.1\n for <linux-cifs@vger.kernel.org>;\n Tue, 24 Mar 2026 20:49:57 -0700 (PDT)", "from wsfd-netdev58.anl.eng.rdu2.dc.redhat.com ([66.187.232.140])\n by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50b36cb2e29sm150093001cf.1.2026.03.24.20.49.53\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 24 Mar 2026 20:49:55 -0700 (PDT)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774410598; cv=none;\n b=h//ugGo3ISrr8/pvfpuAkFgj/eL9POjp2hi2CMksEXSRzt5cvOGQDsrY2ehnnmciVMH4BsdGuetJfc5/XIeV9B6rZN5bwGDSHCWxRjIHKBDewsafx9VgLZomIC3D0z0eWuNk922NjW+Pa5SmPX7b5Iyd2AWGi/rFLhJlCf/hjMw=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774410598; c=relaxed/simple;\n\tbh=Q+XwNmUUkjG7EWq81ruU+NiO4UPFYNLyiwO4GdKFvVg=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=Ai2JO5+kjVxGrhYb0JhrR6bTY0egvhMTBPN1b27MTnRQ8B8cA+EKdNmMgrBg7jlP/3mCg9Kd93nKh66JUs+L2c8qEkSLSjqC2wVRPd3wco+Jqs2hn2tfWcKqEFphIWzzBeVQNKkFP1pq0e7Nwz/6Hg1/W7fUN7vHDzKSOkuDnF8=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=c6/eXWDJ; arc=none smtp.client-ip=209.85.160.174", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1774410596; x=1775015396;\n darn=vger.kernel.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=ZuUAes6rNoYThLRW9AbdSAfLFgKqqMFG27AYV3oLAgc=;\n b=c6/eXWDJ0w/eCK7YsfxV/OSzBYSZlRdWktT15SIS3DS2bTU+V/TGYYk1zANAHXHp3L\n rcdM5j9mGQB+n9c0D9Ldqcvn3+8AH5F3fTdcS1B3csBc0m0hqtz3uKQVEcHQcR2KSpYY\n uv3CgWbbldmnYD5kCvhZeCXUs79IJXy1C3oPxswqiR0AEjTMqOn7s9Zl2BgdzC6CvLLQ\n b/8Hhy3JGomYtMB9OQoIrfMgMjJ9IulRVBVMOjx3kHKpA27Ei/1XHaItcm7SmkseTh0l\n +vRjFoZ7y7RjREVKwIxt0QJUzbHKkq1zbXt+zTFoNebhCHpnfapJUwme0LhFphqfIhtC\n aJzw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774410596; x=1775015396;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=ZuUAes6rNoYThLRW9AbdSAfLFgKqqMFG27AYV3oLAgc=;\n b=qNEFDqOlO1kk5GwntzvJeuXGblPPWu10jzszSqaxpCXQuG1z7tsLt1a+H3ClpUylt5\n 4Mg83AFPitnphOPKCUuhipnVltc+4DJODmDxBLSQqv2i7dQXUaQgV/pz40hjZed7ALye\n LX1QeITRkqjlwh78ZgpIvl8uvXHvyqKudATfV9L+1wyK4r84RHviYpl1YOEzGv82kzQv\n h69lSuGzdsb/Tao2hz8yfMOx1C16iNJMz/gU4Ajve7owSz/F+y5nhy/Jnm+xlEM3V2yh\n Px1hYofwqGGAekAb16UqnCYcACKHSJrEdvp0NnK26oRNr2jwtzLAc5bXvZsp1PRzT+YM\n CwXg==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCVU8cjWT4D1AdLWi11GXBYBnt8HglCKHrLGVb72uQU3KPoC9M27ZSZJTONvURa7UTTrgwXQItelLVdW@vger.kernel.org", "X-Gm-Message-State": "AOJu0Yw/ngBdDsKCALqjC0ILl7BTu4wGGWPM1YOCY5XcsteW5mfy5O6z\n\ttjNZH7pMiS8FXWOrJ0bWTxib92xxtTaQ44LWP1mlluStxvZF+VfCeBgY", "X-Gm-Gg": "ATEYQzz0neev6TIp30JUNypeDWeUFATWF9c79DL11CEVWcNnlsQB1kFdjSRPRJ8sRiy\n\ttDcr371VZA6X43LDSwRr7mW/oql/w5OVMsveNV5fG4cmuPDos8zggFfXcsGfsr8kVf9WC71FI24\n\ttbSHf8/+JKpy6Xe0covoPq2mfOkYQfhjoEMh8Gb4qXpdmduwLBhqEJAtK4iAuNTez2Xo5u9UeBF\n\tEjEyJOAAd6lMuJn4+iH6EXo1HSy8RcIjSCUp9KPqI1NgYMmcDPziGkqdMahp8bFhLeJDWJnpzV5\n\tywQXmX/T2Cju63rOnmSI4aJKPSQ+q1wErR7OKCLd7c4f7a1sgM7WVbYPGmYCFZDhNbMn0EVvVTE\n\tt6Nt93ZbfE7OT6PpuSZjTCu9sQeI/OWwnP/Wn1RV0rUimVjuIeIbhIG+lGcZVX8b8bOeLVJOA05\n\tBFHpWzX96I7H0Qu+JOT/4N6sUL3Wem5yqemj2p0GX2QlBybA9THpdeXRk8vuvEEHaDmHP863C+u\n\t2QRfFXCm+ZCoeXOIrmLM5WS/1OrJ/e+8bGjtMS8GUe/p4S5npf5JsSFDU6dakavA94zKUO/Rsz+", "X-Received": "by 2002:a05:622a:4d4c:b0:50b:3664:b207 with SMTP id\n d75a77b69052e-50b80cf6d13mr31530131cf.20.1774410596054;\n Tue, 24 Mar 2026 20:49:56 -0700 (PDT)", "From": "Xin Long <lucien.xin@gmail.com>", "To": "network dev <netdev@vger.kernel.org>,\n\tquic@lists.linux.dev", "Cc": "davem@davemloft.net,\n\tkuba@kernel.org,\n\tEric Dumazet <edumazet@google.com>,\n\tPaolo Abeni <pabeni@redhat.com>,\n\tSimon Horman <horms@kernel.org>,\n\tStefan Metzmacher <metze@samba.org>,\n\tMoritz Buhl <mbuhl@openbsd.org>,\n\tTyler Fanelli <tfanelli@redhat.com>,\n\tPengtao He <hepengtao@xiaomi.com>,\n\tThomas Dreibholz <dreibh@simula.no>,\n\tlinux-cifs@vger.kernel.org,\n\tSteve French <smfrench@gmail.com>,\n\tNamjae Jeon <linkinjeon@kernel.org>,\n\tPaulo Alcantara <pc@manguebit.com>,\n\tTom Talpey <tom@talpey.com>,\n\tkernel-tls-handshake@lists.linux.dev,\n\tChuck Lever <chuck.lever@oracle.com>,\n\tJeff Layton <jlayton@kernel.org>,\n\tSteve Dickson <steved@redhat.com>,\n\tHannes Reinecke <hare@suse.de>,\n\tAlexander Aring <aahringo@redhat.com>,\n\tDavid Howells <dhowells@redhat.com>,\n\tMatthieu Baerts <matttbe@kernel.org>,\n\tJohn Ericson <mail@johnericson.me>,\n\tCong Wang <xiyou.wangcong@gmail.com>,\n\t\"D . Wythe\" <alibuda@linux.alibaba.com>,\n\tJason Baron <jbaron@akamai.com>,\n\tilliliti <illiliti@protonmail.com>,\n\tSabrina Dubroca <sd@queasysnail.net>,\n\tMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>,\n\tDaniel Stenberg <daniel@haxx.se>,\n\tAndy Gospodarek <andrew.gospodarek@broadcom.com>,\n\t\"Marc E . Fiuczynski\" <marc@fiuczynski.com>", "Subject": "[PATCH net-next v11 13/15] quic: add timer management", "Date": "Tue, 24 Mar 2026 23:47:18 -0400", "Message-ID": "\n <4019cfba3ffd6f91aee24713d2adc778f858b4c4.1774410440.git.lucien.xin@gmail.com>", "X-Mailer": "git-send-email 2.47.1", "In-Reply-To": "<cover.1774410440.git.lucien.xin@gmail.com>", "References": "<cover.1774410440.git.lucien.xin@gmail.com>", "Precedence": "bulk", "X-Mailing-List": "linux-cifs@vger.kernel.org", "List-Id": "<linux-cifs.vger.kernel.org>", "List-Subscribe": "<mailto:linux-cifs+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-cifs+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit" }, "content": "This patch introduces 'quic_timer' to unify and manage the five main\ntimers used in QUIC: loss detection, delayed ACK, path validation,\nPMTU probing, and pacing. These timers are critical for driving\nretransmissions, connection liveness, and flow control.\n\nEach timer type is initialized, started, reset, or stopped using a common\nset of operations.\n\n- quic_timer_reset(): Reset a timer with type and timeout\n\n- quic_timer_start(): Start a timer with type and timeout\n\n- quic_timer_stop(): Stop a timer with type\n\nAlthough handler functions for each timer are defined, they are currently\nplaceholders; their logic will be implemented in upcoming patches for\npacket transmission and outqueue handling.\n\nDeferred timer actions are also integrated through quic_release_cb(),\nwhich dispatches to the appropriate handler when timers expire.\n\nSigned-off-by: Tyler Fanelli <tfanelli@redhat.com>\nSigned-off-by: Xin Long <lucien.xin@gmail.com>\nAcked-by: Paolo Abeni <pabeni@redhat.com>\n---\nv5:\n - Rename QUIC_TSQ_DEFERRED to QUIC_PACE_DEFERRED.\nv11:\n - Note for AI reviews: it is safe to avoid synchronous timer shutdown,\n as the timer holds a socket reference and handlers will not access\n pnspace/crypto/cong data once sk_state is closed in later patches.\n - Note for AI reviews: QUIC_F_MTU_REDUCED_DEFERRED will be used in a\n later patch; handling in quic_release_cb() will be added then.\n - Set maximum line length to 80 characters.\n - Add a check for type in quic_timer_reset().\n - Extract quic_timer_timeout() from\n quic_timer_sack/loss/path/pmtu/pace_timeout() (noted by AI review).\n---\n net/quic/Makefile | 2 +-\n net/quic/socket.c | 33 ++++++++++\n net/quic/socket.h | 33 ++++++++++\n net/quic/timer.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++\n net/quic/timer.h | 47 +++++++++++++\n 5 files changed, 279 insertions(+), 1 deletion(-)\n create mode 100644 net/quic/timer.c\n create mode 100644 net/quic/timer.h", "diff": "diff --git a/net/quic/Makefile b/net/quic/Makefile\nindex 58bb18f7926d..2ccf01ad9e22 100644\n--- a/net/quic/Makefile\n+++ b/net/quic/Makefile\n@@ -6,4 +6,4 @@\n obj-$(CONFIG_IP_QUIC) += quic.o\n \n quic-y := common.o family.o protocol.o socket.o stream.o connid.o path.o \\\n-\t cong.o pnspace.o crypto.o\n+\t cong.o pnspace.o crypto.o timer.o\ndiff --git a/net/quic/socket.c b/net/quic/socket.c\nindex 4016de4b39fe..c37cc1522254 100644\n--- a/net/quic/socket.c\n+++ b/net/quic/socket.c\n@@ -51,6 +51,8 @@ static int quic_init_sock(struct sock *sk)\n \tquic_conn_id_set_init(quic_dest(sk), 0);\n \tquic_cong_init(quic_cong(sk));\n \n+\tquic_timer_init(sk);\n+\n \tif (quic_stream_init(quic_streams(sk)))\n \t\treturn -ENOMEM;\n \n@@ -66,6 +68,8 @@ static void quic_destroy_sock(struct sock *sk)\n {\n \tu8 i;\n \n+\tquic_timer_free(sk);\n+\n \tfor (i = 0; i < QUIC_PNSPACE_MAX; i++)\n \t\tquic_pnspace_free(quic_pnspace(sk, i));\n \tfor (i = 0; i < QUIC_CRYPTO_MAX; i++)\n@@ -199,6 +203,35 @@ static int quic_getsockopt(struct sock *sk, int level, int optname,\n \n static void quic_release_cb(struct sock *sk)\n {\n+\t/* Similar to tcp_release_cb(). */\n+\tunsigned long nflags, flags = smp_load_acquire(&sk->sk_tsq_flags);\n+\n+\tdo {\n+\t\tif (!(flags & QUIC_DEFERRED_ALL))\n+\t\t\treturn;\n+\t\tnflags = flags & ~QUIC_DEFERRED_ALL;\n+\t} while (!try_cmpxchg(&sk->sk_tsq_flags, &flags, nflags));\n+\n+\tif (flags & QUIC_F_LOSS_DEFERRED) {\n+\t\tquic_timer_loss_handler(sk);\n+\t\t__sock_put(sk);\n+\t}\n+\tif (flags & QUIC_F_SACK_DEFERRED) {\n+\t\tquic_timer_sack_handler(sk);\n+\t\t__sock_put(sk);\n+\t}\n+\tif (flags & QUIC_F_PATH_DEFERRED) {\n+\t\tquic_timer_path_handler(sk);\n+\t\t__sock_put(sk);\n+\t}\n+\tif (flags & QUIC_F_PMTU_DEFERRED) {\n+\t\tquic_timer_pmtu_handler(sk);\n+\t\t__sock_put(sk);\n+\t}\n+\tif (flags & QUIC_F_PACE_DEFERRED) {\n+\t\tquic_timer_pace_handler(sk);\n+\t\t__sock_put(sk);\n+\t}\n }\n \n static int quic_disconnect(struct sock *sk, int flags)\ndiff --git a/net/quic/socket.h b/net/quic/socket.h\nindex d7811391cc8b..c5654fdc06b5 100644\n--- a/net/quic/socket.h\n+++ b/net/quic/socket.h\n@@ -21,6 +21,7 @@\n #include \"cong.h\"\n \n #include \"protocol.h\"\n+#include \"timer.h\"\n \n extern struct proto quic_prot;\n extern struct proto quicv6_prot;\n@@ -32,6 +33,31 @@ enum quic_state {\n \tQUIC_SS_ESTABLISHED\t= TCP_ESTABLISHED,\n };\n \n+enum quic_tsq_enum {\n+\tQUIC_MTU_REDUCED_DEFERRED,\n+\tQUIC_LOSS_DEFERRED,\n+\tQUIC_SACK_DEFERRED,\n+\tQUIC_PATH_DEFERRED,\n+\tQUIC_PMTU_DEFERRED,\n+\tQUIC_PACE_DEFERRED,\n+};\n+\n+enum quic_tsq_flags {\n+\tQUIC_F_MTU_REDUCED_DEFERRED\t= BIT(QUIC_MTU_REDUCED_DEFERRED),\n+\tQUIC_F_LOSS_DEFERRED\t\t= BIT(QUIC_LOSS_DEFERRED),\n+\tQUIC_F_SACK_DEFERRED\t\t= BIT(QUIC_SACK_DEFERRED),\n+\tQUIC_F_PATH_DEFERRED\t\t= BIT(QUIC_PATH_DEFERRED),\n+\tQUIC_F_PMTU_DEFERRED\t\t= BIT(QUIC_PMTU_DEFERRED),\n+\tQUIC_F_PACE_DEFERRED\t\t= BIT(QUIC_PACE_DEFERRED),\n+};\n+\n+#define QUIC_DEFERRED_ALL (QUIC_F_MTU_REDUCED_DEFERRED |\t\\\n+\t\t\t QUIC_F_LOSS_DEFERRED |\t\t\\\n+\t\t\t QUIC_F_SACK_DEFERRED |\t\t\\\n+\t\t\t QUIC_F_PATH_DEFERRED |\t\t\\\n+\t\t\t QUIC_F_PMTU_DEFERRED |\t\t\\\n+\t\t\t QUIC_F_PACE_DEFERRED)\n+\n struct quic_sock {\n \tstruct inet_sock\t\tinet;\n \tstruct list_head\t\treqs;\n@@ -47,6 +73,8 @@ struct quic_sock {\n \tstruct quic_cong\t\tcong;\n \tstruct quic_pnspace\t\tspace[QUIC_PNSPACE_MAX];\n \tstruct quic_crypto\t\tcrypto[QUIC_CRYPTO_MAX];\n+\n+\tstruct quic_timer\t\ttimers[QUIC_TIMER_MAX];\n };\n \n struct quic6_sock {\n@@ -119,6 +147,11 @@ static inline struct quic_crypto *quic_crypto(const struct sock *sk, u8 level)\n \treturn &quic_sk(sk)->crypto[level];\n }\n \n+static inline void *quic_timer(const struct sock *sk, u8 type)\n+{\n+\treturn (void *)&quic_sk(sk)->timers[type];\n+}\n+\n static inline bool quic_is_establishing(struct sock *sk)\n {\n \treturn sk->sk_state == QUIC_SS_ESTABLISHING;\ndiff --git a/net/quic/timer.c b/net/quic/timer.c\nnew file mode 100644\nindex 000000000000..a0914eae628e\n--- /dev/null\n+++ b/net/quic/timer.c\n@@ -0,0 +1,165 @@\n+// SPDX-License-Identifier: GPL-2.0-or-later\n+/* QUIC kernel implementation\n+ * (C) Copyright Red Hat Corp. 2023\n+ *\n+ * This file is part of the QUIC kernel implementation\n+ *\n+ * Initialization/cleanup for QUIC protocol support.\n+ *\n+ * Written or modified by:\n+ * Xin Long <lucien.xin@gmail.com>\n+ */\n+\n+#include \"socket.h\"\n+\n+static void quic_timer_timeout(struct quic_timer *t, int type, int defer_bit,\n+\t\t\t void (*handler)(struct sock *sk))\n+{\n+\tstruct quic_sock *qs = container_of(t, struct quic_sock, timers[type]);\n+\tstruct sock *sk = &qs->inet.sk;\n+\n+\tbh_lock_sock(sk);\n+\tif (sock_owned_by_user(sk)) {\n+\t\tif (!test_and_set_bit(defer_bit, &sk->sk_tsq_flags))\n+\t\t\tsock_hold(sk);\n+\t\tgoto out;\n+\t}\n+\n+\thandler(sk);\n+out:\n+\tbh_unlock_sock(sk);\n+\tsock_put(sk);\n+}\n+\n+void quic_timer_sack_handler(struct sock *sk)\n+{\n+}\n+\n+static void quic_timer_sack_timeout(struct timer_list *t)\n+{\n+\tquic_timer_timeout((struct quic_timer *)t, QUIC_TIMER_SACK,\n+\t\t\t QUIC_SACK_DEFERRED, quic_timer_sack_handler);\n+}\n+\n+void quic_timer_loss_handler(struct sock *sk)\n+{\n+}\n+\n+static void quic_timer_loss_timeout(struct timer_list *t)\n+{\n+\tquic_timer_timeout((struct quic_timer *)t, QUIC_TIMER_LOSS,\n+\t\t\t QUIC_LOSS_DEFERRED, quic_timer_loss_handler);\n+}\n+\n+void quic_timer_path_handler(struct sock *sk)\n+{\n+}\n+\n+static void quic_timer_path_timeout(struct timer_list *t)\n+{\n+\tquic_timer_timeout((struct quic_timer *)t, QUIC_TIMER_PATH,\n+\t\t\t QUIC_PATH_DEFERRED, quic_timer_path_handler);\n+}\n+\n+void quic_timer_reset_path(struct sock *sk)\n+{\n+\tstruct quic_cong *cong = quic_cong(sk);\n+\tu64 timeout = cong->pto * 2;\n+\n+\t/* Calculate timeout based on cong.pto, but enforce a lower bound. */\n+\tif (timeout < QUIC_MIN_PATH_TIMEOUT)\n+\t\ttimeout = QUIC_MIN_PATH_TIMEOUT;\n+\tquic_timer_reset(sk, QUIC_TIMER_PATH, timeout);\n+}\n+\n+void quic_timer_pmtu_handler(struct sock *sk)\n+{\n+}\n+\n+static void quic_timer_pmtu_timeout(struct timer_list *t)\n+{\n+\tquic_timer_timeout((struct quic_timer *)t, QUIC_TIMER_PMTU,\n+\t\t\t QUIC_PMTU_DEFERRED, quic_timer_pmtu_handler);\n+}\n+\n+void quic_timer_pace_handler(struct sock *sk)\n+{\n+}\n+\n+static enum hrtimer_restart quic_timer_pace_timeout(struct hrtimer *hr)\n+{\n+\tquic_timer_timeout((struct quic_timer *)hr, QUIC_TIMER_PACE,\n+\t\t\t QUIC_PACE_DEFERRED, quic_timer_pace_handler);\n+\treturn HRTIMER_NORESTART;\n+}\n+\n+void quic_timer_reset(struct sock *sk, u8 type, u64 timeout)\n+{\n+\tstruct timer_list *t = quic_timer(sk, type);\n+\n+\t/* Note that type must never be QUIC_TIMER_PACE for this helper. */\n+\tif (WARN_ON_ONCE(type == QUIC_TIMER_PACE))\n+\t\treturn;\n+\tif (timeout && !mod_timer(t, jiffies + usecs_to_jiffies(timeout)))\n+\t\tsock_hold(sk);\n+}\n+\n+void quic_timer_start(struct sock *sk, u8 type, u64 timeout)\n+{\n+\tstruct timer_list *t;\n+\tstruct hrtimer *hr;\n+\n+\tif (type == QUIC_TIMER_PACE) {\n+\t\thr = quic_timer(sk, type);\n+\n+\t\tif (!hrtimer_is_queued(hr)) {\n+\t\t\thrtimer_start(hr, ns_to_ktime(timeout),\n+\t\t\t\t HRTIMER_MODE_ABS_PINNED_SOFT);\n+\t\t\tsock_hold(sk);\n+\t\t}\n+\t\treturn;\n+\t}\n+\n+\tt = quic_timer(sk, type);\n+\tif (timeout && !timer_pending(t)) {\n+\t\tif (!mod_timer(t, jiffies + usecs_to_jiffies(timeout)))\n+\t\t\tsock_hold(sk);\n+\t}\n+}\n+\n+void quic_timer_stop(struct sock *sk, u8 type)\n+{\n+\tif (type == QUIC_TIMER_PACE) {\n+\t\tif (hrtimer_try_to_cancel(quic_timer(sk, type)) == 1)\n+\t\t\tsock_put(sk);\n+\t\treturn;\n+\t}\n+\tif (timer_delete(quic_timer(sk, type)))\n+\t\tsock_put(sk);\n+}\n+\n+void quic_timer_init(struct sock *sk)\n+{\n+\ttimer_setup(quic_timer(sk, QUIC_TIMER_LOSS), quic_timer_loss_timeout,\n+\t\t 0);\n+\ttimer_setup(quic_timer(sk, QUIC_TIMER_SACK), quic_timer_sack_timeout,\n+\t\t 0);\n+\ttimer_setup(quic_timer(sk, QUIC_TIMER_PATH), quic_timer_path_timeout,\n+\t\t 0);\n+\ttimer_setup(quic_timer(sk, QUIC_TIMER_PMTU), quic_timer_pmtu_timeout,\n+\t\t 0);\n+\t/* Use hrtimer for pace timer, ensuring precise control over send\n+\t * timing.\n+\t */\n+\thrtimer_setup(quic_timer(sk, QUIC_TIMER_PACE), quic_timer_pace_timeout,\n+\t\t CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_SOFT);\n+}\n+\n+void quic_timer_free(struct sock *sk)\n+{\n+\tquic_timer_stop(sk, QUIC_TIMER_LOSS);\n+\tquic_timer_stop(sk, QUIC_TIMER_SACK);\n+\tquic_timer_stop(sk, QUIC_TIMER_PATH);\n+\tquic_timer_stop(sk, QUIC_TIMER_PMTU);\n+\tquic_timer_stop(sk, QUIC_TIMER_PACE);\n+}\ndiff --git a/net/quic/timer.h b/net/quic/timer.h\nnew file mode 100644\nindex 000000000000..a5dec85f7c3e\n--- /dev/null\n+++ b/net/quic/timer.h\n@@ -0,0 +1,47 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/* QUIC kernel implementation\n+ * (C) Copyright Red Hat Corp. 2023\n+ *\n+ * This file is part of the QUIC kernel implementation\n+ *\n+ * Written or modified by:\n+ * Xin Long <lucien.xin@gmail.com>\n+ */\n+\n+enum {\n+\tQUIC_TIMER_LOSS, /* Loss detection timer: retransmit on packet loss */\n+\tQUIC_TIMER_SACK, /* ACK delay timer, also used as idle timer alias */\n+\tQUIC_TIMER_PATH, /* Path validation timer: verifies path connectivity */\n+\tQUIC_TIMER_PMTU, /* PLPMTUD probing timer */\n+\tQUIC_TIMER_PACE, /* Pacing timer: controls packet transmission pacing */\n+\tQUIC_TIMER_MAX,\n+\tQUIC_TIMER_IDLE = QUIC_TIMER_SACK,\n+};\n+\n+struct quic_timer {\n+\tunion {\n+\t\tstruct timer_list t;\n+\t\tstruct hrtimer hr;\n+\t};\n+};\n+\n+#define QUIC_MIN_PROBE_TIMEOUT\t5000000\n+\n+#define QUIC_MIN_PATH_TIMEOUT\t1500000\n+\n+#define QUIC_MIN_IDLE_TIMEOUT\t1000000\n+#define QUIC_DEF_IDLE_TIMEOUT\t30000000\n+\n+void quic_timer_reset(struct sock *sk, u8 type, u64 timeout);\n+void quic_timer_start(struct sock *sk, u8 type, u64 timeout);\n+void quic_timer_stop(struct sock *sk, u8 type);\n+void quic_timer_init(struct sock *sk);\n+void quic_timer_free(struct sock *sk);\n+\n+void quic_timer_reset_path(struct sock *sk);\n+\n+void quic_timer_loss_handler(struct sock *sk);\n+void quic_timer_pace_handler(struct sock *sk);\n+void quic_timer_path_handler(struct sock *sk);\n+void quic_timer_sack_handler(struct sock *sk);\n+void quic_timer_pmtu_handler(struct sock *sk);\n", "prefixes": [ "net-next", "v11", "13/15" ] }