-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
flow-manager: fix off-by-one in flow_hash row allocation #6993
Conversation
The current code doesn't cover all rows when more than one flow manager is used. It leaves a single row between ftd->max and ftd->min of the next manager orphaned. As an example: hash_size=1000 flowmgr_number=3 range=333 instance ftd->min ftd->max 0 0 333 1 334 666 2 667 1000 Rows not covered: 333, 666
Thanks for your work and analysis. A ticket would be great as we use it to track backports to stable branches and to generate release notes. |
Codecov Report
@@ Coverage Diff @@
## master #6993 +/- ##
==========================================
- Coverage 77.70% 77.66% -0.04%
==========================================
Files 628 628
Lines 185656 185653 -3
==========================================
- Hits 144270 144195 -75
- Misses 41386 41458 +72
Flags with carried forward coverage won't be shown. Click here to find out more. |
I've created 5073. |
ftd->max = (ftd->instance + 1) * range; | ||
|
||
/* last flow-manager takes on hash_size % flowmgr_number extra rows */ | ||
if ((ftd->instance + 1) == flowmgr_number) { | ||
ftd->max = flow_config.hash_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @awelzel for your first contribution to our project! :)
Just adding my thoughts around rounding of range
that Victor asked to check.
hash size = 9000
thread count = 57
range (uint32_t) = 9000/57 = 157.8... but stored as 157
But, range x thread_count (our max) = 157 x 57 = 8949
So, we're short of 9000 - 8949 = 51
Although, with the patch, while we're at the last stage when thread count == 57, we'll set the max to 9000 so seems all will be OK..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if rounding errors can get us into a state of missing rows, or assigning duplicate rows to threads, we need a new approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @awelzel for your first contribution to our project! :)
Thanks!
Although, with the patch, while we're at the last stage when thread count == 57, we'll set the max to 9000 so seems all will be OK..
Yes, so that was the intention. The last flow-manager just picks up all remaining rows. As in the comment, it'll deal with hash_size % flowmgr_number
more rows than the others.
Now, with hash_size of 9000 and 57 flow managers that looks like a lot: Every manager is allocated 157 rows, while the last one deals with 208 rows (~30% more).
However, seems like hash_size 9000 and 57 flow manager isn't a practical setting one would run.
With hash_size 65536 (default) and 7 flow managers (still quite high?), it's 9362 rows for flow-managers 1-6, and 9364 for manager 7, which is only 2 rows more and probably negligible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That logic/idea is already in place already in the current code. It's just more explicit now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@victorjulien / @inashivb - is there anything more you'd need input on for this PR?
Merged in #7187, thanks! |
Make sure these boxes are signed before submitting your Pull Request -- thank you.
Link to redmine ticket: 5073.
Describe changes:
The current code doesn't cover all rows when more than one flow manager is
used. It leaves a single row between ftd->max and ftd->min of the next
manager orphaned. As an example:
#suricata-verify-pr:
#suricata-verify-repo:
#suricata-verify-branch:
#suricata-update-pr:
#suricata-update-repo:
#suricata-update-branch:
#libhtp-pr:
#libhtp-repo:
#libhtp-branch: