From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202408 header.b=AZpoEvGU; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 3DC765A0276 for ; Fri, 13 Sep 2024 06:32:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202408; t=1726201936; bh=n6TWen9b35DZ5FaeumuGTHB8ghLvZAVmmegk0EZtnrs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AZpoEvGU8WVvHr2O/IXukGVZAXZQg0PydPa3QomPW3eFEc8D/iUYxFrkO9xrnjamg Bi0wkl3l4rxZontTz8Hfm6le/tbyYKQ5E7eVNzn49SY/95mXgm08947iUD2Yv8K/Xe Xpitjpe2aQwk89efEzkzHiIPKZ3ygsT3DVPkacaQrobnNJ79RmM/yGiajCl4xvM+DT QM3sIfidXcmOBp5fLzL955ihRJZU0sn+/N1UY4fetkr54vFRSxAMGFloxB6CVYF903 xfjbc61OA2j2OncJQodUZKu3Rz0/VbE2taMXhsq1USVl4ihj8gaEeQE46DmU72MJdr qA2HuZaZ8/FHw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4X4hH45xm1z4xQW; Fri, 13 Sep 2024 14:32:16 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 08/10] tcp: Keep track of connections blocked due to a full tap interface Date: Fri, 13 Sep 2024 14:32:12 +1000 Message-ID: <20240913043214.1753014-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240913043214.1753014-1-david@gibson.dropbear.id.au> References: <20240913043214.1753014-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: PUVD6YVLNGDQM7GJ5JZ6ADZ7SZFH5NHI X-Message-ID-Hash: PUVD6YVLNGDQM7GJ5JZ6ADZ7SZFH5NHI 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: When we receive new data on a TCP socket, we attempt to forward all of it to the tap interface immediately. However, if the tap buffers fill up, we might fail to transfer some of it. In that case we'll need to try again later. Currently that's handled by the EPOLLIN event being re-asserted in level mode at some point by complicated fiddling of the event masks. In preparation for a simpler way of triggering the retry, keep track of which connections are in this state with a new TAP_FULL flag. We also keep a count of the total number of connections currently in the TAP_FULL state. Signed-off-by: David Gibson --- tcp.c | 12 +++++++++++- tcp_buf.c | 3 +++ tcp_conn.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tcp.c b/tcp.c index 32e45e09..4b478432 100644 --- a/tcp.c +++ b/tcp.c @@ -349,7 +349,7 @@ static const char *tcp_state_str[] __attribute((__unused__)) = { static const char *tcp_flag_str[] __attribute((__unused__)) = { "STALLED", "LOCAL", "ACTIVE_CLOSE", "ACK_TO_TAP_DUE", - "ACK_FROM_TAP_DUE", + "ACK_FROM_TAP_DUE", "TAP_FULL", }; /* Listening sockets, used for automatic port forwarding in pasta mode only */ @@ -381,6 +381,11 @@ static struct iovec tcp_iov [UIO_MAXIOV]; int init_sock_pool4 [TCP_SOCK_POOL_SIZE]; int init_sock_pool6 [TCP_SOCK_POOL_SIZE]; +/* Number of connections with pending socket data that couldn't be sent because + * we ran out of buffer space on the tap side + */ +unsigned num_tap_full; + /** * conn_at_sidx() - Get TCP connection specific flow at given sidx * @sidx: Flow and side to retrieve @@ -597,6 +602,11 @@ void conn_flag_do(const struct ctx *c, struct tcp_tap_conn *conn, (flag == ~ACK_FROM_TAP_DUE && (conn->flags & ACK_TO_TAP_DUE)) || (flag == ~ACK_TO_TAP_DUE && (conn->flags & ACK_FROM_TAP_DUE))) tcp_timer_ctl(c, conn); + + if (flag == TAP_FULL) + num_tap_full++; + else if (flag == ~TAP_FULL) + num_tap_full--; } /** diff --git a/tcp_buf.c b/tcp_buf.c index 83f91a37..0ccb9e6b 100644 --- a/tcp_buf.c +++ b/tcp_buf.c @@ -250,6 +250,8 @@ static void tcp_revert_seq(const struct ctx *c, struct tcp_tap_conn **conns, uint32_t seq = ntohl(th->seq); uint32_t peek_offset; + conn_flag(c, conn, TAP_FULL); + if (SEQ_LE(conn->seq_to_tap, seq)) continue; @@ -526,6 +528,7 @@ int tcp_buf_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn) seq += dlen; } + conn_flag(c, conn, ~TAP_FULL); conn_flag(c, conn, ACK_FROM_TAP_DUE); return 0; diff --git a/tcp_conn.h b/tcp_conn.h index 6ae05115..9677678c 100644 --- a/tcp_conn.h +++ b/tcp_conn.h @@ -77,6 +77,7 @@ struct tcp_tap_conn { #define ACTIVE_CLOSE BIT(2) #define ACK_TO_TAP_DUE BIT(3) #define ACK_FROM_TAP_DUE BIT(4) +#define TAP_FULL BIT(5) #define SNDBUF_BITS 24 unsigned int sndbuf :SNDBUF_BITS; -- 2.46.0