diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2024-01-16 11:50:43 +1100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-01-22 23:35:37 +0100 |
commit | 8981a720aac4ab22beb3375cd77062a8aed693e6 (patch) | |
tree | 16cdc6bec085763de21b705f5c8188990251f50d /flow_table.h | |
parent | 9c0881d4f6dd651fd2a40896b54d554cb7ba5b2e (diff) | |
download | passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar.gz passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar.bz2 passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar.lz passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar.xz passt-8981a720aac4ab22beb3375cd77062a8aed693e6.tar.zst passt-8981a720aac4ab22beb3375cd77062a8aed693e6.zip |
flow: Avoid moving flow entries to compact table
Currently we always keep the flow table maximally compact: that is all the
active entries are contiguous at the start of the table. Doing this
sometimes requires moving an entry when one is freed. That's kind of
fiddly, and potentially expensive: it requires updating the hash table for
the new location, and depending on flow type, it may require EPOLL_CTL_MOD,
system calls to update epoll tags with the new location too.
Implement a new way of managing the flow table that doesn't ever move
entries. It attempts to maintain some compactness by always using the
first free slot for a new connection, and mitigates the effect of non
compactness by cheaply skipping over contiguous blocks of free entries.
See the "theory of operation" comment in flow.c for details.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>b
[sbrivio: additional ASSERT(flow_first_free <= FLOW_MAX - 2) to avoid
Coverity Scan false positive]
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'flow_table.h')
-rw-r--r-- | flow_table.h | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/flow_table.h b/flow_table.h index 2773a2b..eecf884 100644 --- a/flow_table.h +++ b/flow_table.h @@ -10,6 +10,19 @@ #include "tcp_conn.h" /** + * struct flow_free_cluster - Information about a cluster of free entries + * @f: Generic flow information + * @n: Number of entries in the free cluster (including this one) + * @next: Index of next free cluster + */ +struct flow_free_cluster { + /* Must be first element */ + struct flow_common f; + unsigned n; + unsigned next; +}; + +/** * union flow - Descriptor for a logical packet flow (e.g. connection) * @f: Fields common between all variants * @tcp: Fields for non-spliced TCP connections @@ -17,12 +30,13 @@ */ union flow { struct flow_common f; + struct flow_free_cluster free; struct tcp_tap_conn tcp; struct tcp_splice_conn tcp_splice; }; /* Global Flow Table */ -extern unsigned flow_count; +extern unsigned flow_first_free; extern union flow flowtab[]; |