mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
monitor: convert from oneshot BH to persistent BH
Convert monitor_accept_input from a oneshot BH (aio_bh_schedule_oneshot) to a persistent BH (aio_bh_new + qemu_bh_schedule). Oneshot BHs cannot be cancelled, so monitor_resume() racing with destruction would schedule a callback against memory that monitor_qmp_destroy() is about to free. A persistent BH can be deleted during destruction, cancelling any pending schedule. Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> [DB: extracted oneshot BH conversion from larger commit] Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-ID: <20260706135824.2623960-25-berrange@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
committed by
Markus Armbruster
parent
75f31e3a8a
commit
94c64bfb44
@@ -134,7 +134,7 @@ struct Monitor {
|
||||
char *chardev_id;
|
||||
CharFrontend chr;
|
||||
int suspend_cnt; /* Needs to be accessed atomically */
|
||||
|
||||
QEMUBH *accept_input_bh; /* persistent BH for monitor_accept_input */
|
||||
char *mon_cpu_path;
|
||||
QTAILQ_ENTRY(Monitor) entry;
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ static void monitor_finalize(Object *obj)
|
||||
{
|
||||
Monitor *mon = MONITOR(obj);
|
||||
|
||||
if (mon->accept_input_bh) {
|
||||
qemu_bh_delete(mon->accept_input_bh);
|
||||
}
|
||||
g_free(mon->chardev_id);
|
||||
g_free(mon->mon_cpu_path);
|
||||
qemu_chr_fe_deinit(&mon->chr, false);
|
||||
@@ -569,15 +572,7 @@ static void monitor_accept_input(void *opaque)
|
||||
void monitor_resume(Monitor *mon)
|
||||
{
|
||||
if (qatomic_dec_fetch(&mon->suspend_cnt) == 0) {
|
||||
AioContext *ctx;
|
||||
|
||||
if (monitor_requires_iothread(mon)) {
|
||||
ctx = iothread_get_aio_context(mon_iothread);
|
||||
} else {
|
||||
ctx = qemu_get_aio_context();
|
||||
}
|
||||
|
||||
aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon);
|
||||
qemu_bh_schedule(mon->accept_input_bh);
|
||||
}
|
||||
|
||||
trace_monitor_suspend(mon, -1);
|
||||
@@ -700,6 +695,7 @@ char *monitor_compat_id(void)
|
||||
static void monitor_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
Monitor *mon = MONITOR(uc);
|
||||
AioContext *ctx;
|
||||
|
||||
if (mon->chardev_id) {
|
||||
Chardev *chr = qemu_chr_find(mon->chardev_id);
|
||||
@@ -713,9 +709,16 @@ static void monitor_complete(UserCreatable *uc, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
if (monitor_requires_iothread(mon) && !mon_iothread) {
|
||||
mon_iothread = iothread_create("mon_iothread", &error_abort);
|
||||
if (monitor_requires_iothread(mon)) {
|
||||
if (!mon_iothread) {
|
||||
mon_iothread = iothread_create("mon_iothread", &error_abort);
|
||||
}
|
||||
|
||||
ctx = iothread_get_aio_context(mon_iothread);
|
||||
} else {
|
||||
ctx = qemu_get_aio_context();
|
||||
}
|
||||
mon->accept_input_bh = aio_bh_new(ctx, monitor_accept_input, mon);
|
||||
}
|
||||
|
||||
int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp)
|
||||
|
||||
Reference in New Issue
Block a user