From nobody Mon Feb 9 09:52:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1509962453113546.872750092563; Mon, 6 Nov 2017 02:00:53 -0800 (PST) Received: from localhost ([::1]:47236 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eBeD4-0006r0-9p for importer@patchew.org; Mon, 06 Nov 2017 05:00:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eBe1z-0005BS-Tm for qemu-devel@nongnu.org; Mon, 06 Nov 2017 04:49:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eBe1u-0004Ws-SU for qemu-devel@nongnu.org; Mon, 06 Nov 2017 04:49:23 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44602) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eBe1u-0004WT-Kk for qemu-devel@nongnu.org; Mon, 06 Nov 2017 04:49:18 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A21FDC058EC2; Mon, 6 Nov 2017 09:49:17 +0000 (UTC) Received: from pxdev.xzpeter.org.com (ovpn-12-165.pek2.redhat.com [10.72.12.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4287E614FF; Mon, 6 Nov 2017 09:49:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A21FDC058EC2 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=peterx@redhat.com From: Peter Xu To: qemu-devel@nongnu.org Date: Mon, 6 Nov 2017 17:46:27 +0800 Message-Id: <20171106094643.14881-12-peterx@redhat.com> In-Reply-To: <20171106094643.14881-1-peterx@redhat.com> References: <20171106094643.14881-1-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 06 Nov 2017 09:49:17 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v3 11/27] monitor: allow to use IO thread for parsing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Fam Zheng , Juan Quintela , mdroth@linux.vnet.ibm.com, peterx@redhat.com, Markus Armbruster , marcandre.lureau@redhat.com, Stefan Hajnoczi , Paolo Bonzini , Jiri Denemark , "Dr . David Alan Gilbert" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" For each Monitor, add one field "use_io_thr" to show whether it will be using the dedicated monitor IO thread to handle input/output. When set, monitor IO parsing work will be offloaded to dedicated monitor IO thread, rather than the original main loop thread. This only works for QMP. HMP will always be run on main loop thread. Currently we're still keeping use_io_thr to off always. Will turn it on later at some point. One thing to mention is that we cannot set use_io_thr for every QMP monitors. The problem is that MUXed typed chardevs may not work well with it now. When MUX is used, frontend of chardev can be the monitor plus something else. The only thing we know would be safe to be run outside main thread so far is the monitor frontend. All the rest of the frontends should still be run in main thread only. Signed-off-by: Peter Xu Reviewed-by: Fam Zheng --- monitor.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index df1ec8d037..7255c110f9 100644 --- a/monitor.c +++ b/monitor.c @@ -191,6 +191,7 @@ struct Monitor { int flags; int suspend_cnt; bool skip_flush; + bool use_io_thr; =20 QemuMutex out_lock; QString *outbuf; @@ -575,7 +576,8 @@ static void monitor_qapi_event_init(void) =20 static void handle_hmp_command(Monitor *mon, const char *cmdline); =20 -static void monitor_data_init(Monitor *mon, bool skip_flush) +static void monitor_data_init(Monitor *mon, bool skip_flush, + bool use_io_thr) { memset(mon, 0, sizeof(Monitor)); qemu_mutex_init(&mon->out_lock); @@ -583,6 +585,7 @@ static void monitor_data_init(Monitor *mon, bool skip_f= lush) /* Use *mon_cmds by default. */ mon->cmd_table =3D mon_cmds; mon->skip_flush =3D skip_flush; + mon->use_io_thr =3D use_io_thr; } =20 static void monitor_data_destroy(Monitor *mon) @@ -603,7 +606,7 @@ char *qmp_human_monitor_command(const char *command_lin= e, bool has_cpu_index, char *output =3D NULL; Monitor *old_mon, hmp; =20 - monitor_data_init(&hmp, true); + monitor_data_init(&hmp, true, false); =20 old_mon =3D cur_mon; cur_mon =3D &hmp; @@ -4109,8 +4112,9 @@ void error_vprintf_unless_qmp(const char *fmt, va_lis= t ap) void monitor_init(Chardev *chr, int flags) { Monitor *mon =3D g_malloc(sizeof(*mon)); + GMainContext *context; =20 - monitor_data_init(mon, false); + monitor_data_init(mon, false, false); =20 qemu_chr_fe_init(&mon->chr, chr, &error_abort); mon->flags =3D flags; @@ -4122,19 +4126,37 @@ void monitor_init(Chardev *chr, int flags) monitor_read_command(mon, 0); } =20 + if (mon->use_io_thr) { + /* + * When use_io_thr is set, we use the global shared dedicated + * IO thread for this monitor to handle input/output. + */ + context =3D monitor_io_context_get(); + /* We should have inited globals before reaching here. */ + assert(context); + } else { + /* The default main loop, which is the main thread */ + context =3D NULL; + } + + /* + * Add the monitor before running it (which is triggered by + * qemu_chr_fe_set_handlers), otherwise one monitor may find + * itself not on the mon_list when running. + */ + qemu_mutex_lock(&monitor_lock); + QTAILQ_INSERT_HEAD(&mon_list, mon, entry); + qemu_mutex_unlock(&monitor_lock); + if (monitor_is_qmp(mon)) { qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_qmp_= read, - monitor_qmp_event, NULL, mon, NULL, true); + monitor_qmp_event, NULL, mon, context, tr= ue); qemu_chr_fe_set_echo(&mon->chr, true); json_message_parser_init(&mon->qmp.parser, handle_qmp_command, mon= ); } else { qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_read, monitor_event, NULL, mon, NULL, true); } - - qemu_mutex_lock(&monitor_lock); - QLIST_INSERT_HEAD(&mon_list, mon, entry); - qemu_mutex_unlock(&monitor_lock); } =20 void monitor_cleanup(void) --=20 2.13.5