]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup()
authorWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 14:39:33 +0000 (16:39 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 14:42:05 +0000 (16:42 +0200)
task_wakeup() passes the task through the global run queue under the
global RQ lock, which is expensive when dealing with large amounts of
h1_takeover() calls. Let's use the new task_kill() instead to kill the
task.

By doing so, a scenario involving approximately 130k takeover/s running on
16 threads gained almost 3% performance from 319k req/s to 328k.

src/mux_h1.c

index 3b21731a3d924a839dcc4e88a8c6c5154dfd9fd3..ace04cb68f31193ef1bebae38ddb2b8108c7e24c 100644 (file)
@@ -2926,6 +2926,7 @@ static int add_hdr_case_adjust(const char *from, const char *to, char **err)
 static int h1_takeover(struct connection *conn)
 {
        struct h1c *h1c = conn->ctx;
+       struct task *task;
 
        if (fd_takeover(conn->handle.fd, conn) != 0)
                return -1;
@@ -2937,10 +2938,13 @@ static int h1_takeover(struct connection *conn)
         */
        h1c->wait_event.tasklet->context = NULL;
        tasklet_wakeup(h1c->wait_event.tasklet);
-       if (h1c->task) {
-               h1c->task->context = NULL;
-               /* Wake the task, to let it free itself */
-               task_wakeup(h1c->task, TASK_WOKEN_OTHER);
+
+       task = h1c->task;
+       if (task) {
+               task->context = NULL;
+               h1c->task = NULL;
+               __ha_barrier_store();
+               task_kill(task);
 
                h1c->task = task_new(tid_bit);
                if (!h1c->task) {