When under stress, the packet threads ultimately fall back
to walking the hash table until they find a flow they can
safely evict and reuse. This could lead to all threads
fighting over the FlowBucket locks.
Fix by adding a limit to the number of hash rows that are
checked for a new flow. If the limit is reached, simply fail
to get a flow.
{
uint32_t idx = SC_ATOMIC_GET(flow_prune_idx) % flow_config.hash_size;
uint32_t cnt = flow_config.hash_size;
+ uint32_t tried = 0;
while (cnt--) {
+ tried++;
if (++idx >= flow_config.hash_size)
idx = 0;
+ if (tried >= 25) {
+ (void) SC_ATOMIC_ADD(flow_prune_idx, (flow_config.hash_size - cnt));
+ break;
+ }
+
FlowBucket *fb = &flow_hash[idx];
if (FBLOCK_TRYLOCK(fb) != 0)