Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@brian-armstrong-discord
Copy link

Netmap is a project that gives user-space networking to linux
applications. Netmap binds to the network interface, and traffic
steering rules (generated by ethtool) drive packets into user-specific
receive queues. This completely bypasses the kernel except for NIC IRQs.
Because only some queues are controlled in userspace, the kernel
continues to run other functionality like pings and ssh. In practice we
find this yields approximately 5x more efficient packet receives.

https://blog.cloudflare.com/single-rx-queue-kernel-bypass-with-netmap/

This patch brings netmap to libuv for UDP packets. We connect the event
loop to a single netmap queue. When the use_netmap flag is turned on
for new udp sockets, these sockets bypass the kernel calls and instead
operate on top of the netmap rings.

Netmap is a project that gives user-space networking to linux
applications. Netmap binds to the network interface, and traffic
steering rules (generated by ethtool) drive packets into user-specific
receive queues. This completely bypasses the kernel except for NIC IRQs.
Because only some queues are controlled in userspace, the kernel
continues to run other functionality like pings and ssh. In practice we
find this yields approximately 5x more efficient packet receives.

https://blog.cloudflare.com/single-rx-queue-kernel-bypass-with-netmap/

This patch brings netmap to libuv for UDP packets. We connect the event
loop to a single netmap queue. When the `use_netmap` flag is turned on
for new udp sockets, these sockets bypass the kernel calls and instead
operate on top of the netmap rings.
Copy link
Member

@adill adill left a comment

Choose a reason for hiding this comment

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

I think this generally looks good 👍 with the following caveats / notes:

  • It's difficult to thoroughly review this for correctness without deeper knowledge of both libuv and netmap
  • A lot of potential cases are not handled (NULL inputs, memcpy bounds validation) and we should consider how pedantic we need to be / should be
  • The uv_udp_ interface seems incomplete -- maybe that is fine because it looks like in most cases you're failing with -1 and what is implemented fits our use case (should we explicitly assert when some functionality is not intended to be used?)
  • Is it worth your time to add tests which exercise the netmap functionality?


udp_chksum = udp->check;
if (udp_chksum != udp_checksum(ip, udp, payload, payload_len)) {
printf("udp checksum failed, %x != %x\n", udp_chksum, udp_checksum(ip, udp, payload, payload_len));

Choose a reason for hiding this comment

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

didn't mean to leave this printf in, will remove

Copy link
Member

@adill adill left a comment

Choose a reason for hiding this comment

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

🎉

if (intopt > UCHAR_MAX) {
return -1;
}
if (option4 == IP_TOS) {
Copy link
Member

Choose a reason for hiding this comment

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

Are you not using option6? It's not clear to me what option4 and option6 are supposed to be. setsockopt calls them level and option_name, yea? Now it looks like option4 == option_name and option6 is not used?

Copy link
Author

@brian-armstrong-discord brian-armstrong-discord Aug 12, 2019

Choose a reason for hiding this comment

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

For some confusing reason, uv__udp_setsockopt is actually setsockopt(IPPROTO_IP, ...) or setsockopt(IPPROTO_IPV6, ...), depending on whether the socket is ipv4 or ipv6. I completely missed this the first time around. Callers are supposed to invoke with the IPv4 and IPv6 options and uv__udp_setsockopt() sorts out which to use.

This fun detail means it's only valid to use uv__udp_setsockopt() when one wants to set IP parameters, and the calling signature is completely different from setsockopt()

@brian-armstrong-discord brian-armstrong-discord merged commit 2b664ff into discord-1.29.0 Aug 14, 2019
@brian-armstrong-discord brian-armstrong-discord deleted the feature/netmap branch August 14, 2019 21:28
snowyote pushed a commit that referenced this pull request May 24, 2022
ERROR: LeakSanitizer: detected memory leaks

```
Direct leak of 432 byte(s) in 9 object(s) allocated from:
    #0 0x1062eedc2 in __sanitizer_mz_calloc+0x92 (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x46dc2)
    #1 0x7fff20171eb6 in _malloc_zone_calloc+0x3a (libsystem_malloc.dylib:x86_64+0x1beb6)
    #2 0x7fff203ac180 in _CFRuntimeCreateInstance+0x124 (CoreFoundation:x86_64h+0x4180)
    #3 0x7fff203ab906 in __CFStringCreateImmutableFunnel3+0x84d (CoreFoundation:x86_64h+0x3906)
    #4 0x7fff203ab0a1 in CFStringCreateWithCString+0x48 (CoreFoundation:x86_64h+0x30a1)
    #5 0x1056f63e1 in uv__get_cpu_speed darwin.c:267
    #6 0x1056f491e in uv_cpu_info darwin.c:338
```

PR-URL: libuv#3098
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
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.

3 participants