On Thu, Jun 27, 2024 at 2:32 AM Roman Kiryanov <r...@google.com> wrote:
> +        if (qatomic_read(&ts->cb_running)) {
> +            qemu_event_wait(&timer_list->timers_done_ev);
> +        }

qemu_event_wait() already has the right atomic magic, and
ts->cb_running is both redundant (in general), and I think racy (as
implemented in this patch). This stuff is really hard to get right. At
the very least you need a store-release when clearing the flag, and I
think it also has to be read under the mutex (I'm not sure if there's
anything else, I haven't done a full analysis).

But especially, you haven't justified in the commit message _why_ you
need this. Since this problem is not timer-specific, using
aio_bh_schedule_oneshot() or aio_wait_bh_oneshot() to synchronize
everything with the AioContext thread seems like a superior solution
to me.

Paolo

>      }
>  }
>
> @@ -571,9 +576,15 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
>          cb = ts->cb;
>          opaque = ts->opaque;
>
> +        /* prevent timer_del from returning while cb(opaque)
> +         * is still running (by waiting for timers_done_ev).
> +         */
> +        qatomic_set(&ts->cb_running, true);
> +
>          /* run the callback (the timer list can be modified) */
>          qemu_mutex_unlock(&timer_list->active_timers_lock);
>          cb(opaque);
> +        qatomic_set(&ts->cb_running, false);
>          qemu_mutex_lock(&timer_list->active_timers_lock);
>
>          progress = true;
> --
> 2.45.2.741.gdbec12cfda-goog
>


Reply via email to