diff options
author | Willy Tarreau <w@1wt.eu> | 2020-09-25 11:22:59 +0200 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2020-10-07 17:27:56 +0200 |
commit | 66700022fecd3e54b05fcbdadf13a30c088560f5 (patch) | |
tree | 40684897881db4bab0afeb9268f327e698a4d841 | |
parent | 0f68de2726eaa4b48924cd4a1cb4e09a0293a132 (diff) | |
download | haproxy-66700022fecd3e54b05fcbdadf13a30c088560f5.tar.gz |
MEDIUM: listeners: don't bounce listeners management between queues
During 2.1 development, commit f2cb16948 ("BUG/MAJOR: listener: fix
thread safety in resume_listener()") was introduced to bounce the
enabling/disabling of a listener's FD to one of its threads because
the remains of fd_update_cache() were fundamentally incompatible with
the need to call fd_want_recv() or fd_stop_recv() for another thread.
However since then we've totally dropped such code and it's totally
safe to use these functions on an FD that is solely used by another
thread (this is even used by the FD migration code). The only remaining
limitation concerning the wake up delay was addressed by previous commit
"MEDIUM: fd: always wake up one thread when enabling a foreing FD".
The current situation forces the FD management to remain in the
pause_listener() and resume_listener() functions just so that it can
bounce between threads, without having the ability to delegate it to
the suitable protocol layer.
So let's first remove this now unneeded workaround.
-rw-r--r-- | src/listener.c | 37 |
1 files changed, 0 insertions, 37 deletions
diff --git a/src/listener.c b/src/listener.c index ecad1f072..4b21f67a4 100644 --- a/src/listener.c +++ b/src/listener.c @@ -44,12 +44,6 @@ static struct bind_kw_list bind_keywords = { .list = LIST_HEAD_INIT(bind_keywords.list) }; -/* there is one listener queue per thread so that a thread unblocking the - * global queue can wake up listeners bound only to foreign threads by - * moving them to the remote queues and waking up the associated tasklet. - */ -static struct work_list *local_listener_queue; - /* list of the temporarily limited listeners because of lack of resource */ static struct mt_list global_listener_queue = MT_LIST_HEAD_INIT(global_listener_queue); static struct task *global_listener_queue_task; @@ -380,22 +374,11 @@ int resume_listener(struct listener *l) if (l->state == LI_READY) goto end; - MT_LIST_DEL(&l->wait_queue); - if (l->maxconn && l->nbconn >= l->maxconn) { l->state = LI_FULL; goto end; } - if (!(thread_mask(l->rx.settings->bind_thread) & tid_bit)) { - /* we're not allowed to touch this listener's FD, let's requeue - * the listener into one of its owning thread's queue instead. - */ - int first_thread = my_flsl(thread_mask(l->rx.settings->bind_thread) & all_threads_mask) - 1; - work_list_add(&local_listener_queue[first_thread], &l->wait_queue); - goto end; - } - fd_want_recv(l->rx.fd); l->state = LI_READY; end: @@ -1110,28 +1093,9 @@ void listener_release(struct listener *l) dequeue_proxy_listeners(fe); } -/* resume listeners waiting in the local listener queue. They are still in LI_LIMITED state */ -static struct task *listener_queue_process(struct task *t, void *context, unsigned short state) -{ - struct work_list *wl = context; - struct listener *l; - - while ((l = MT_LIST_POP(&wl->head, struct listener *, wait_queue))) { - /* The listeners are still in the LI_LIMITED state */ - resume_listener(l); - } - return t; -} - /* Initializes the listener queues. Returns 0 on success, otherwise ERR_* flags */ static int listener_queue_init() { - local_listener_queue = work_list_create(global.nbthread, listener_queue_process, NULL); - if (!local_listener_queue) { - ha_alert("Out of memory while initializing listener queues.\n"); - return ERR_FATAL|ERR_ABORT; - } - global_listener_queue_task = task_new(MAX_THREADS_MASK); if (!global_listener_queue_task) { ha_alert("Out of memory when initializing global listener queue\n"); @@ -1146,7 +1110,6 @@ static int listener_queue_init() static void listener_queue_deinit() { - work_list_destroy(local_listener_queue, global.nbthread); task_destroy(global_listener_queue_task); global_listener_queue_task = NULL; } |