From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 2624A5A0278 for ; Tue, 16 Jan 2024 01:50:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1705366246; bh=9W0qTo5l/XZkYxBTVRxTnKyreNnS5PfwpTrhOglZ0JA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hAOKUI+jfeZI0PzHK2B84CH0Lz+RZjFNrKbYrpSAiEiUZ93NufBUuCY8uEbMLegwL AxELkFvb09lEPVOqChBNbZTBNto0leH/a7T5xtD265avNWut6SyyqDxR2JRQjj+oY6 598886nfngtczuUS5Hzg1PPJaWamlaWsX1QP12SeLybCByRrvP/aL3SMYE219OrMam 3jRqwOPtagI8lW+he0MRKKTFoTfGiSNTxRfb4wcqZcGYB/7eT5HV4E/xJlgbzngGZE Wakp+dygkN6Hjatff4HsWQxqmyr6j92WAbEbmGABt1egHL8PjBLkVELtCwu5KbFQru PPwXCcvXeP2EQ== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4TDVmk2WGlz4xGR; Tue, 16 Jan 2024 11:50:46 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v4 06/13] flow, tcp: Add handling for per-flow timers Date: Tue, 16 Jan 2024 11:50:36 +1100 Message-ID: <20240116005043.2212259-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240116005043.2212259-1-david@gibson.dropbear.id.au> References: <20240116005043.2212259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 437FUPHCACCUAWS46KGBX5KUP52WLRNE X-Message-ID-Hash: 437FUPHCACCUAWS46KGBX5KUP52WLRNE 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 | 16 ++++++++++++++-- flow.h | 4 +++- passt.c | 7 ++++--- tcp.c | 6 ------ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/flow.c b/flow.c index 4dc2767..5dd5d2b 100644 --- a/flow.c +++ b/flow.c @@ -28,6 +28,9 @@ static_assert(ARRAY_SIZE(flow_type_str) == FLOW_NUM_TYPES, /* Global Flow Table */ union flow flowtab[FLOW_MAX]; +/* Last time the flow timers ran */ +static struct timespec flow_timer_run; + /** * flow_table_compact() - Perform compaction on flow table * @c: Execution context @@ -86,13 +89,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, &flow_timer_run) >= FLOW_TIMER_INTERVAL) { + timer = true; + flow_timer_run = *now; + } + for (flow = flowtab + c->flow_count - 1; flow >= flowtab; flow--) { switch (flow->f.type) { case FLOW_TCP: @@ -100,6 +110,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 6b17fa8..423e685 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 */ @@ -67,7 +69,7 @@ static inline bool flow_sidx_eq(flow_sidx_t a, flow_sidx_t b) 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/tcp.c b/tcp.c index 7065531..9fffafb 100644 --- a/tcp.c +++ b/tcp.c @@ -3171,8 +3171,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) { @@ -3187,10 +3185,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