|
From: | Maxim Davydov |
Subject: | Re: [PATCH v1 7/9] colo-compare: safe finalization |
Date: | Mon, 4 Apr 2022 18:20:48 +0300 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 |
On 3/30/22 17:54, Vladimir Sementsov-Ogievskiy wrote:
if colo_compare_active == false, event_mtx and event_complete_cond didn't inited in colo_compare_complete()29.03.2022 00:15, Maxim Davydov wrote:Fixes some possible issues with finalization. For example, finalization immediately after instance_init fails on the assert. Signed-off-by: Maxim Davydov <maxim.davydov@openvz.org> --- net/colo-compare.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/net/colo-compare.c b/net/colo-compare.c index 62554b5b3c..81d8de0aaa 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -1426,7 +1426,7 @@ static void colo_compare_finalize(Object *obj) break; } } - if (QTAILQ_EMPTY(&net_compares)) {
s->event_bh wasn't allocated in colo_compare_iothread() in colo_compare_complete()+ if (QTAILQ_EMPTY(&net_compares) && colo_compare_active) { colo_compare_active = false; qemu_mutex_destroy(&event_mtx); qemu_cond_destroy(&event_complete_cond); @@ -1442,19 +1442,26 @@ static void colo_compare_finalize(Object *obj) colo_compare_timer_del(s); - qemu_bh_delete(s->event_bh);
s->iothread == NULL after .instance_init (it can be detected in colo_compare_complete(), if it has been called)+ if (s->event_bh) { + qemu_bh_delete(s->event_bh); + } - AioContext *ctx = iothread_get_aio_context(s->iothread); - aio_context_acquire(ctx); - AIO_WAIT_WHILE(ctx, !s->out_sendco.done); - if (s->notify_dev) { - AIO_WAIT_WHILE(ctx, !s->notify_sendco.done);
In normal situation, it flushes all packets and sets s->out_sendco.done = true via compare_chr_send (we wait this event). But s->conn_list isn't initialized, s->out_sendco.done == false and won't become true. So, it's infinite waiting.+ if (s->iothread) { + AioContext *ctx = iothread_get_aio_context(s->iothread); + aio_context_acquire(ctx); + AIO_WAIT_WHILE(ctx, !s->out_sendco.done); + if (s->notify_dev) { + AIO_WAIT_WHILE(ctx, !s->notify_sendco.done); + } + aio_context_release(ctx); } - aio_context_release(ctx); /* Release all unhandled packets after compare thead exited */ g_queue_foreach(&s->conn_list, colo_flush_packets, s); - AIO_WAIT_WHILE(NULL, !s->out_sendco.done);
+ /* Without colo_compare_complete done == false without packets */ + if (!g_queue_is_empty(&s->out_sendco.send_list)) { + AIO_WAIT_WHILE(NULL, !s->out_sendco.done); + }I think, would be good to add more description for this last change. It's not as obvious as previous two changes.g_queue_clear(&s->conn_list); g_queue_clear(&s->out_sendco.send_list);
-- Best regards, Maxim Davydov
[Prev in Thread] | Current Thread | [Next in Thread] |