From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id EF6595A0279 for ; Thu, 14 Dec 2023 03:15:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1702520145; bh=udzohERKoYX9p+hMlSU8GFloUsAU9dR00KCE97GPy6g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g/rics/EekANWklAPKLL9WTpB+7YzOmXYhd8Edt3TksDey0N9xEmSPh/l/lh8SxhI xjTWuCF49sN15MQ8VFeG02q09oygocVEXoOMNXNHpKhwyrk3kwYrek6YYIIPvl621L BU95K3y7OtycoHLk+Q/P+EbPr0u38BZL3AWQJS5ilg3QEnACKVvVFrAlVSKGyi0Ph/ tdENNAz3gPmFWJnNaTSDQI2YbMgD9iWuqe8UkQ/PzfcHYWtImfp6+KXQuhgwAWsxMS qFpxDWAtEfZySDndvXG1lwBnWmOAw2n3REB6V0FcZQKB5fcANI3OhPDiR7mCv5Sbr/ JA+w1tDUYNVeg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4SrGD11m0vz4x1v; Thu, 14 Dec 2023 13:15:45 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 6/8] flow, tcp: Add handling for per-flow timers Date: Thu, 14 Dec 2023 13:15:39 +1100 Message-ID: <20231214021541.3925825-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231214021541.3925825-1-david@gibson.dropbear.id.au> References: <20231214021541.3925825-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 7RXRHVUC5P37RMT2RFOHJX5HAX7FDYHN X-Message-ID-Hash: 7RXRHVUC5P37RMT2RFOHJX5HAX7FDYHN X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: tcp_timer() scans the flow table so that it can run tcp_splice_timer() on each spliced connection. More generally, other flow types might want to run similar timers in future. We could add a flow_timer() analagous to tcp_timer(), udp_timer() etc. However, this would need to scan the flow table, which we would have just done in flow_defer_handler(). We'd prefer to just scan the flow table once, dispatching both per-flow deferred events and per-flow timed events if necessary. So, extend flow_defer_handler() to do this. For now we use the same timer interval for all flow types (1s). We can make that more flexible in future if we need to. Signed-off-by: David Gibson --- flow.c | 13 +++++++++++-- flow.h | 4 +++- passt.c | 7 ++++--- passt.h | 2 ++ tcp.c | 6 ------ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/flow.c b/flow.c index 0a0402d..39166ae 100644 --- a/flow.c +++ b/flow.c @@ -85,13 +85,20 @@ void flow_log_(const struct flow_common *f, int pri, const char *fmt, ...) } /** - * flow_defer_handler() - Handler for per-flow deferred tasks + * flow_defer_handler() - Handler for per-flow deferred and timed tasks * @c: Execution context + * @now: Current timestamp */ -void flow_defer_handler(struct ctx *c) +void flow_defer_handler(struct ctx *c, const struct timespec *now) { + bool timer = false; union flow *flow; + if (timespec_diff_ms(now, &c->flow_timer_run) >= FLOW_TIMER_INTERVAL) { + timer = true; + c->flow_timer_run = *now; + } + for (flow = flowtab + c->flow_count - 1; flow >= flowtab; flow--) { switch (flow->f.type) { case FLOW_TCP: @@ -99,6 +106,8 @@ void flow_defer_handler(struct ctx *c) break; case FLOW_TCP_SPLICE: tcp_splice_flow_defer(c, flow); + if (timer) + tcp_splice_timer(c, flow); break; default: /* Assume other flow types don't need any handling */ diff --git a/flow.h b/flow.h index 4733671..c368a69 100644 --- a/flow.h +++ b/flow.h @@ -7,6 +7,8 @@ #ifndef FLOW_H #define FLOW_H +#define FLOW_TIMER_INTERVAL 1000 /* ms */ + /** * enum flow_type - Different types of packet flows we track */ @@ -56,7 +58,7 @@ static_assert(sizeof(flow_sidx_t) <= sizeof(uint32_t), union flow; void flow_table_compact(struct ctx *c, union flow *hole); -void flow_defer_handler(struct ctx *c); +void flow_defer_handler(struct ctx *c, const struct timespec *now); void flow_log_(const struct flow_common *f, int pri, const char *fmt, ...) __attribute__((format(printf, 3, 4))); diff --git a/passt.c b/passt.c index 5f72a28..870064f 100644 --- a/passt.c +++ b/passt.c @@ -53,8 +53,9 @@ #define EPOLL_EVENTS 8 -#define __TIMER_INTERVAL MIN(TCP_TIMER_INTERVAL, UDP_TIMER_INTERVAL) -#define TIMER_INTERVAL MIN(__TIMER_INTERVAL, ICMP_TIMER_INTERVAL) +#define TIMER_INTERVAL__ MIN(TCP_TIMER_INTERVAL, UDP_TIMER_INTERVAL) +#define TIMER_INTERVAL_ MIN(TIMER_INTERVAL__, ICMP_TIMER_INTERVAL) +#define TIMER_INTERVAL MIN(TIMER_INTERVAL_, FLOW_TIMER_INTERVAL) char pkt_buf[PKT_BUF_BYTES] __attribute__ ((aligned(PAGE_SIZE))); @@ -103,7 +104,7 @@ static void post_handler(struct ctx *c, const struct timespec *now) /* NOLINTNEXTLINE(bugprone-branch-clone): intervals can be the same */ CALL_PROTO_HANDLER(c, now, icmp, ICMP); - flow_defer_handler(c); + flow_defer_handler(c, now); #undef CALL_PROTO_HANDLER } diff --git a/passt.h b/passt.h index c74887a..20528d5 100644 --- a/passt.h +++ b/passt.h @@ -223,6 +223,7 @@ struct ip6_ctx { * @no_copy_routes: Don't copy all routes when configuring target namespace * @no_copy_addrs: Don't copy all addresses when configuring namespace * @flow_count: Number of tracked packet flows (connections etc.) + * @flow_timer_run: Timestamp of most recent flow timer run * @no_tcp: Disable TCP operation * @tcp: Context for TCP protocol handler * @no_tcp: Disable UDP operation @@ -283,6 +284,7 @@ struct ctx { int no_copy_addrs; unsigned flow_count; + struct timespec flow_timer_run; int no_tcp; struct tcp_ctx tcp; diff --git a/tcp.c b/tcp.c index 0e8e9e3..95ec760 100644 --- a/tcp.c +++ b/tcp.c @@ -3163,8 +3163,6 @@ static int tcp_port_rebind_outbound(void *arg) */ void tcp_timer(struct ctx *c, const struct timespec *now) { - union flow *flow; - (void)now; if (c->mode == MODE_PASTA) { @@ -3179,10 +3177,6 @@ void tcp_timer(struct ctx *c, const struct timespec *now) } } - for (flow = flowtab + c->flow_count - 1; flow >= flowtab; flow--) - if (flow->f.type == FLOW_TCP_SPLICE) - tcp_splice_timer(c, flow); - tcp_sock_refill_init(c); if (c->mode == MODE_PASTA) tcp_splice_refill(c); -- 2.43.0