diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-10-09 13:20:46 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-10-09 13:20:46 +0100 |
commit | b7092cda1b36ce687e65ab1831346f9529b781b8 (patch) | |
tree | 50a7bf08af03d1f2c17392ef48c80a56380d2397 /include | |
parent | 497d415d76b9f59fcae27f22df1ca2c3fa4df64e (diff) | |
parent | eb94b81a94bce112e6b206df846c1551aaf6cab6 (diff) | |
download | qemu-b7092cda1b36ce687e65ab1831346f9529b781b8.zip qemu-b7092cda1b36ce687e65ab1831346f9529b781b8.tar.gz qemu-b7092cda1b36ce687e65ab1831346f9529b781b8.tar.bz2 |
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2020-10-09' into staging
Monitor patches for 2020-10-09
# gpg: Signature made Fri 09 Oct 2020 06:16:51 BST
# gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg: issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653
* remotes/armbru/tags/pull-monitor-2020-10-09:
block: Convert 'block_resize' to coroutine
block: Add bdrv_lock()/unlock()
block: Add bdrv_co_enter()/leave()
util/async: Add aio_co_reschedule_self()
hmp: Add support for coroutine command handlers
qmp: Move dispatcher to a coroutine
qapi: Add a 'coroutine' flag for commands
monitor: Make current monitor a per-coroutine property
qmp: Call monitor_set_cur() only in qmp_dispatch()
qmp: Assert that no other monitor is active
hmp: Update current monitor only in handle_hmp_command()
monitor: Use getter/setter functions for cur_mon
monitor: Add Monitor parameter to monitor_get_cpu_index()
monitor: Add Monitor parameter to monitor_set_cpu()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/block/aio.h | 10 | ||||
-rw-r--r-- | include/block/block.h | 31 | ||||
-rw-r--r-- | include/monitor/monitor.h | 7 | ||||
-rw-r--r-- | include/qapi/qmp/dispatch.h | 5 |
4 files changed, 49 insertions, 4 deletions
diff --git a/include/block/aio.h b/include/block/aio.h index ec8c5af..5f34226 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -17,6 +17,7 @@ #ifdef CONFIG_LINUX_IO_URING #include <liburing.h> #endif +#include "qemu/coroutine.h" #include "qemu/queue.h" #include "qemu/event_notifier.h" #include "qemu/thread.h" @@ -655,6 +656,15 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external) void aio_co_schedule(AioContext *ctx, struct Coroutine *co); /** + * aio_co_reschedule_self: + * @new_ctx: the new context + * + * Move the currently running coroutine to new_ctx. If the coroutine is already + * running in new_ctx, do nothing. + */ +void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx); + +/** * aio_co_wake: * @co: the coroutine * diff --git a/include/block/block.h b/include/block/block.h index ce2ac39..d16c401 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -641,6 +641,37 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); AioContext *bdrv_get_aio_context(BlockDriverState *bs); /** + * Move the current coroutine to the AioContext of @bs and return the old + * AioContext of the coroutine. Increase bs->in_flight so that draining @bs + * will wait for the operation to proceed until the corresponding + * bdrv_co_leave(). + * + * Consequently, you can't call drain inside a bdrv_co_enter/leave() section as + * this will deadlock. + */ +AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs); + +/** + * Ends a section started by bdrv_co_enter(). Move the current coroutine back + * to old_ctx and decrease bs->in_flight again. + */ +void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx); + +/** + * Locks the AioContext of @bs if it's not the current AioContext. This avoids + * double locking which could lead to deadlocks: This is a coroutine_fn, so we + * know we already own the lock of the current AioContext. + * + * May only be called in the main thread. + */ +void coroutine_fn bdrv_co_lock(BlockDriverState *bs); + +/** + * Unlocks the AioContext of @bs if it's not the current AioContext. + */ +void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); + +/** * Transfer control to @co in the aio context of @bs */ void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co); diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index c017077..348bfad 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -5,7 +5,6 @@ #include "qapi/qapi-types-misc.h" #include "qemu/readline.h" -extern __thread Monitor *cur_mon; typedef struct MonitorHMP MonitorHMP; typedef struct MonitorOptions MonitorOptions; @@ -13,6 +12,8 @@ typedef struct MonitorOptions MonitorOptions; extern QemuOptsList qemu_mon_opts; +Monitor *monitor_cur(void); +Monitor *monitor_set_cur(Coroutine *co, Monitor *mon); bool monitor_cur_is_qmp(void); void monitor_init_globals(void); @@ -33,8 +34,8 @@ int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); int monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_flush(Monitor *mon); -int monitor_set_cpu(int cpu_index); -int monitor_get_cpu_index(void); +int monitor_set_cpu(Monitor *mon, int cpu_index); +int monitor_get_cpu_index(Monitor *mon); void monitor_read_command(MonitorHMP *mon, int show_prompt); int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func, diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 5a9cf82..af8d96c 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -14,6 +14,7 @@ #ifndef QAPI_QMP_DISPATCH_H #define QAPI_QMP_DISPATCH_H +#include "monitor/monitor.h" #include "qemu/queue.h" typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); @@ -24,11 +25,13 @@ typedef enum QmpCommandOptions QCO_NO_SUCCESS_RESP = (1U << 0), QCO_ALLOW_OOB = (1U << 1), QCO_ALLOW_PRECONFIG = (1U << 2), + QCO_COROUTINE = (1U << 3), } QmpCommandOptions; typedef struct QmpCommand { const char *name; + /* Runs in coroutine context if QCO_COROUTINE is set */ QmpCommandFunc *fn; QmpCommandOptions options; QTAILQ_ENTRY(QmpCommand) node; @@ -49,7 +52,7 @@ const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - bool allow_oob); + bool allow_oob, Monitor *cur_mon); bool qmp_is_oob(const QDict *dict); typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque); |