qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and compositio


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2)
Date: Mon, 05 Dec 2011 13:28:29 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.21) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13

On 12/05/2011 09:33 AM, Peter Maydell wrote:
On 5 December 2011 15:04, Anthony Liguori<address@hidden>  wrote:
On 12/05/2011 08:50 AM, Peter Maydell wrote:

On 5 December 2011 14:36, Anthony Liguori<address@hidden>    wrote:

struct LSIDevice {

    PCIDevice parent;
};

static void lsi_command_complete(SCSIBus *bus, SCSIRequest *req)
{
   LSIDevice *dev = LSI_DEVICE(bus);
   ...
}


What is the LSI_DEVICE macro actually doing here? I assume
it's not just a cast...


https://github.com/aliguori/qemu/blob/qom-next/hw/object.c#L376

It's quite literally dynamic_cast<LSIDevice>(bus) in C++.

This is confusing "interface I expose to the world" with
Device. Since "interface I expose to the world shouldn't
be a subtype of Device [they are fundamentally different kinds
of object and having exposed interfaces be kinds-of Devices
is extremely confusing] I'm not sure how this would work.

No, an interface is not a subclass of DeviceState. SCSIBus is a subclass of Interface.

I think this will become more obvious once we start converting BusState's to interfaces. That's still a ways off so I'd suggest we defer this discussion until then.

Saying a device is-a interface doesn't match reality. Devices
have multiple interfaces with the rest of the world.


There are two ways a device can interact with the rest of the world.  It can
expose a portion of it's functionality (such as an IRQ) via a child object.
This is how it would expose MemoryRegions too.

Perhaps this is terminology confusion again. To me that is 'exposing
an interface to the rest of the world' -- it's a named point where
we expose a specific API. (For an MMIO region probably that's just
"return a MemoryRegion*".)

Yes, what you describe here is possible and will be very common. What I'm talking about as "Interfaces" is a higher level concept.

The other point of confusion here is that "child objects" are doing
two things:
  * composition, ie "my model of the Foo SoC has a child object FooUART
    which implements its serial ports" (but that is an internal
    implementation detail and might change in future)

Yup.  Does you see this as a problem?

  * providing connections to the rest of the world, ie "my Foo SoC has
    a child object Pin named 'my_signal' which is part of its API
    contract with the outside world"

Providing an ABI and providing full backwards compatibility are two different things.

An ABI means (or API really) that if you ask QEMU to does something, if it doesn't fail in a predictable fashion, then what it ends up doing will always be the same.

IOW, if I say, -device virtio-blk-pci, it should create a virtio block device using the PCI virtio transport. If it caused QEMU to print device information about that device, that's an ABI breakage.

Backwards compatibility is stronger than this. It says that if you invoke QEMU a certain way, it will behave in an indistinguishable way from an older version.

I want QOM to be ABI compatible but not backwards compatible. I want to give us the flexibility to change device names, break up devices, or add devices. When things are removed, it should result in errors. It should also be possible to do enough introspection to understand what is supported without relying on version numbers.

We should provide a backwards compatible interface, but it should be much higher level. The way I think about it, qom-* is the non-backwards compatible API within QMP, and then we'll introduce higher level interfaces (much like query-pci) that will remain long term backwards compatible.

Obviously it's useful (and neat) if the implementation of these things
is broadly similar, but I think that because they're conceptually
totally different things we should strive to pick terminology (and
type/class names) that maintain and make clear that difference.

You can take a subset of the exposed children (and perhaps some mapping
logic), and for an ad-hoc interface.

This is composition-of-interfaces, right? That would also be useful
(but probably not needed to start with).

But sometimes, you want the entire device to act like a specific thing.  In
this case, you want the LSIDevice to act like SCSIBus.  Interfaces are just
a more formal form of what would otherwise be an ad-hoc interface.

This is something different again -- it's not just composition-of-interfaces
to provide a SCSI-bus-connector, it's claiming the whole device is-a
SCSI-bus-connector.

I think we should have one way of doing connections between devices,
and we should make sure it does what we want. If we immediately say
"oh, SCSI and PCI connect in a special way" then we've removed a lot
of the impetus to make the standard connection method usefully flexible
and convenient.

(This is
one of the major reasons why SysBus exists: it provides a suboptimal
but usuable model of this for the two most common kinds of interface,
MMIO regions and random gpio.)

My expectation is that most things that use SysBus today would not implement
any interfaces.  They would just expose child properties.

Terminology confusion again. They definitely need to be able to expose
the equivalent of gpio in and out pins, and memory regions, by name.

Yes, child properties. Pins and MemoryRegions need to be Objects (not necessarily DeviceStates).

Regards,

Anthony Liguori

-- PMM





reply via email to

[Prev in Thread] Current Thread [Next in Thread]