aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-10-09 13:20:46 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-10-09 13:20:46 +0100
commitb7092cda1b36ce687e65ab1831346f9529b781b8 (patch)
tree50a7bf08af03d1f2c17392ef48c80a56380d2397 /include
parent497d415d76b9f59fcae27f22df1ca2c3fa4df64e (diff)
parenteb94b81a94bce112e6b206df846c1551aaf6cab6 (diff)
downloadqemu-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.h10
-rw-r--r--include/block/block.h31
-rw-r--r--include/monitor/monitor.h7
-rw-r--r--include/qapi/qmp/dispatch.h5
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);