On Sun, Feb 13, 2011 at 5:31 PM, Anthony Liguori <anth...@codemonkey.ws> wrote:
> On 02/11/2011 12:14 PM, Blue Swirl wrote:
>>
>> On Thu, Feb 10, 2011 at 6:05 PM, Anthony Liguori<anth...@codemonkey.ws>
>>  wrote:
>>
>>>
>>> On 02/10/2011 03:20 PM, Gleb Natapov wrote:
>>>
>>>>
>>>> Jugging by how well all previous conversion went we will end up with one
>>>> more way of creating devices. One legacy, another qdev and your new one.
>>>> And what is the problem with qdev again (not that I am a big qdev fan)?
>>>>
>>>>
>>>
>>> We've really been arguing about probably the most minor aspect of the
>>> problem with qdev.
>>>
>>> All I'm really saying is that we shouldn't tie device construction to a
>>> factory interface as we do with qdev.
>>>
>>> That simply means that we should be able to do:
>>>
>>> RTC *rtc_create(arg1, arg2, arg2);
>>>
>>
>> I don't see how that would help at all. Throwing qdev away and just
>> calling various functions directly, with all states exposed would be
>> like QEMU 0.9.0.
>>
>
> qdev doesn't expose any state today.  qdev properties are construction-only
> properties that happen to be stored in each device state.
>
> What we really need is a full property framework that includes properties
> with hookable getters and setters along with the ability to mark properties
> as construct-only, read-only, or read-write.
>
> But I think it's reasonable to expose construct-only properties as just an
> initfn argument.

Sounds OK. About read-write properties, what happens if we one day
have extensive threading, and locks are pushed to device level? I can
imagine a deadlock involving one thread running in IO thread for a
device and another trying to access that device's properties. Maybe
that is not different from function call version.

>>> And that a separate piece of code decides which devices are exposed
>>> through
>>> -device or device_add.  Which devices are exposed is really a minor
>>> detail.
>>>
>>> That said, qdev has a number of significant limitations in my mind.  The
>>> first is that the only relationship between devices is through the
>>> BusState
>>> interface.
>>>
>>
>> There's also qemu_irq for arbitrary signals.
>>
>
> Yes, but qemu_irq is very restricted as it only models a signal bit of
> information and doesn't really have a mechanism to attach/detach in any
> generic way.

Basic signals are already very useful for many purposes, since they
match digital logic signals in real HW. In theory, whole machines
could be constructed with just qemu_irq and NAND gate emulator. ;-)

In the message passing IRQ discussion earlier, it was IIRC decided
that the one bit version would not be changed but a separate message
passing version would be created if ever needed.

>>>  I don't think we should even try to have a generic bus model.
>>>  When you look at how badly broken PCI hotplug is current in qdev, I
>>> think
>>> this is symptomatic of this.
>>>
>>
>> And how should this be fixed? The API change would not help.
>>
>
> Just as we have bus level creation functions, we should have bus level
> hotplug interfaces.
>
>>> There's also no way in qdev to really have polymorphism.  Interfaces
>>> really
>>> aren't meaningful in qdev so you have things like PCIDevice where some
>>> methods are stored in the object instead of the class dispatch table and
>>> you
>>> have overuse of static class members.
>>>
>>
>> QEMU is developed in C, not C++.
>>
>
> But we're trying to do object oriented programming in C so as long as we're
> doing that, we ought to do it right.
>
>>> And it's all unrelated to VMState.
>>>
>>
>> Right, but this has also the good side that not all device state is
>> automatically exported. If other devices would be allowed to muck with
>> a devices internal state freely, bad things could happen.
>>
>> Device reset could also use standard register definitions, shared with
>> VMState.
>>
>
> There's a way to have formally verifiable serialization/deserialization if
> we can satisfy two conditions 1) the devices rely on no global state (i.e.
> static variables) and 2) every field asssociated with a device is marshalled
> during serialization/deserialization.
>
> When we define a device, right now we say that certain state is writable
> during construction.  It's not a stretch to want to have some properties
> writable during runtime.  If we also had a mechanism to mark certain
> properties as read-only, but still were able to introspect them, we could
> implement serialization without having to have a second VMState definition.
>
> Compatibility will always require manipulating state, but once you have the
> state stored in a data structure, you can describe those transformations in
> a pretty high level fashion.
>
>>> And this is just the basic mechanisms of qdev.  The actual implementation
>>> is
>>> worse.  The use of qemu_irq as gpio in the base class and overuse of
>>> SystemBus is really quite insane.
>>>
>>
>> Maybe qemu_irq should be renamed to QEMUSignal (and I don't like
>> typedeffing pointers), otherwise it looks quite sane to me.
>>
>
> Any interfaces of a base class should make sense even for derived classes.
>
> That means if the base class is going to expose essentially a pin-out
> interface, that if I have a PCIDevice and cast it to Device, I should be
> able to interact with the GPIO interface to interact with the PCI device.
>  Presumably, that means interfacing at the PCI signalling level.  That's
> insane to model in QEMU :-)

This would be doable, if we built buses from a bunch of signals, like
in VHDL or Verilog. It would simplify aliased MMIO addresses nicely,
the undecoded address pins would be ignored. I don't think it would be
useful, but a separate interface could be added for connecting to
PCIBus with just qemu_irqs.

> In reality, GPIO only makes sense for a small class of simple devices where
> modelling the pin-out interface makes sense (like a 7-segment LCD).  That
> suggests that GPIO should not be in the DeviceState interface but instead
> should be in a SimpleDevice subclass or something like that.
>
>> Could you point to examples of SystemBus overuse?
>>
>
> anthony@titi:~/git/qemu/hw$ grep qdev_create *.c | wc -l
> 73
> anthony@titi:~/git/qemu/hw$ grep 'qdev_create(NULL' *.c | wc -l
> 56
>
> SystemBus has become a catch-all for shallow qdev conversions.  We've got
> Northbridges, RAM, and network devices sitting on the same bus...

On Sparc32 I have not bothered to create a SBus bus. Now it would be
useful to get bootindex corrected. Most devices (even on-board IO)
should use SBus.

The only other bus (MBus) would exist between CPU, IOMMU and memory.

But SysBus fitted the need until recently.

>>> I don't think there is any device that has been improved by qdev.
>>>  -device
>>> is a nice feature, but it could have been implemented without qdev.
>>>
>>
>> We have 'info qtree' which can't be implemented easily without a
>> generic device class. Avi (or who was it) sent patches to expose even
>> more device state.
>>
>> With the patches I'm going to apply, if Redhat wants to disable
>> building various devices, it can be done without #ifdeffery. This is
>> not possible without a generic factory interface.
>>
>
> I'm not arguing against a generic factory interface, I'm arguing that it
> should be separate.
>
> IOW:
>
> SerialState *serial_create(int iobase, int irq, ...);
>
> static DeviceState *qdev_serial_create(QemuOpts *opts);
>
> static void serial_init(void)
> {
>     qdev_register("serial", qdev_serial_create);
> }
>
> The key point is that when we create devices internally, we should have a
> C-friendly, type-safe interface to interact with.  This will encourage
> composition and a richer device model than what we have today.

Isn't this what we have now in most cases?

Reply via email to