qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Stefan Hajnoczi <stefanha@gmail.com>,
	Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
Cc: "Laurent Vivier" <lvivier@redhat.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/7] tests/qgraph: pci-pc driver and interface nodes
Date: Wed, 11 Jul 2018 17:18:03 +0200	[thread overview]
Message-ID: <494e6b18-a5e9-0521-4ace-dca2160ea191@redhat.com> (raw)
In-Reply-To: <20180711144920.GN31228@stefanha-x1.localdomain>

On 11/07/2018 16:49, Stefan Hajnoczi wrote:
> On Mon, Jul 09, 2018 at 11:11:31AM +0200, Emanuele Giuseppe Esposito wrote:
>> -QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)
>> +static void *qpci_get_driver(void *obj, const char *interface)
>>  {
>> -    QPCIBusPC *ret = g_new0(QPCIBusPC, 1);
>> +    QPCIBusPC *qpci = obj;
>> +    if (!g_strcmp0(interface, "pci-bus")) {
>> +        return &qpci->bus;
>> +    }
>> +    printf("%s not present in pci-bus-pc", interface);
>> +    abort();
>> +}
> 
> At this point I wonder if it makes sense to use the QEMU Object Model
> (QOM), which has interfaces and inheritance.  qgraph duplicates part of
> the object model.

Replying for Emanuele on this point since we didn't really go through
QOM yet; I'll let him answer the comments that are more related to the code.

QOM is much heavier weight than qgraph, and adds a lot more boilerplate:

- QOM properties interact with QAPI and bring in a lot of baggage;
qgraph would only use "child" properties to implement containment.

- QOM objects are long-lived, qgraph objects only last for the duration
of a single test.  qgraph doesn't need reference counting or complex
two-phase initialization like "realize" or "user_complete"

- QOM's hierarchy is shallow, but qgraph doesn't really need _any_
hierarchy.  Because it focuses on interface rather than hierarchy,
everything can be expressed simply through structs contained into one
another.

Consider that qgraph is 1/4th the size of QOM, and a large part of it is
the graph data structure that (as you said) would not be provided by QOM.

There are two things where using QOM would save a little bit of
duplicated concepts, namely the get_driver (get interface, what you
quote above) and get_device (get contained object) callbacks.  However,
it wouldn't simplify the code at all, because it would require the
introduction of separate instance and class structs.  We didn't want to
add all too much boilerplate for people that want to write qtest, as you
pointed out in the review of patch 4.

>> +void qpci_set_pc(QPCIBusPC *ret, QTestState *qts, QGuestAllocator *alloc)
> 
> It's not clear to me what the purpose of this function is - at least the
> name is a bit cryptic since it seems more like an initialization
> function than 'setting pc' on QPCIBusPC.  How about inlining this in
> qpci_init_pc() instead of keeping a separate function?

I agree about the naming.  Perhaps we can rename the existing
qpci_init_pc to qpci_pc_new, and qpci_set_pc to qpci_pc_init.

Would you prefer if the split was done in the patch that introduces the
user for qpci_set_pc (patch 5)?  We did it here because this patch
prepares qpci-pc

Thanks,

Paolo

