From nobody Wed Nov 5 16:17:58 2025 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1535101924547612.6643388363765; Fri, 24 Aug 2018 02:12:04 -0700 (PDT) Received: from localhost ([::1]:40579 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ft88R-0003N1-Fo for importer@patchew.org; Fri, 24 Aug 2018 05:12:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56833) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ft85C-0008A5-GN for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:08:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ft85A-0005xR-UZ for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:08:42 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:37114 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ft85A-0005x9-P0 for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:08:40 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6E45D87A74 for ; Fri, 24 Aug 2018 09:08:40 +0000 (UTC) Received: from xz-x1.redhat.com (ovpn-12-107.pek2.redhat.com [10.72.12.107]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4EE1D10EE6D0; Fri, 24 Aug 2018 09:08:35 +0000 (UTC) From: Peter Xu To: qemu-devel@nongnu.org Date: Fri, 24 Aug 2018 17:08:24 +0800 Message-Id: <20180824090826.21370-2-peterx@redhat.com> In-Reply-To: <20180824090826.21370-1-peterx@redhat.com> References: <20180824090826.21370-1-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 24 Aug 2018 09:08:40 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 24 Aug 2018 09:08:40 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'peterx@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC 1/3] chardev: introduce chardev contexts 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: Markus Armbruster , peterx@redhat.com, "Dr . David Alan Gilbert" , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce contexts in chardev layer. Normally chardevs are running with the main context except the monitors. Let's create the first standalone context for the monitors. Note that this does not mean the chardev backend will depend on the monitor code, but it's just a naming that let people know this context should only be used by monitors. This patch itself should not have any functional change (we'll create a new iothread that managed by chardev module, but no one is currently using it), however after this patch we should be able to specify the context for a chardev by using a qemu_opt_set_number() onto the QemuOps before the chardev backend is created. Signed-off-by: Peter Xu --- chardev/char.c | 73 +++++++++++++++++++++++++++++++++++++++--- gdbstub.c | 2 +- hw/bt/hci-csr.c | 2 +- include/chardev/char.h | 15 ++++++++- tests/test-char.c | 4 +-- 5 files changed, 86 insertions(+), 10 deletions(-) diff --git a/chardev/char.c b/chardev/char.c index 76d866e6fe..c98d245ef7 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -41,6 +41,13 @@ /***********************************************************/ /* character device */ =20 +typedef struct { + IOThread *iothread; + GMainContext *gcontext; +} ChardevContextMap; + +static ChardevContextMap *chr_context_table; + static Object *get_chardevs_root(void) { return container_get(object_get_root(), "/chardevs"); @@ -623,6 +630,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) const char *name =3D chardev_alias_translate(qemu_opt_get(opts, "backe= nd")); const char *id =3D qemu_opts_id(opts); char *bid =3D NULL; + ChardevContext context; =20 if (name && is_help_option(name)) { GString *str =3D g_string_new(""); @@ -634,6 +642,8 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) return NULL; } =20 + context =3D qemu_opt_get_number(opts, "context", CHR_CONTEXT_MAIN); + if (id =3D=3D NULL) { error_setg(errp, "chardev: no id specified"); return NULL; @@ -655,7 +665,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) =20 chr =3D qemu_chardev_new(bid ? bid : id, object_class_get_name(OBJECT_CLASS(cc)), - backend, errp); + backend, context, errp); =20 if (chr =3D=3D NULL) { goto out; @@ -668,7 +678,8 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) backend->type =3D CHARDEV_BACKEND_KIND_MUX; backend->u.mux.data =3D g_new0(ChardevMux, 1); backend->u.mux.data->chardev =3D g_strdup(bid); - mux =3D qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, errp); + mux =3D qemu_chardev_new(id, TYPE_CHARDEV_MUX, + backend, CHR_CONTEXT_MAIN, errp); if (mux =3D=3D NULL) { object_unparent(OBJECT(chr)); chr =3D NULL; @@ -876,6 +887,10 @@ QemuOptsList qemu_chardev_opts =3D { },{ .name =3D "logappend", .type =3D QEMU_OPT_BOOL, + },{ + /* TODO: should only be used internally */ + .name =3D "context", + .type =3D QEMU_OPT_NUMBER, }, { /* end of list */ } }, @@ -893,8 +908,42 @@ void qemu_chr_set_feature(Chardev *chr, return set_bit(feature, chr->features); } =20 +static void qemu_chr_context_init(void) +{ + if (!chr_context_table) { + ChardevContext i; + ChardevContextMap *map; + + chr_context_table =3D g_new0(ChardevContextMap, CHR_CONTEXT_MAX); + + /* This stands for the main context */ + chr_context_table[0].iothread =3D NULL; + chr_context_table[0].gcontext =3D NULL; + + for (i =3D 1; i < CHR_CONTEXT_MAX; i++) { + map =3D &chr_context_table[i]; + map->iothread =3D iothread_create("chr_iothread", &error_abort= ); + map->gcontext =3D iothread_get_g_main_context(map->iothread); + } + } +} + +IOThread *qemu_chr_iothread_get(ChardevContext context) +{ + assert(context >=3D 0 && context < CHR_CONTEXT_MAX); + qemu_chr_context_init(); + return chr_context_table[context].iothread; +} + +GMainContext *qemu_chr_context_get(ChardevContext context) +{ + assert(context >=3D 0 && context < CHR_CONTEXT_MAX); + qemu_chr_context_init(); + return chr_context_table[context].gcontext; +} + Chardev *qemu_chardev_new(const char *id, const char *typename, - ChardevBackend *backend, + ChardevBackend *backend, ChardevContext context, Error **errp) { Object *obj; @@ -907,6 +956,7 @@ Chardev *qemu_chardev_new(const char *id, const char *t= ypename, obj =3D object_new(typename); chr =3D CHARDEV(obj); chr->label =3D g_strdup(id); + chr->gcontext =3D qemu_chr_context_get(context); =20 qemu_char_open(chr, backend, &be_opened, &local_err); if (local_err) { @@ -951,7 +1001,7 @@ ChardevReturn *qmp_chardev_add(const char *id, Chardev= Backend *backend, } =20 chr =3D qemu_chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), - backend, errp); + backend, CHR_CONTEXT_MAIN, errp); if (!chr) { return NULL; } @@ -1009,7 +1059,7 @@ ChardevReturn *qmp_chardev_change(const char *id, Cha= rdevBackend *backend, } =20 chr_new =3D qemu_chardev_new(NULL, object_class_get_name(OBJECT_CLASS(= cc)), - backend, errp); + backend, CHR_CONTEXT_MAIN, errp); if (!chr_new) { return NULL; } @@ -1102,6 +1152,19 @@ GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint= ms, void qemu_chr_cleanup(void) { object_unparent(get_chardevs_root()); + + if (chr_context_table) { + ChardevContext i; + ChardevContextMap *map; + for (i =3D 1; i < CHR_CONTEXT_MAX; i++) { + map =3D &chr_context_table[i]; + map->gcontext =3D NULL; + iothread_destroy(map->iothread); + map->iothread =3D NULL; + } + g_free(chr_context_table); + chr_context_table =3D NULL; + } } =20 static void register_types(void) diff --git a/gdbstub.c b/gdbstub.c index d6ab95006c..777cb257d7 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2052,7 +2052,7 @@ int gdbserver_start(const char *device) =20 /* Initialize a monitor terminal for gdb */ mon_chr =3D qemu_chardev_new(NULL, TYPE_CHARDEV_GDB, - NULL, &error_abort); + NULL, CHR_CONTEXT_MAIN, &error_abort); monitor_init(mon_chr, 0); } else { qemu_chr_fe_deinit(&s->chr, true); diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 0341ded50c..0e36b63301 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -501,7 +501,7 @@ static const TypeInfo char_hci_type_info =3D { Chardev *uart_hci_init(void) { return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI, - NULL, &error_abort); + NULL, CHR_CONTEXT_MAIN, &error_abort); } =20 static void register_types(void) diff --git a/include/chardev/char.h b/include/chardev/char.h index 6f0576e214..e83b93e707 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -5,6 +5,7 @@ #include "qemu/main-loop.h" #include "qemu/bitmap.h" #include "qom/object.h" +#include "sysemu/iothread.h" =20 #define IAC_EOR 239 #define IAC_SE 240 @@ -67,6 +68,15 @@ struct Chardev { DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); }; =20 +/* This decides the customized context to run the chardev */ +typedef enum { + /* Run the chardev in the main context (NULL) */ + CHR_CONTEXT_MAIN, + /* Run the chardev in the monitor specific context */ + CHR_CONTEXT_MONITOR, + CHR_CONTEXT_MAX, +} ChardevContext; + /** * @qemu_chr_new_from_opts: * @@ -262,7 +272,10 @@ typedef struct ChardevClass { } ChardevClass; =20 Chardev *qemu_chardev_new(const char *id, const char *typename, - ChardevBackend *backend, Error **errp); + ChardevBackend *backend, ChardevContext context, + Error **errp); +IOThread *qemu_chr_iothread_get(ChardevContext context); +GMainContext *qemu_chr_context_get(ChardevContext context); =20 extern int term_escape_char; =20 diff --git a/tests/test-char.c b/tests/test-char.c index 5905d31441..ae95e1e3b7 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -593,7 +593,7 @@ static void char_file_fifo_test(void) g_assert_cmpint(ret, =3D=3D, 8); =20 chr =3D qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend, - &error_abort); + CHR_CONTEXT_MAIN, &error_abort); =20 qemu_chr_fe_init(&be, chr, &error_abort); qemu_chr_fe_set_handlers(&be, @@ -647,7 +647,7 @@ static void char_file_test_internal(Chardev *ext_chr, c= onst char *filepath) out =3D g_build_filename(tmp_path, "out", NULL); file.out =3D out; chr =3D qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, - &error_abort); + CHR_CONTEXT_MAIN, &error_abort); } ret =3D qemu_chr_write_all(chr, (uint8_t *)"hello!", 6); g_assert_cmpint(ret, =3D=3D, 6); --=20 2.17.1