Skip to content

UFT tables should not attempt to delegate eviction score - #1044

Open
FelixMcFelix wants to merge 1 commit into
bound-flow-childrenfrom
uft-ttl-fix
Open

UFT tables should not attempt to delegate eviction score#1044
FelixMcFelix wants to merge 1 commit into
bound-flow-childrenfrom
uft-ttl-fix

Conversation

@FelixMcFelix

Copy link
Copy Markdown
Collaborator

Only layers' flow table entries have parents, with the setup we have
today. One of the things we do which takes advantage of this is that for
a TCP flow, LFT entries will receive a high evictability score -- we do
so because one of these parents is an entry in the TCP flow table. If
the entry is absent, we know we have a disconnected LFT entry that can
be safely removed. If it is present, it will reduce the entry's
evictability with a better score.

The problem is that this logic was implemented directly on the Ttl
type, which we use by default. The UFTs then assign a maximum
evictability to any TCP flows, forcing them into having LRU eviction
because there is no child entry -- that's not the policy we want. (Yet,
at least.)

This fix moves that behaviour into a newtype and has the LFTs explcitly
opt into that behaviour.


Stack created with GitHub Stacks CLIGive Feedback 💬

@rcgoodfellow

rcgoodfellow commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Is the following correct?

Before the UFT had a policy of Arc::new(FLOW_DEF_TTL). And because of that we were picking up delegated eviction semantics for TCP for everything in the UFT. But now that we have removed those delegated semantics from the ExpiryPolicy trait impl for Ttl and created the new TtlDelegateTcp wrapper for Ttl with the delegated eviction and explicitly construct LFTs with that policy we only get delegated TTL mechanics on LFT flows?

Only layers' flow table entries have parents, with the setup we have
today. One of the things we do which takes advantage of this is that for
a TCP flow, LFT entries will receive a high evictability score -- we do
so because one of these parents is an entry in the TCP flow table. If
the entry is absent, we know we have a disconnected LFT entry that can
be safely removed. If it is present, it will reduce the entry's
evictability with a better score.

The problem is that this logic was implemented directly on the `Ttl`
type, which we use by default. The UFTs then assign a maximum
evictability to any TCP flows, forcing them into having LRU eviction
because there is no child entry -- that's not the policy we want. (Yet,
at least.)

This fix moves that behaviour into a newtype and has the LFTs explcitly
opt into that behaviour.
@FelixMcFelix

Copy link
Copy Markdown
Collaborator Author

Is the following correct?

Before the UFT had a policy of Arc::new(FLOW_DEF_TTL). And because of that we were picking up delegated eviction semantics for TCP for everything in the UFT. But now that we have removed those delegated semantics from the ExpiryPolicy trait impl for Ttl and created the new TtlDelegateTcp wrapper for Ttl with the delegated eviction and explicitly construct LFTs with that policy we only get delegated TTL mechanics on LFT flows?

That's correct, strictly speaking, but things are related a bit more confusingly. I guess if we look at one LFT entry and its parents we can make this a bit clearer for a given TCP flow using master's Ttl/TcpExpiry:

[Policy=TTL]
   L_1 -----(children)-----> UFT_in1     [Policy=TTL]
                     \-----> UFT_out1    [Policy=TTL]
                     \-----> TCP1        [Policy=TcpExpiry]

The only child relationships are from L_1 to the UFT/TCP state -- the UFT entries don't have a link to TCP1. When we want to find an eviction score for L_1, we get an initial score of EvictionPriority::Evictable(NonZeroU16::MAX), because the flow's protocol is TCP. Each UFT entry also reports the same score (!), and then TCP1's score will determine whether L_1 has a better score. The problem there is that all TCP UFT entries, if examined on their own, end up with the same high evictability score. It's never reduced to something reasonable because there is intentionally no child link, while UDP/ICMP traffic ends up with fixed 60s eviction/expiry semantics.

(Note: I think making all UFT entries purely LRU evictable is an interesting thing to look at in future if we want to reduce the table size, but if we're doing that it should be uniform across protocols.)

UFT eviction is still indirectly controlled by TCP1 with this fixed to use TtlDelegateTcp. If L_1 is misbehaving and is evicted, then [UFT_in1, UFT_out1, TCP1] are all marked killed. An eviction candidate search will terminate as soon as such an entry is seen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants