All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhao Liu <zhao1.liu@linux.intel.com>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
	"Yanan Wang" <wangyanan55@huawei.com>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	"Jason Wang" <jasowang@redhat.com>,
	"Nicholas Piggin" <npiggin@gmail.com>,
	"Daniel Henrique Barboza" <danielhb413@gmail.com>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"Cédric Le Goater" <clg@kaod.org>,
	"Frédéric Barrat" <fbarrat@linux.ibm.com>,
	"David Gibson" <david@gibson.dropbear.id.au>,
	"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Anthony Perard" <anthony.perard@citrix.com>,
	"Paul Durrant" <paul@xen.org>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Alistair Francis" <alistair@alistair23.me>,
	"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>,
	"Bin Meng" <bin.meng@windriver.com>,
	"Palmer Dabbelt" <palmer@dabbelt.com>,
	"Weiwei Li" <liwei1518@gmail.com>,
	"Liu Zhiwei" <zhiwei_liu@linux.alibaba.com>,
	qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org,
	xen-devel@lists.xenproject.org, qemu-arm@nongnu.org,
	qemu-riscv@nongnu.org, qemu-s390x@nongnu.org
Cc: Nina Schoetterl-Glausch <nsg@linux.ibm.com>,
	Thomas Huth <thuth@redhat.com>, Zhiyuan Lv <zhiyuan.lv@intel.com>,
	Zhenyu Wang <zhenyu.z.wang@intel.com>,
	Yongwei Ma <yongwei.ma@intel.com>, Zhao Liu <zhao1.liu@intel.com>
Subject: [RFC 06/41] qdev: Introduce user-child interface to collect devices from -device
Date: Thu, 30 Nov 2023 22:41:28 +0800	[thread overview]
Message-ID: <20231130144203.2307629-7-zhao1.liu@linux.intel.com> (raw)
In-Reply-To: <20231130144203.2307629-1-zhao1.liu@linux.intel.com>

From: Zhao Liu <zhao1.liu@intel.com>

Topology relationship is based on child<> property, therefore introduce
a new user-child interface to help bus-less devices create child<>
property from cli.

User-child interface works in qdev_set_id(), where the child<> property
is created for cli devices.

With several methods, user-child could provide the specific "parent"
device other than the default peripheral/peripheral-anon container.

The topology root (cpu-slot) could collect topology devices based on
user-child implementation.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 MAINTAINERS                  |  2 +
 include/monitor/user-child.h | 57 +++++++++++++++++++++++
 include/qom/object.h         | 11 +++++
 qom/object.c                 | 13 ++++++
 system/meson.build           |  1 +
 system/qdev-monitor.c        | 89 +++++++++++++++++++++++++++++++++---
 system/user-child.c          | 72 +++++++++++++++++++++++++++++
 7 files changed, 239 insertions(+), 6 deletions(-)
 create mode 100644 include/monitor/user-child.h
 create mode 100644 system/user-child.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 695e0bd34fbb..fdbabaa983cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3208,12 +3208,14 @@ F: hw/core/bus.c
 F: hw/core/sysbus.c
 F: include/hw/qdev*
 F: include/monitor/qdev.h
+F: include/monitor/user-child.h
 F: include/qom/
 F: qapi/qom.json
 F: qapi/qdev.json
 F: scripts/coccinelle/qom-parent-type.cocci
 F: scripts/qom-cast-macro-clean-cocci-gen.py
 F: system/qdev-monitor.c
+F: system/user-child.c
 F: stubs/qdev.c
 F: qom/
 F: tests/unit/check-qom-interface.c
diff --git a/include/monitor/user-child.h b/include/monitor/user-child.h
new file mode 100644
index 000000000000..e246fcefe40a
--- /dev/null
+++ b/include/monitor/user-child.h
@@ -0,0 +1,57 @@
+/*
+ * Child configurable interface header.
+ *
+ * Copyright (c) 2023 Intel Corporation
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef USER_CHILD_H
+#define USER_CHILD_H
+
+#include "qom/object.h"
+
+#define TYPE_USER_CHILD "user-child"
+
+typedef struct UserChildClass UserChildClass;
+DECLARE_CLASS_CHECKERS(UserChildClass, USER_CHILD, TYPE_USER_CHILD)
+#define USER_CHILD(obj) INTERFACE_CHECK(UserChild, (obj), TYPE_USER_CHILD)
+
+typedef struct UserChild UserChild;
+
+/**
+ * UserChildClass:
+ * @get_parent: Method to get the default parent if user doesn't specify
+ *     the parent in cli.
+ * @get_child_name: Method to get the default device id for this device
+ *     if user doesn't specify id in cli.
+ * @check_parent: Method to check if the parent specified by user in cli
+ *     is valid.
+ */
+struct UserChildClass {
+    /* <private> */
+    InterfaceClass parent_class;
+
+    /* <public> */
+    Object *(*get_parent)(UserChild *uc, Error **errp);
+    char *(*get_child_name)(UserChild *uc, Object *parent);
+    bool (*check_parent)(UserChild *uc, Object *parent);
+};
+
+Object *uc_provide_default_parent(Object *obj, Error **errp);
+char *uc_name_future_child(Object *obj, Object *parent);
+bool uc_check_user_parent(Object *obj, Object *parent);
+
+#endif /* USER_CHILD_H */
diff --git a/include/qom/object.h b/include/qom/object.h
index 494eef801be3..f725d9452c76 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1484,6 +1484,17 @@ Object *object_get_objects_root(void);
  */
 Object *object_get_internal_root(void);
 
