aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorKuniyuki Iwashima <[email protected]>2024-03-25 20:24:20 +0000
committerJakub Kicinski <[email protected]>2024-03-29 15:28:25 +0000
commit77e5593aebba823bcbcf2c4b58b07efcd63933b8 (patch)
tree15f041a665d5a043a4c363aca2fa5ca790d31c98 /net/unix/af_unix.c
parentaf_unix: Save O(n) setup of Tarjan's algo. (diff)
downloadkernel-77e5593aebba823bcbcf2c4b58b07efcd63933b8.tar.gz
kernel-77e5593aebba823bcbcf2c4b58b07efcd63933b8.zip
af_unix: Skip GC if no cycle exists.
We do not need to run GC if there is no possible cyclic reference. We use unix_graph_maybe_cyclic to decide if we should run GC. If a fd of an AF_UNIX socket is passed to an already inflight AF_UNIX socket, they could form a cyclic reference. Then, we set true to unix_graph_maybe_cyclic and later run Tarjan's algorithm to group them into SCC. Once we run Tarjan's algorithm, we are 100% sure whether cyclic references exist or not. If there is no cycle, we set false to unix_graph_maybe_cyclic and can skip the entire garbage collection next time. When finalising SCC, we set true to unix_graph_maybe_cyclic if SCC consists of multiple vertices. Even if SCC is a single vertex, a cycle might exist as self-fd passing. Given the corner case is rare, we detect it by checking all edges of the vertex and set true to unix_graph_maybe_cyclic. With this change, __unix_gc() is just a spin_lock() dance in the normal usage. Signed-off-by: Kuniyuki Iwashima <[email protected]> Acked-by: Paolo Abeni <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'net/unix/af_unix.c')
0 files changed, 0 insertions, 0 deletions