From a7a48f5146d9a1784c8e1febc229f309814efa11 Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Fri, 17 Dec 2021 17:21:10 +0000
Subject: [PATCH 2/3] MEDIUM: socket Add support for the new reuseportbpf
 directive.

It's an option supported from Linux 4.6, we purposely deactivate by default
 even if SO_REUSEPORT is on, it might be benefitial only in few chosen
kernel versions/hardware cases in the end.

Starting with a basic BPF socket filter, pulling the processor id explicitly,
it could be eventually expanded if needs arise.
---
 src/sock_inet.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/sock_inet.c b/src/sock_inet.c
index fa04dfed0..d8c50c0b5 100644
--- a/src/sock_inet.c
+++ b/src/sock_inet.c
@@ -335,8 +335,39 @@ int sock_inet_bind_receiver(struct receiver *rx, char **errmsg)
 	/* OpenBSD and Linux 3.9 support this. As it's present in old libc versions of
 	 * Linux, it might return an error that we will silently ignore.
 	 */
-	if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT))
-		setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
+	if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT)) {
+		int ret __maybe_unused;
+		ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
+#ifdef SO_ATTACH_REUSEPORT_CBPF
+		/* Linux 4.6 supports this to have a tigher control over the SO_REUSEPORT algorithm
+		 * here an attempt to guarantee for the socket to be bound to a particular cpu
+		 * rather than the actual round robin distribution.
+		 *
+		 * option disabled by default as this might not necessarily translate to nicer performances,
+		 * would need broader tests on various configurations, while kernel support evolves, to push otherwise.
+		 */
+		if (ret != -1 && (global.tune.options & GTUNE_USE_REUSEPORTBPF)) {
+			static struct sock_filter hacode[2] = {
+				  /* processor cpu id into A */
+				{ BPF_LD | BPF_W | BPF_ABS, 0, 0, (uint32_t)(SKF_AD_OFF + SKF_AD_CPU) },
+				  /* It could have been broadened as below, but it is a configuration bit */
+				  /* modulo threads */
+				 /* { BPF_ALU | BPF_MOD, 0, 0, (uint32_t)(<nbthreads>) }, */
+				  /* returns A */
+				{ BPF_RET | BPF_A, 0, 0, 0 },
+			};
+			static struct sock_fprog haprog = {
+				.filter = hacode,
+				.len = (sizeof(hacode) / sizeof(hacode[0])),
+			};
+
+			if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &haprog, sizeof(haprog)) == -1) {
+				err |= ERR_FATAL | ERR_ALERT;
+				memprintf(errmsg, "cannot do reuseport bpf");
+			}
+		}
+#endif
+	}
 #endif
 
 	if (!ext && (rx->settings->options & RX_O_FOREIGN)) {
-- 
2.32.0

Reply via email to