]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: backend: hold correctly lock when killing idle conn
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 28 Jan 2021 09:16:29 +0000 (10:16 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 12 Feb 2021 11:32:31 +0000 (12:32 +0100)
The wrong lock seems to be held when trying to remove another thread
connection if max fd limit has been reached (locking the current thread
instead of the target thread lock).

This could be backported up to 2.0.

src/backend.c

index f6afde358de5360acc78f6ee3fcd0fef2871d39a..7a1d1796839ac0fc9df7d7e8756e9d9940cad76f 100644 (file)
@@ -1350,22 +1350,23 @@ int connect_server(struct stream *s)
                                // see it possibly larger.
                                ALREADY_CHECKED(i);
 
-                               HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock);
+                               HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[i].takeover_lock);
                                tokill_conn = MT_LIST_POP(&srv->idle_conns[i],
                                    struct connection *, list);
                                if (!tokill_conn)
                                        tokill_conn = MT_LIST_POP(&srv->safe_conns[i],
                                            struct connection *, list);
+
                                if (tokill_conn) {
                                        /* We got one, put it into the concerned thread's to kill list, and wake it's kill task */
 
                                        MT_LIST_ADDQ(&idle_conns[i].toremove_conns,
                                            (struct mt_list *)&tokill_conn->list);
                                        task_wakeup(idle_conns[i].cleanup_task, TASK_WOKEN_OTHER);
-                                       HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock);
+                                       HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[i].takeover_lock);
                                        break;
                                }
-                               HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].takeover_lock);
+                               HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[i].takeover_lock);
                        }
                }