diff options
author | Jo-Philipp Wich <jo@mein.io> | 2024-01-10 12:37:12 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2024-01-10 12:37:12 +0100 |
commit | 9cbe8294909f76f69cf654d8df4ddc2f609848e0 (patch) | |
tree | f36d727c62adea1d95953cc4abb604b99212d1e4 | |
parent | 30a3f7ad0433be059f744c974917bc589b928682 (diff) |
rtnl: optimize reception of rtnl events
Once we're notified about pending data on the netlink event socket,
try to receive as much messages as possible in order to empty the socket
buffer. In contrast to the previous implementation which received one
message per epoll read notification, this avoids some premature ENOBUFS
situations when a huge burst of messages arrives, e.g. due to kernel
side GC runs on the neighbor table.
Since libnl's nl_recvmsgs*() functions do not expose the underlying
-1 error returned by the recvmsg() calls, we need to indirectly check
for errors through errno variable, so clear it out both before the
recvmsgs() call and after successfully completing a message reception
callback invocation.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | lib/rtnl.c | 15 |
1 files changed, 14 insertions, 1 deletions
@@ -3618,13 +3618,26 @@ cb_listener_event(struct nl_msg *msg, void *arg) ucv_put(uc_vm_stack_pop(vm)); } + errno = 0; + return NL_SKIP; } static void uc_nl_listener_cb(struct uloop_fd *fd, unsigned int events) { - nl_recvmsgs_default(nl_conn.evsock); + while (true) { + errno = 0; + + nl_recvmsgs_default(nl_conn.evsock); + + if (errno != 0) { + if (errno != EAGAIN && errno != EWOULDBLOCK) + set_error(errno, NULL); + + break; + } + } } static void |