aboutgitcodebugslistschat
path: root/tcp.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2022-11-17 16:58:54 +1100
committerStefano Brivio <sbrivio@redhat.com>2022-11-25 01:35:28 +0100
commitb65d603e23d7f05c4974dcf22f3244d2ae987482 (patch)
treeaff065e264bfa2ec743ed8d988543781c272eaec /tcp.c
parent233b95e90f8e9391d93d2187f682eaf51b6f3dd1 (diff)
downloadpasst-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar.gz
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar.bz2
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar.lz
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar.xz
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.tar.zst
passt-b65d603e23d7f05c4974dcf22f3244d2ae987482.zip
tcp: Don't store hash bucket in connection structures
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/tcp.c b/tcp.c
index b11ce6e..e9803aa 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1244,6 +1244,24 @@ static unsigned int tcp_hash(const struct ctx *c, int af, const void *addr,
}
/**
+ * 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
* @conn: Connection pointer
@@ -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);
}