[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 24/36] monitor: let suspend/resume work even with QMP
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PULL 24/36] monitor: let suspend/resume work even with QMPs |
Date: |
Mon, 12 Mar 2018 13:36:15 -0500 |
From: Peter Xu <address@hidden>
This patches allows QMP monitors to be suspended/resumed.
One thing to mention is that for QMPs that are using IOThreads, we need
an explicit kick for the IOThread in case it is sleeping.
Meanwhile, we need to take special care on non-interactive HMPs.
Currently only gdbserver is using that. For these monitors, we still
don't allow suspend/resume operations.
Since at it, add traces for the operations.
Signed-off-by: Peter Xu <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Eric Blake <address@hidden>
---
monitor.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
trace-events | 1 +
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/monitor.c b/monitor.c
index 608faf35c25..6b225e9fc5c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -250,6 +250,21 @@ static inline bool monitor_is_qmp(const Monitor *mon)
return (mon->flags & MONITOR_USE_CONTROL);
}
+/**
+ * Whether @mon is using readline? Note: not all HMP monitors use
+ * readline, e.g., gdbserver has a non-interactive HMP monitor, so
+ * readline is not used there.
+ */
+static inline bool monitor_uses_readline(const Monitor *mon)
+{
+ return mon->flags & MONITOR_USE_READLINE;
+}
+
+static inline bool monitor_is_hmp_non_interactive(const Monitor *mon)
+{
+ return !monitor_is_qmp(mon) && !monitor_uses_readline(mon);
+}
+
/**
* Is the current monitor, if any, a QMP monitor?
*/
@@ -3946,19 +3961,45 @@ static void monitor_command_cb(void *opaque, const char
*cmdline,
int monitor_suspend(Monitor *mon)
{
- if (!mon->rs)
+ if (monitor_is_hmp_non_interactive(mon)) {
return -ENOTTY;
+ }
+
atomic_inc(&mon->suspend_cnt);
+
+ if (monitor_is_qmp(mon)) {
+ /*
+ * Kick iothread to make sure this takes effect. It'll be
+ * evaluated again in prepare() of the watch object.
+ */
+ aio_notify(iothread_get_aio_context(mon_global.mon_iothread));
+ }
+
+ trace_monitor_suspend(mon, 1);
return 0;
}
void monitor_resume(Monitor *mon)
{
- if (!mon->rs)
+ if (monitor_is_hmp_non_interactive(mon)) {
return;
+ }
+
if (atomic_dec_fetch(&mon->suspend_cnt) == 0) {
- readline_show_prompt(mon->rs);
+ if (monitor_is_qmp(mon)) {
+ /*
+ * For QMP monitors that are running in IOThread, let's
+ * kick the thread in case it's sleeping.
+ */
+ if (mon->use_io_thr) {
+ aio_notify(iothread_get_aio_context(mon_global.mon_iothread));
+ }
+ } else {
+ assert(mon->rs);
+ readline_show_prompt(mon->rs);
+ }
}
+ trace_monitor_suspend(mon, -1);
}
static QObject *get_qmp_greeting(Monitor *mon)
diff --git a/trace-events b/trace-events
index 89fcad0fd13..fe10c3b487c 100644
--- a/trace-events
+++ b/trace-events
@@ -47,6 +47,7 @@ monitor_protocol_event_emit(uint32_t event, void *data)
"event=%d data=%p"
monitor_protocol_event_queue(uint32_t event, void *qdict, uint64_t rate)
"event=%d data=%p rate=%" PRId64
handle_hmp_command(void *mon, const char *cmdline) "mon %p cmdline: %s"
handle_qmp_command(void *mon, const char *req) "mon %p req: %s"
+monitor_suspend(void *ptr, int cnt) "mon %p: %d"
# dma-helpers.c
dma_blk_io(void *dbs, void *bs, int64_t offset, bool to_dev) "dbs=%p bs=%p
offset=%" PRId64 " to_dev=%d"
--
2.14.3
- [Qemu-devel] [PULL 17/36] monitor: move the cur_mon hack deeper for QMP, (continued)
- [Qemu-devel] [PULL 17/36] monitor: move the cur_mon hack deeper for QMP, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 10/36] block: Handle null backing link, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 13/36] qobject: introduce qstring_get_try_str(), Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 26/36] qmp: add new event "command-dropped", Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 19/36] monitor: let mon_list be tail queue, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 01/36] qapi2texi: minor python code simplification, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 12/36] docs: update QMP documents for OOB commands, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 14/36] qobject: introduce qobject_get_try_str(), Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 22/36] monitor: introduce monitor_qmp_respond(), Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 20/36] monitor: allow using IO thread for parsing, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 24/36] monitor: let suspend/resume work even with QMPs,
Eric Blake <=
- [Qemu-devel] [PULL 29/36] qmp: support out-of-band (oob) execution, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 32/36] qmp: add command "x-oob-test", Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 34/36] tests: qmp-test: add oob test, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 28/36] qapi: introduce new cmd option "allow-oob", Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 21/36] qmp: introduce QMPCapability, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 30/36] qmp: isolate responses into io thread, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 15/36] qobject: let object_property_get_str() use new API, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 23/36] monitor: let suspend_cnt be thread safe, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 27/36] monitor: send event when command queue full, Eric Blake, 2018/03/12
- [Qemu-devel] [PULL 25/36] monitor: separate QMP parser and dispatcher, Eric Blake, 2018/03/12