Skip to content
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

Add expiration of incomplete reassembly buffers to IPv6 #1384

Merged
merged 15 commits into from
Jun 6, 2019

Conversation

alexandergall
Copy link
Contributor

No description provided.

Frequent trace aborts due to "register coalescing too complex" have
been observed within handle_fragment().  This commit attempts to
mitigate this by limiting the scope of local variables, either by
explicit scoping with do/end or by placing variable declarations after
function calls that don't need them.
The amount of work being done in the main push() loop is reduced by
moving fragments to a separate queue.  This is beneficial if the
workload is unbiased with respect to fragmentation or if the workload
shifts from mainly fragmented to mainly unfragmented packets.

All packets needing reassembly are processed in a separate loop.
Add an optional callback which is invoked on an evicted entry to
perform cleanup before the entry is purged from the table.
Respect the precondition for sort_array().

Use bit.band instead of modulo operator to check for multple of 8 of
the fragment size.
The headers of all fragments are derived from the unfragmentable part
of the original packet, hence the distinction for fragment #0 is not
necessary.
Copy link
Contributor

@dpino dpino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I think a review from @wingo would be nice as he is wrote a big chunk of this code.

local max_data_offset = ether_ipv6_header_len + frag_start + frag_size
if max_data_offset > ffi.sizeof(reassembly.packet.data) then
-- Snabb packets have a maximum size of 10240 bytes.
return self:reassembly_error(entry)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maximum size of a packet is defined as a constant in core/packet.lua:max_payload.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is from the original code (I only added a do...end to limit the scope of locals). This would be a cosmetic change, I suppose?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't realize this wasn't a new change. Rather than cosmetic, the difference is that the size is being computed every time this function is called, when it can be retrieved from a constant. I leave it up to you if you'd like to change it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have expected that this would be taken care of by the optimizer, but if it's not, that change would certainly be a good idea.

@@ -264,24 +284,27 @@ function Reassembler:handle_fragment(h)
else
reassembly.final_start = frag_start
end
elseif frag_size % 8 ~= 0 then
elseif bit.band(frag_size, 0x7) ~= 0 then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changed isn't justified. I benchmarked % and "mod with logical and" and they're the same speed. What's indeed much slower is math.fmod. I think this change should be reverted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I assume that % optimizes for this case?

Copy link
Contributor

@dpino dpino Jan 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The results I got from benchmarking % and & showed no difference. Here's a gist of the code I tried https://gist.github.com/dpino/925a79494d3da27e3681e8b3acf67b32. I don't know what LuaJIT compiles % to, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked and the compiler does indeed specialize to bitops if the module is a power of 2.

@eugeneia
Copy link
Member

eugeneia commented Jan 7, 2019

@alexandergall If you think this is ready I can I merge this onto max-next.

@alexandergall
Copy link
Contributor Author

Pushed the changes suggested by @dpino. Ready to merge for me.

Take padding to minimum Ethernet frame size into account.
@eugeneia eugeneia merged commit 69473eb into snabbco:master Jun 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants