From 9cbe8294909f76f69cf654d8df4ddc2f609848e0 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 10 Jan 2024 12:37:12 +0100 Subject: 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 --- lib/rtnl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/rtnl.c b/lib/rtnl.c index 663e634..448e43e 100644 --- a/lib/rtnl.c +++ b/lib/rtnl.c @@ -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 -- cgit v1.2.3