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 | focaccia-qemu-b7092cda1b36ce687e65ab1831346f9529b781b8.tar.gz focaccia-qemu-b7092cda1b36ce687e65ab1831346f9529b781b8.zip | |
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 ec8c5af642..5f342267d5 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 ce2ac39299..d16c401cb4 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 c0170773d4..348bfad3d5 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 5a9cf82472..af8d96c570 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); |