From nobody Sun Apr 28 13:06:19 2024 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.zoho.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 1489017617283647.145547650874; Wed, 8 Mar 2017 16:00:17 -0800 (PST) Received: from localhost ([::1]:59198 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cllV8-0005Oy-92 for importer@patchew.org; Wed, 08 Mar 2017 19:00:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35593) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cllUg-0005Mv-9k for qemu-devel@nongnu.org; Wed, 08 Mar 2017 18:59:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cllUc-0001uq-Ch for qemu-devel@nongnu.org; Wed, 08 Mar 2017 18:59:46 -0500 Received: from mail.kernel.org ([198.145.29.136]:56776) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cllUc-0001uO-3d for qemu-devel@nongnu.org; Wed, 08 Mar 2017 18:59:42 -0500 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9EBDA204C9; Wed, 8 Mar 2017 23:59:38 +0000 (UTC) Received: from redhat.com (pool-96-237-235-121.bstnma.fios.verizon.net [96.237.235.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 23069204B0; Wed, 8 Mar 2017 23:59:37 +0000 (UTC) Date: Thu, 9 Mar 2017 01:59:35 +0200 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Message-ID: <1489017212-2990-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Mailer: git-send-email 2.8.0.287.g0deeb61 X-Mutt-Fcc: =sent X-Virus-Scanned: ClamAV using ClamSMTP X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 198.145.29.136 Subject: [Qemu-devel] [PATCH RFC] qdev: add init order filter 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: Peter Maydell , Paolo Bonzini , Marcel Apfelbaum 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 Content-Type: text/plain; charset="utf-8" Allow forcing a specific order of initialization on devices created with -device. Helpful e.g. for built-in devices such as IOMMUs which must exist before all other devices. Signed-off-by: Michael S. Tsirkin --- Looks like we have a ton of problems because devices are initialized in a random order, while we really want e.g. iommu to be initialized earlier than devices. This will be helpful for other things, e.g. real hardware often is initialized in a specific order, creating built-in devices for the board often has to happen in a specific order, etc. We could then stop trying to do things at machine done time and simply set initialization order. The following patch achieves this for devices created with -device but unfortunately not others (e.g. not -net nic, etc). Thoughts on the best way to complete this would be appreciated. As you can see this patch is small enough for 2.9 and it might be a good idea considering the pile of hacks we have pending as a replacement. include/hw/qdev-core.h | 10 ++++++++++ include/monitor/qdev.h | 2 +- qdev-monitor.c | 9 +++++++-- vl.c | 15 ++++++++++----- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index b44b476..5704b67 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -40,6 +40,13 @@ typedef void (*BusUnrealize)(BusState *bus, Error **errp= ); =20 struct VMStateDescription; =20 +typedef enum DeviceInitOrder { + DEVICE_INIT_ORDER_MIN =3D -1, + DEVICE_INIT_ORDER_EARLY =3D -1, + DEVICE_INIT_ORDER_DEFAULT =3D 0, + DEVICE_INIT_ORDER_MAX =3D 0, +} DeviceInitOrder; + /** * DeviceClass: * @props: Properties accessing state fields. @@ -128,6 +135,9 @@ typedef struct DeviceClass { =20 bool hotpluggable; =20 + /* init order. Only affects devices created with -device at this point= */ + DeviceInitOrder init_order; + /* callbacks */ void (*reset)(DeviceState *dev); DeviceRealize realize; diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index 0ff3331..af2dc67 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -11,7 +11,7 @@ void hmp_info_qom_tree(Monitor *mon, const QDict *dict); void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp); =20 int qdev_device_help(QemuOpts *opts); -DeviceState *qdev_device_add(QemuOpts *opts, Error **errp); +DeviceState *qdev_device_add(QemuOpts *opts, int init_order, Error **errp); void qdev_set_id(DeviceState *dev, const char *id); =20 #endif diff --git a/qdev-monitor.c b/qdev-monitor.c index 549f45f..657f89d 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -559,7 +559,7 @@ void qdev_set_id(DeviceState *dev, const char *id) } } =20 -DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) +DeviceState *qdev_device_add(QemuOpts *opts, int init_order, Error **errp) { DeviceClass *dc; const char *driver, *path; @@ -579,6 +579,11 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **e= rrp) return NULL; } =20 + if (dc->init_order !=3D init_order) { + /* Not an error - will be initialized with correct order */ + return NULL; + } + if (only_migratable) { if (dc->vmsd->unmigratable) { error_setg(errp, "Device %s is not migratable, but " @@ -807,7 +812,7 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, E= rror **errp) qemu_opts_del(opts); return; } - dev =3D qdev_device_add(opts, &local_err); + dev =3D qdev_device_add(opts, DEVICE_INIT_ORDER_DEFAULT, &local_err); if (!dev) { error_propagate(errp, local_err); qemu_opts_del(opts); diff --git a/vl.c b/vl.c index e10a27b..d77fbc9 100644 --- a/vl.c +++ b/vl.c @@ -2300,11 +2300,14 @@ static int device_init_func(void *opaque, QemuOpts = *opts, Error **errp) { Error *err =3D NULL; DeviceState *dev; + int init_order =3D (intptr_t)opaque; =20 - dev =3D qdev_device_add(opts, &err); - if (!dev) { + dev =3D qdev_device_add(opts, init_order, &err); + if (!dev && err) { error_report_err(err); return -1; + } else if (!dev) { + return 0; } object_unref(OBJECT(dev)); return 0; @@ -4546,9 +4549,11 @@ int main(int argc, char **argv, char **envp) =20 /* init generic devices */ rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE); - if (qemu_opts_foreach(qemu_find_opts("device"), - device_init_func, NULL, NULL)) { - exit(1); + for (i =3D DEVICE_INIT_ORDER_MIN; i <=3D DEVICE_INIT_ORDER_MAX; ++i) { + if (qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, (void *)(intptr_t)i, NULL)= ) { + exit(1); + } } =20 cpu_synchronize_all_post_init(); --=20 MST