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 761A95A027C for ; Wed, 16 Nov 2022 05:42:23 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4NBr4R2WtWz4xcY; Wed, 16 Nov 2022 15:42:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1668573735; bh=i5/mDgR9tgUiTd2TLrKaOQLUeYJfC6R5EaT3qIpoJW8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YjgDBtdOGNdicaYKTAHTdjNjL92bUA3oCYzJ/TwENcMTXQEFUaJC4HbyyXwzIKP9y ZzcZqWECkC5mmfEaaJdaqB1qEJpDzotQNVvnbeZz3LqynAwf+P2k7s14/DweO+jKo5 wSor1aPe9MGjl9WJGJTsuUut4tge23nGwbGbLQdw= From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 18/32] tcp: Don't store hash bucket in connection structures Date: Wed, 16 Nov 2022 15:41:58 +1100 Message-Id: <20221116044212.3876516-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221116044212.3876516-1-david@gibson.dropbear.id.au> References: <20221116044212.3876516-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: D3RJ4NENIFGD6IBAFU3ZHG3KBHRRICX7 X-Message-ID-Hash: D3RJ4NENIFGD6IBAFU3ZHG3KBHRRICX7 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.3 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: Currently when we insert a connection into the hash table, we store its bucket number so we can find it when removing entries. However, we can recompute the hash value from other contents of the structure so we don't need to store it. This brings the size of tcp_tap_conn down to 64 bytes again, which means it will fit in a single cacheline on common machines. This change also removes a non-obvious constraint that the hash table have less than twice TCP_MAX_CONNS buckets, because of the way TCP_HASH_BUCKET_BITS was constructed. Signed-off-by: David Gibson --- tcp.c | 29 ++++++++++++++++++++++++----- tcp_conn.h | 5 ----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/tcp.c b/tcp.c index e46330e..7686766 100644 --- a/tcp.c +++ b/tcp.c @@ -1243,6 +1243,24 @@ static unsigned int tcp_hash(const struct ctx *c, int af, const void *addr, return (unsigned int)(b % TCP_HASH_TABLE_SIZE); } +/** + * tcp_conn_hash() - Calculate hash bucket of an existing connection + * @c: Execution context + * @conn: Connection + * + * Return: hash value, already modulo size of the hash table + */ +static unsigned int tcp_conn_hash(const struct ctx *c, + const struct tcp_tap_conn *conn) +{ + if (CONN_V6(conn)) + return tcp_hash(c, AF_INET6, &conn->a.a6, + conn->tap_port, conn->sock_port); + else + return tcp_hash(c, AF_INET, &conn->a.a4.a, + conn->tap_port, conn->sock_port); +} + /** * tcp_hash_insert() - Insert connection into hash table, chain link * @c: Execution context @@ -1258,7 +1276,6 @@ static void tcp_hash_insert(const struct ctx *c, struct tcp_tap_conn *conn, b = tcp_hash(c, af, addr, conn->tap_port, conn->sock_port); conn->next_index = tc_hash[b] ? CONN_IDX(tc_hash[b]) : -1; tc_hash[b] = conn; - conn->hash_bucket = b; debug("TCP: hash table insert: index %li, sock %i, bucket: %i, next: " "%p", CONN_IDX(conn), conn->sock, b, conn_at_idx(conn->next_index)); @@ -1266,12 +1283,14 @@ static void tcp_hash_insert(const struct ctx *c, struct tcp_tap_conn *conn, /** * tcp_hash_remove() - Drop connection from hash table, chain unlink + * @c: Execution context * @conn: Connection pointer */ -static void tcp_hash_remove(const struct tcp_tap_conn *conn) +static void tcp_hash_remove(const struct ctx *c, + const struct tcp_tap_conn *conn) { struct tcp_tap_conn *entry, *prev = NULL; - int b = conn->hash_bucket; + int b = tcp_conn_hash(c, conn); for (entry = tc_hash[b]; entry; prev = entry, entry = conn_at_idx(entry->next_index)) { @@ -1299,7 +1318,7 @@ static void tcp_tap_conn_update(struct ctx *c, struct tcp_tap_conn *old, struct tcp_tap_conn *new) { struct tcp_tap_conn *entry, *prev = NULL; - int b = old->hash_bucket; + int b = tcp_conn_hash(c, old); for (entry = tc_hash[b]; entry; prev = entry, entry = conn_at_idx(entry->next_index)) { @@ -1387,7 +1406,7 @@ static void tcp_conn_destroy(struct ctx *c, struct tcp_tap_conn *conn) if (conn->timer != -1) close(conn->timer); - tcp_hash_remove(conn); + tcp_hash_remove(c, conn); tcp_table_compact(c, (union tcp_conn *)conn); } diff --git a/tcp_conn.h b/tcp_conn.h index faa63dc..4bffe9a 100644 --- a/tcp_conn.h +++ b/tcp_conn.h @@ -9,8 +9,6 @@ #ifndef TCP_CONN_H #define TCP_CONN_H -#define TCP_HASH_BUCKET_BITS (TCP_CONN_INDEX_BITS + 1) - /** * struct tcp_conn_common - Common fields for spliced and non-spliced * @spliced: Is this a spliced connection? @@ -32,7 +30,6 @@ extern const char *tcp_common_flag_str[]; * @events: Connection events, implying connection states * @timer: timerfd descriptor for timeout events * @flags: Connection flags representing internal attributes - * @hash_bucket: Bucket index in connection lookup hash table * @retrans: Number of retransmissions occurred due to ACK_TIMEOUT * @ws_from_tap: Window scaling factor advertised from tap/guest * @ws_to_tap: Window scaling factor advertised to tap/guest @@ -97,8 +94,6 @@ struct tcp_tap_conn { #define ACK_FROM_TAP_DUE BIT(5) - unsigned int hash_bucket :TCP_HASH_BUCKET_BITS; - #define TCP_MSS_BITS 14 unsigned int tap_mss :TCP_MSS_BITS; #define MSS_SET(conn, mss) (conn->tap_mss = (mss >> (16 - TCP_MSS_BITS))) -- 2.38.1