From: Willy Tarreau Date: Wed, 1 Jul 2020 14:39:33 +0000 (+0200) Subject: MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup() X-Git-Tag: v2.2-dev12~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=09e0d9ecbc49d33635f2b035864b086b317fa2dd;p=thirdparty%2Fhaproxy.git MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup() 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. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 3b21731a3d..ace04cb68f 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -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) {