+/**
+ * object_is_child_from:
+ * @child: the object.
+ * @parent: the parent/non-direct parent object.
+ *
+ * Check whether @parent is the parent/non-direct parent of @child.
+ *
+ * Returns: true iff @parent is the parent/non-direct parent of @child.
+ */
+bool object_is_child_from(const Object *child, const Object *parent);
+
 /**
  * object_get_canonical_path_component:
  * @obj: the object
diff --git a/qom/object.c b/qom/object.c
index da29e88816b5..d6f55aa59504 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2024,6 +2024,19 @@ object_property_add_const_link(Object *obj, const char *name,
                                 NULL, OBJ_PROP_LINK_DIRECT);
 }
 
+bool object_is_child_from(const Object *child, const Object *parent)
+{
+    Object *obj = child->parent;
+
+    while (obj) {
+        if (obj == parent) {
+            return true;
+        }
+        obj = obj->parent;
+    }
+    return false;
+}
+
 const char *object_get_canonical_path_component(const Object *obj)
 {
     ObjectProperty *prop = NULL;
diff --git a/system/meson.build b/system/meson.build
index 3a64dd89de1f..ac682a3ca9e1 100644
--- a/system/meson.build
+++ b/system/meson.build
@@ -24,6 +24,7 @@ system_ss.add(files(
   'runstate-hmp-cmds.c',
   'runstate.c',
   'tpm-hmp-cmds.c',
+  'user-child.c',
   'vl.c',
 ), sdl, libpmem, libdaxctl)
 
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 107411bb50cc..0261937b8462 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -22,6 +22,7 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
+#include "monitor/user-child.h"
 #include "sysemu/arch_init.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
@@ -585,26 +586,93 @@ static BusState *qbus_find(const char *path, Error **errp)
     return bus;
 }
 
+static Object *qdev_find_peripheral_parent(DeviceState *dev,
+                                           Error **errp)
+{
+    Object *parent_obj, *obj = OBJECT(dev);
+
+    parent_obj = uc_provide_default_parent(obj, errp);
+    if (*errp) {
+        return NULL;
+    }
+
+    if (parent_obj) {
+        /*
+         * Non-anonymous parents (under "/peripheral") are allowed to
+         * be accessed to create child<> properties.
+         */
+        if (object_is_child_from(parent_obj, qdev_get_peripheral())) {
+            return parent_obj;
+        }
+    }
+
+    return NULL;
+}
+
+static bool qdev_pre_check_device_id(char *id, Error **errp)
+{
+    bool ambiguous = false;
+    Object *obj;
+
+    if (!id) {
+        return true;
+    }
+
+    obj = object_resolve_path_from(qdev_get_peripheral(), id, &ambiguous);
+    if (obj || ambiguous) {
+        error_setg(errp, "Duplicate device default ID '%s'. "
+                   "Please specify another 'id'", id);
+        return false;
+    }
+    return true;
+}
+
 /* Takes ownership of @id, will be freed when deleting the device */
 const char *qdev_set_id(DeviceState *dev, char *id, Error **errp)
 {
+    Object *parent_obj = NULL;
     ObjectProperty *prop;
+    UserChild *uc;
 
     assert(!dev->id && !dev->realized);
 
+    uc = (UserChild *)object_dynamic_cast(OBJECT(dev), TYPE_USER_CHILD);
+
+    if (uc) {
+        parent_obj = qdev_find_peripheral_parent(dev, errp);
+        if (*errp) {
+            goto err;
+        }
+
+        if (!id && parent_obj) {
+            /*
+             * Covert anonymous device with user-child interface to
+             * non-anonymous, then it will be insert under "/peripheral"
+             * path.
+             */
+            id = uc_name_future_child(OBJECT(dev), parent_obj);
+            if (!qdev_pre_check_device_id(id, errp)) {
+                goto err;
+            }
+        }
+    }
+
     /*
      * object_property_[try_]add_child() below will assert the device
      * has no parent
      */
     if (id) {
-        prop = object_property_try_add_child(qdev_get_peripheral(), id,
+        if (!parent_obj) {
+            parent_obj = qdev_get_peripheral();
+        }
+
+        prop = object_property_try_add_child(parent_obj, id,
                                              OBJECT(dev), NULL);
         if (prop) {
             dev->id = id;
         } else {
             error_setg(errp, "Duplicate device ID '%s'", id);
-            g_free(id);
-            return NULL;
+            goto err;
         }
     } else {
         static int anon_count;
@@ -615,6 +683,9 @@ const char *qdev_set_id(DeviceState *dev, char *id, Error **errp)
     }
 
     return prop->name;
+err:
+    g_free(id);
+    return NULL;
 }
 
 DeviceState *qdev_device_add_from_qdict(const QDict *opts, long *category,
@@ -885,12 +956,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
 
 static DeviceState *find_device_state(const char *id, Error **errp)
 {
-    Object *obj = object_resolve_path_at(qdev_get_peripheral(), id);
+    bool ambiguous = false;
     DeviceState *dev;
+    Object *obj;
 
+    obj = object_resolve_path_from(qdev_get_peripheral(), id, &ambiguous);
     if (!obj) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-                  "Device '%s' not found", id);
+        if (ambiguous) {
+            error_setg(errp, "Device ID '%s' is ambiguous", id);
+        } else {
+            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+                      "Device '%s' not found", id);
+        }
         return NULL;
     }
 
