MINOR: config: add global tune.listener.multi-queue setting

tune.listener.multi-queue { on | off }
  Enables ('on') or disables ('off') the listener's multi-queue accept which
  spreads the incoming traffic to all threads a "bind" line is allowed to run
  on instead of taking them for itself. This provides a smoother traffic
  distribution and scales much better, especially in environments where threads
  may be unevenly loaded due to external activity (network interrupts colliding
  with one thread for example). This option is enabled by default, but it may
  be forcefully disabled for troubleshooting or for situations where it is
  estimated that the operating system already provides a good enough
  distribution and connections are extremely short-lived.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index aedced5..cd6ddf6 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1638,6 +1638,17 @@
   clicking). There should be not reason for changing this value. Please check
   tune.ssl.maxrecord below.
 
+tune.listener.multi-queue { on | off }
+  Enables ('on') or disables ('off') the listener's multi-queue accept which
+  spreads the incoming traffic to all threads a "bind" line is allowed to run
+  on instead of taking them for itself. This provides a smoother traffic
+  distribution and scales much better, especially in environments where threads
+  may be unevenly loaded due to external activity (network interrupts colliding
+  with one thread for example). This option is enabled by default, but it may
+  be forcefully disabled for troubleshooting or for situations where it is
+  estimated that the operating system already provides a good enough
+  distribution and connections are extremely short-lived.
+
 tune.lua.forced-yield <number>
   This directive forces the Lua engine to execute a yield each <number> of
   instructions executed. This permits interrupting a long script and allows the
diff --git a/include/types/global.h b/include/types/global.h
index b26553b..503d8f9 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -70,6 +70,7 @@
 #define GTUNE_USE_SYSTEMD        (1<<10)
 
 #define GTUNE_BUSY_POLLING       (1<<11)
+#define GTUNE_LISTENER_MQ        (1<<12)
 
 /* Access level for a stats socket */
 #define ACCESS_LVL_NONE     0
diff --git a/src/haproxy.c b/src/haproxy.c
index 9ae0939..c9aaa23 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -150,6 +150,7 @@
 		 }
 	},
 	.tune = {
+		.options = GTUNE_LISTENER_MQ,
 		.bufsize = (BUFSIZE + 2*sizeof(void *) - 1) & -(2*sizeof(void *)),
 		.maxrewrite = -1,
 		.chksize = (BUFSIZE + 2*sizeof(void *) - 1) & -(2*sizeof(void *)),
diff --git a/src/listener.c b/src/listener.c
index 0d7a1c4..504cbbf 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -818,7 +818,7 @@
 
 #if defined(USE_THREAD)
 		count = l->bind_conf->thr_count;
-		if (count > 1) {
+		if (count > 1 && (global.tune.options & GTUNE_LISTENER_MQ)) {
 			struct accept_queue_ring *ring;
 			int r, t1, t2, q1, q2;
 
@@ -1272,6 +1272,25 @@
 	return 0;
 }
 
+/* config parser for global "tune.listener.multi-queue", accepts "on" or "off" */
+static int cfg_parse_tune_listener_mq(char **args, int section_type, struct proxy *curpx,
+                                      struct proxy *defpx, const char *file, int line,
+                                      char **err)
+{
+	if (too_many_args(1, args, err, NULL))
+		return -1;
+
+	if (strcmp(args[1], "on") == 0)
+		global.tune.options |= GTUNE_LISTENER_MQ;
+	else if (strcmp(args[1], "off") == 0)
+		global.tune.options &= ~GTUNE_LISTENER_MQ;
+	else {
+		memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]);
+		return -1;
+	}
+	return 0;
+}
+
 /* Note: must not be declared <const> as its list will be overwritten.
  * Please take care of keeping this list alphabetically sorted.
  */
@@ -1314,6 +1333,14 @@
 
 INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
 
+/* config keyword parsers */
+static struct cfg_kw_list cfg_kws = {ILH, {
+	{ CFG_GLOBAL, "tune.listener.multi-queue",      cfg_parse_tune_listener_mq      },
+	{ 0, NULL, NULL }
+}};
+
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
+
 /*
  * Local variables:
  *  c-indent-level: 8