>> +{
>>      assert(qts);
>>  
>>      ret->bus.pio_readb = qpci_pc_pio_readb;
>> @@ -147,11 +164,23 @@ QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)
>>      ret->bus.mmio_alloc_ptr = 0xE0000000;
>>      ret->bus.mmio_limit = 0x100000000ULL;
>>  
>> +    ret->obj.get_driver = qpci_get_driver;
>> +}
>> +
>> +QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)
>> +{
>> +    QPCIBusPC *ret = g_new0(QPCIBusPC, 1);
>> +    qpci_set_pc(ret, qts, alloc);
>> +
>>      return &ret->bus;
>>  }
>>  
>>  void qpci_free_pc(QPCIBus *bus)
>>  {
>> +    if (!bus) {
>> +        return;
>> +    }
> 
> Why is this needed now?
> 
>> +
>>      QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);
>>  
>>      g_free(s);
>> @@ -176,3 +205,11 @@ void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
>>  
>>      qmp_eventwait("DEVICE_DELETED");
>>  }
>> +
>> +static void qpci_pc(void)
>> +{
>> +    qos_node_create_driver("pci-bus-pc", NULL);
>> +    qos_node_produces("pci-bus-pc", "pci-bus");
> 
> In QOM pci-bus-pc would be a class, pci-bus would be an interface.  From
> a driver perspective it seems QOM can already do what is needed and the
> qgraph infrastructure isn't necessary.
> 
> Obviously the depth-first search *is* unique and not in QOM, although
> QOM does offer a tree namespace which can be used for looking up object
> instances and I guess this could be used to configure tests at runtime.
> 
> I'll think about this more as I read the rest of the patches.
> 
>> +}
>> +
>> +libqos_init(qpci_pc);
>> diff --git a/tests/libqos/pci-pc.h b/tests/libqos/pci-pc.h
>> index 491eeac756..ee381c5667 100644
>> --- a/tests/libqos/pci-pc.h
>> +++ b/tests/libqos/pci-pc.h
>> @@ -15,7 +15,15 @@
>>  
>>  #include "libqos/pci.h"
>>  #include "libqos/malloc.h"
>> +#include "qgraph.h"
>>  
>> +typedef struct QPCIBusPC {
>> +    QOSGraphObject obj;
>> +    QPCIBus bus;
>> +} QPCIBusPC;
> 
> Why does this need to be public?
> 
>> +
>> +void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, int devfn);
> 
> Why does this need to be public?
> 
>> +void qpci_set_pc(QPCIBusPC *ret, QTestState *qts, QGuestAllocator *alloc);
> 
> Why does this need to be public?
> 
>>  QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc);
>>  void     qpci_free_pc(QPCIBus *bus);
>>  
>> diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
>> index 0b73cb23d0..c51c186867 100644
>> --- a/tests/libqos/pci.c
>> +++ b/tests/libqos/pci.c
>> @@ -15,6 +15,7 @@
>>  
>>  #include "hw/pci/pci_regs.h"
>>  #include "qemu/host-utils.h"
>> +#include "qgraph.h"
>>  
>>  void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
>>                           void (*func)(QPCIDevice *dev, int devfn, void *data),
>> @@ -402,3 +403,10 @@ void qpci_plug_device_test(const char *driver, const char *id,
>>      qtest_qmp_device_add(driver, id, "'addr': '%d'%s%s", slot,
>>                           opts ? ", " : "", opts ? opts : "");
>>  }
>> +
>> +static void qpci(void)
>> +{
>> +    qos_node_create_interface("pci-bus");
>> +}
>> +
>> +libqos_init(qpci);
> 
> Why does an interface need to be created?  The drivers declare which
> interfaces they support?
> 
> I don't think this can be used to detect typoes in the driver's
> qos_node_produces() call since there is no explicit control over the
> order in which libqos_init() functions are called.  So the driver may
> call qos_node_produces() before the qos_node_create_interface() is
> called?
> 

  reply	other threads:[~2018-07-11 15:18 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-09  9:11 [Qemu-devel] [PATCH 0/7] Qtest driver framework Emanuele Giuseppe Esposito
2018-07-09  9:11 ` [Qemu-devel] [PATCH 1/7] tests: qgraph API for the qtest " Emanuele Giuseppe Esposito
2018-07-11 14:28   ` Stefan Hajnoczi
2018-07-11 14:58     ` Paolo Bonzini
2018-07-18 14:23       ` Stefan Hajnoczi
2018-07-18 18:05         ` Emanuele
2018-07-18 19:28         ` Paolo Bonzini
2018-07-18 21:13           ` Emanuele
2018-07-27 12:54             ` Stefan Hajnoczi
2018-07-09  9:11 ` [Qemu-devel] [PATCH 2/7] tests/qgraph: pci-pc driver and interface nodes Emanuele Giuseppe Esposito
2018-07-11 14:49   ` Stefan Hajnoczi
2018-07-11 15:18     ` Paolo Bonzini [this message]
2018-07-18 14:29       ` Stefan Hajnoczi
2018-07-18 18:29         ` Emanuele
2018-07-18 19:33           ` Paolo Bonzini
2018-07-18 20:49             ` Emanuele
2018-07-11 17:46     ` Emanuele
2018-07-18 15:02       ` Stefan Hajnoczi
2018-07-18 19:38       ` Paolo Bonzini
2018-07-11 20:05   ` Philippe Mathieu-Daudé
2018-07-09  9:11 ` [Qemu-devel] [PATCH 3/7] tests/qgraph: sdhci " Emanuele Giuseppe Esposito
2018-07-11 20:13   ` Philippe Mathieu-Daudé
2018-07-11 20:44     ` Emanuele
2018-07-09  9:11 ` [Qemu-devel] [PATCH 4/7] tests/qgraph: arm/raspi2 machine node Emanuele Giuseppe Esposito
2018-07-11 14:59   ` Stefan Hajnoczi
2018-07-11 15:30     ` Paolo Bonzini
2018-07-11 20:19       ` Philippe Mathieu-Daudé
2018-07-09  9:11 ` [Qemu-devel] [PATCH 5/7] tests/qgraph: x86_64/pc " Emanuele Giuseppe Esposito
2018-07-09  9:11 ` [Qemu-devel] [PATCH 6/7] tests/qgraph: gtest integration Emanuele Giuseppe Esposito
2018-07-11 15:02   ` Stefan Hajnoczi
2018-07-09  9:11 ` [Qemu-devel] [PATCH 7/7] tests/qgraph: sdhci test node Emanuele Giuseppe Esposito
2018-07-11 15:15   ` Stefan Hajnoczi
2018-07-11 17:52     ` Emanuele
2018-07-12 12:07       ` Paolo Bonzini
2018-07-11 14:00 ` [Qemu-devel] [PATCH 0/7] Qtest driver framework Stefan Hajnoczi
2018-07-11 14:17   ` Emanuele
2018-07-11 15:27 ` Stefan Hajnoczi
2018-07-18 17:14   ` Markus Armbruster
2018-07-18 19:35     ` Paolo Bonzini

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=494e6b18-a5e9-0521-4ace-dca2160ea191@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=e.emanuelegiuseppe@gmail.com \
    --cc=f4bug@amsat.org \
    --cc=lvivier@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).