[PATCH] Use BPF to distribute packet to different work thread.

Liu, Qiao qiao.liu at intel.com
Thu Sep 10 05:22:12 UTC 2020


# HG changeset patch
# User Liu Qiao <qiao.liu at intel.com>
# Date 1599735293 14400
#      Thu Sep 10 06:54:53 2020 -0400
# Node ID f79d524a2cc0093c53490f947564e42371cf944f
# Parent  da5e3f5b16733167142b599b6af3ce9469a07d52
Use BPF to distribute packet to different work thread.
Use Berkeley Packet Filter to get packet queue_mapping number,
and use this queue_mapping number to distribute the packet to
different work thread, this will improve CPU utilization and http
latency.
Author: Samudrala, Sridhar <sridhar.samudrala at intel.com>

diff -r da5e3f5b1673 -r f79d524a2cc0 auto/os/linux
--- a/auto/os/linux           Wed Sep 02 23:13:36 2020 +0300
+++ b/auto/os/linux        Thu Sep 10 06:54:53 2020 -0400
@@ -32,6 +32,10 @@
     have=NGX_HAVE_POSIX_FADVISE . auto/nohave
fi
+if [ $version -lt 263680 ]; then
+    have=NGX_HAVE_REUSEPORT_CBPF . auto/nohave
+fi
+
# epoll, EPOLLET version
 ngx_feature="epoll"
diff -r da5e3f5b1673 -r f79d524a2cc0 auto/unix
--- a/auto/unix   Wed Sep 02 23:13:36 2020 +0300
+++ b/auto/unix               Thu Sep 10 06:54:53 2020 -0400
@@ -331,6 +331,17 @@
ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_REUSEPORT, NULL, 0)"
. auto/feature
+ngx_feature="SO_REUSEPORT_CBPF"
+ngx_feature_name="NGX_HAVE_REUSEPORT_CBPF"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+                  #include <linux/filter.h>
+                  #include <error.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, NULL, 0)"
+. auto/feature
+
 ngx_feature="SO_ACCEPTFILTER"
ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
diff -r da5e3f5b1673 -r f79d524a2cc0 src/core/ngx_connection.c
--- a/src/core/ngx_connection.c Wed Sep 02 23:13:36 2020 +0300
+++ b/src/core/ngx_connection.c              Thu Sep 10 06:54:53 2020 -0400
@@ -8,7 +8,10 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
-
+#if (NGX_HAVE_REUSEPORT_CBPF)
+#include <linux/filter.h>
+#include <error.h>
+#endif
 ngx_os_io_t  ngx_io;
@@ -708,6 +711,35 @@
     return NGX_OK;
}
+#if(NGX_HAVE_REUSEPORT)
+#if(NGX_HAVE_REUSEPORT_CBPF)
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+static void attach_bpf(int fd, uint16_t n)
+{
+             struct sock_filter code[] = {
+                            /* A = skb->queue_mapping */
+                            { BPF_LD  | BPF_W | BPF_ABS, 0, 0, SKF_AD_OFF + SKF_AD_QUEUE },
+                            /* A = A % n */
+                            { BPF_ALU | BPF_MOD, 0, 0, n },
+                            /* return A */
+                            { BPF_RET | BPF_A, 0, 0, 0 },
+             };
+             struct sock_fprog p = {
+                            .len = ARRAY_SIZE(code),
+                            .filter = code,
+             };
+
+             if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p)))
+                            printf("failed to set SO_ATTACH_REUSEPORT_CBPF");
+             else
+                            printf("bpf prog attached to fd:%d\n", fd);
+}
+#endif
+#endif
+
 void
ngx_configure_listening_sockets(ngx_cycle_t *cycle)
@@ -719,6 +751,11 @@
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
     struct accept_filter_arg   af;
#endif
+#if (NGX_HAVE_REUSEPORT)
+#if (NGX_HAVE_REUSEPORT_CBPF)
+        ngx_core_conf_t* ccf ;
+#endif
+#endif
     ls = cycle->listening.elts;
     for (i = 0; i < cycle->listening.nelts; i++) {
@@ -1011,6 +1048,16 @@
         }
 #endif
+#if (NGX_HAVE_REUSEPORT)
+#if (NGX_HAVE_REUSEPORT_CBPF)
+    if(ls[i].reuseport)
+    {
+        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,ngx_core_module);
+        if(ccf)
+            attach_bpf(ls[i].fd, ccf->worker_processes);
+    }
+#endif
+#endif
     }
     return;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20200910/9d7e3d3e/attachment.htm>


More information about the nginx-devel mailing list