diff --git a/system/user-child.c b/system/user-child.c
new file mode 100644
index 000000000000..1e667f09cc87
--- /dev/null
+++ b/system/user-child.c
@@ -0,0 +1,72 @@
+/*
+ * Child configurable interface.
+ *
+ * Copyright (c) 2023 Intel Corporation
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+
+#include "monitor/user-child.h"
+
+Object *uc_provide_default_parent(Object *obj, Error **errp)
+{
+    UserChild *uc = USER_CHILD(obj);
+    UserChildClass *ucc = USER_CHILD_GET_CLASS(uc);
+
+    if (ucc->get_parent) {
+        return ucc->get_parent(uc, errp);
+    }
+
+    return NULL;
+}
+
+char *uc_name_future_child(Object *obj, Object *parent)
+{
+    UserChild *uc = USER_CHILD(obj);
+    UserChildClass *ucc = USER_CHILD_GET_CLASS(uc);
+
+    if (ucc->get_child_name) {
+        return ucc->get_child_name(uc, parent);
+    }
+
+    return NULL;
+}
+
+bool uc_check_user_parent(Object *obj, Object *parent)
+{
+    UserChild *uc = USER_CHILD(obj);
+    UserChildClass *ucc = USER_CHILD_GET_CLASS(uc);
+
+    if (ucc->check_parent) {
+        ucc->check_parent(uc, parent);
+    }
+
+    return true;
+}
+
+static const TypeInfo user_child_interface_info = {
+    .name          = TYPE_USER_CHILD,
+    .parent        = TYPE_INTERFACE,
+    .class_size = sizeof(UserChildClass),
+};
+
+static void user_child_register_types(void)
+{
+    type_register_static(&user_child_interface_info);
+}
+
+type_init(user_child_register_types)
-- 
2.34.1


  parent reply	other threads:[~2023-11-30 14:31 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30 14:41 [RFC 00/41] qom-topo: Abstract Everything about CPU Topology Zhao Liu
2023-11-30 14:41 ` [RFC 01/41] qdev: Introduce new device category to cover basic topology device Zhao Liu
2023-11-30 14:41 ` [RFC 02/41] qdev: Allow qdev_device_add() to add specific category device Zhao Liu
2023-11-30 14:41 ` [RFC 03/41] system: Create base category devices from cli before board initialization Zhao Liu
2023-11-30 14:41 ` [RFC 04/41] qom/object: Introduce helper to resolve path from non-direct parent Zhao Liu
2023-11-30 14:41 ` [RFC 05/41] qdev: Set device parent and id after setting properties Zhao Liu
2023-11-30 14:41 ` Zhao Liu [this message]
2023-11-30 14:41 ` [RFC 07/41] qdev: Introduce parent option in -device Zhao Liu
2023-11-30 14:41 ` [RFC 08/41] hw/core/topo: Introduce CPU topology device abstraction Zhao Liu
2023-11-30 14:41 ` [RFC 09/41] hw/core/topo: Support topology index for topology device Zhao Liu
2023-11-30 14:41 ` [RFC 10/41] hw/core/topo: Add virtual method to update topology info for parent Zhao Liu
2023-11-30 14:41 ` [RFC 11/41] hw/core/topo: Add virtual method to check topology child Zhao Liu
2023-11-30 14:41 ` [RFC 12/41] hw/core/topo: Add helpers to traverse the CPU topology tree Zhao Liu
2023-11-30 14:41 ` [RFC 13/41] hw/core/cpu: Convert CPU from general device to topology device Zhao Liu
2023-11-30 14:41 ` [RFC 14/41] PPC/ppc-core: Offload core-id to PPC specific core abstarction Zhao Liu
2023-11-30 14:41 ` [RFC 15/41] hw/cpu/core: Allow to configure plugged threads for cpu-core Zhao Liu
2023-11-30 14:41 ` [RFC 16/41] PPC/ppc-core: Limit plugged-threads and nr-threads to be equal Zhao Liu
2023-11-30 14:41 ` [RFC 17/41] hw/cpu/core: Convert cpu-core from general device to topology device Zhao Liu
2023-11-30 14:41 ` [RFC 18/41] hw/cpu/cluster: Rename CPUClusterState to CPUCluster Zhao Liu
2023-11-30 14:41 ` [RFC 19/41] hw/cpu/cluster: Wrap TCG related ops and props into CONFIG_TCG Zhao Liu
2023-11-30 14:41 ` [RFC 20/41] hw/cpu/cluster: Descript cluster is not only used for TCG in comment Zhao Liu
2023-11-30 14:41 ` [RFC 21/41] hw/cpu/cluster: Allow cpu-cluster to be created by -device Zhao Liu
2023-11-30 14:41 ` [RFC 22/41] hw/cpu/cluster: Convert cpu-cluster from general device to topology device Zhao Liu
2023-11-30 14:41 ` [RFC 23/41] hw/cpu/die: Abstract cpu-die level as " Zhao Liu
2023-11-30 14:41 ` [RFC 24/41] hw/cpu/socket: Abstract cpu-socket " Zhao Liu
2023-11-30 14:41 ` [RFC 25/41] hw/cpu/book: Abstract cpu-book " Zhao Liu
2023-11-30 14:41 ` [RFC 26/41] hw/cpu/drawer: Abstract cpu-drawer " Zhao Liu
2023-11-30 14:41 ` [RFC 27/41] hw/core/slot: Introduce CPU slot as the root of CPU topology Zhao Liu
2023-11-30 14:41 ` [RFC 28/41] hw/core/slot: Maintain the core queue in CPU slot Zhao Liu
2023-11-30 14:41 ` [RFC 29/41] hw/core/slot: Statistics topology information " Zhao Liu
2023-11-30 14:41 ` [RFC 30/41] hw/core/slot: Check topology child to be added under " Zhao Liu
2023-11-30 14:41 ` [RFC 31/41] hw/machine: Plug cpu-slot into machine to maintain topology tree Zhao Liu
2023-11-30 14:41 ` [RFC 32/41] hw/machine: Build smp topology tree from -smp Zhao Liu
2023-11-30 14:41 ` [RFC 33/41] hw/machine: Validate smp topology tree without -smp Zhao Liu
2023-11-30 14:41 ` [RFC 34/41] hw/core/topo: Implement user-child to collect topology device from cli Zhao Liu
2023-11-30 14:41 ` [RFC 35/41] hw/i386: Make x86_cpu_new() private in x86.c Zhao Liu
2023-11-30 14:41 ` [RFC 36/41] hw/i386: Allow x86_cpu_new() to specify parent for new CPU Zhao Liu
2023-11-30 14:41 ` [RFC 37/41] hw/i386: Allow i386 to create new CPUs from QOM topology Zhao Liu
2023-11-30 14:42 ` [RFC 38/41] hw/i386: Wrap apic id and topology sub ids assigning as helpers Zhao Liu
2023-11-30 14:42 ` [RFC 39/41] hw/i386: Add the interface to search parent for QOM topology Zhao Liu
2023-11-30 14:42 ` [RFC 40/41] hw/i386: Support " Zhao Liu
2023-11-30 14:42 ` [RFC 41/41] hw/i386: Cleanup non-QOM topology support Zhao Liu
2023-12-11 13:36 ` [RFC 00/41] qom-topo: Abstract Everything about CPU Topology Zhao Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231130144203.2307629-7-zhao1.liu@linux.intel.com \
    --to=zhao1.liu@linux.intel.com \
    --cc=alex.bennee@linaro.org \
    --cc=alistair@alistair23.me \
    --cc=anthony.perard@citrix.com \
    --cc=berrange@redhat.com \
    --cc=bin.meng@windriver.com \
    --cc=clg@kaod.org \
    --cc=danielhb413@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=edgar.iglesias@gmail.com \
    --cc=eduardo@habkost.net \
    --cc=fbarrat@linux.ibm.com \
    --cc=harshpb@linux.ibm.com \
    --cc=imammedo@redhat.com \
    --cc=jasowang@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=liwei1518@gmail.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mst@redhat.com \
    --cc=npiggin@gmail.com \
    --cc=nsg@linux.ibm.com \
    --cc=palmer@dabbelt.com \
    --cc=paul@xen.org \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=sstabellini@kernel.org \
    --cc=thuth@redhat.com \
    --cc=wangyanan55@huawei.com \
    --cc=xen-devel@lists.xenproject.org \
    --cc=yongwei.ma@intel.com \
    --cc=zhao1.liu@intel.com \
    --cc=zhenyu.z.wang@intel.com \
    --cc=zhiwei_liu@linux.alibaba.com \
    --cc=zhiyuan.lv@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.