Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-29 Thread Paolo Bonzini

On 07/28/2011 07:59 PM, Anthony Liguori wrote:

Just define an interface that returns a struct then.  It's no more
complicated than that.


Ok, so we're debating whether to: 1) add an interface returning a 
pointer to an internal struct; 2) include in the internal struct a 
pointer-to-function that does a container_of and returns the outer 
Device object.  Otherwise, we're on the same page.  I'm quite relieved. ;)


I can see advantages to both approach.  The main advantage to (2) is 
that it scales better when you have multiple interfaces of the same kind 
exposed by the device.  You cannot implement an interface twice.


Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Paolo Bonzini

On 07/27/2011 10:01 PM, Anthony Liguori wrote:




That's milkymist, not GoldFish.


Oh, Goldfish is fake. It's not real hardware.

The enumerator device is not a real device.  It's weird because it's
imaginary and was designed specifically within QEMU.

It's not a good example for discussing modelling.


There are plenty of PV interfaces implemented by QEMU.  Would you say 
the same of virtio?


Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Anthony Liguori

On 07/28/2011 02:36 AM, Paolo Bonzini wrote:

On 07/27/2011 10:01 PM, Anthony Liguori wrote:




That's milkymist, not GoldFish.


Oh, Goldfish is fake. It's not real hardware.

The enumerator device is not a real device. It's weird because it's
imaginary and was designed specifically within QEMU.

It's not a good example for discussing modelling.


There are plenty of PV interfaces implemented by QEMU. Would you say the
same of virtio?


Virtio was designed to look like real hardware.

I would say that trying to fit XenStore into QOM would not be a good 
exercise.


Regards,

Anthony Liguori



Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Paolo Bonzini

On 07/28/2011 02:46 PM, Anthony Liguori wrote:


There are plenty of PV interfaces implemented by QEMU. Would you say the
same of virtio?


Virtio was designed to look like real hardware.

I would say that trying to fit XenStore into QOM would not be a good
exercise.


No doubt about that. :)  I'd put a lot more hope into Goldfish though.

Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Anthony Liguori

On 07/28/2011 08:50 AM, Paolo Bonzini wrote:

On 07/28/2011 02:46 PM, Anthony Liguori wrote:


There are plenty of PV interfaces implemented by QEMU. Would you say the
same of virtio?


Virtio was designed to look like real hardware.

I would say that trying to fit XenStore into QOM would not be a good
exercise.


No doubt about that. :) I'd put a lot more hope into Goldfish though.


What's unclear to me about the Goldfish enumerator is whether it should 
be filled out through interaction with hardware devices or via some 
other mechanism.


In many ways, it's similar to ACPI and a Device Tree.  In both of those 
cases, firmware actually is responsible for constructing those tables.


Regards,

Anthony Liguori



Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Paolo Bonzini

On 07/28/2011 04:03 PM, Anthony Liguori wrote:

No doubt about that. :) I'd put a lot more hope into Goldfish though.


What's unclear to me about the Goldfish enumerator is whether it should
be filled out through interaction with hardware devices or via some
other mechanism.

In many ways, it's similar to ACPI and a Device Tree.  In both of those
cases, firmware actually is responsible for constructing those tables.


Yes, it is a flat device tree.

Since it supports hotplug (at least in theory, the Android emulator 
predates qdev so it doesn't support it), I would say it is more similar 
to PCI configuration space.  The difference is that IRQ numbers and MMIO 
base addresses are handed out by hardware (by a piece of the SoC) rather 
than by the firmware.


So yes, the hardware would have some kind of bus to talk to the devices 
and arbitrate hotplug/hotunplug.  The only peculiarity being that the 
bus enumerator hardcodes itself in the list it exposes, in addition to 
the devices on the bus.


But that still means that the devices have two views:

1) the enumerator's view is either this is my name, my MMIO base, my 
IRQ base or I need 4k of MMIO and 1 IRQ line, please tell me 
where/which are those, depending on the device;


2) the PIC's view is please bring this IRQ line up/down (the device 
says which line, since the enumerator can assign those dynamically).


The PIC's view is more complicated than a Pin, and more similar to ISA.

Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Anthony Liguori

On 07/28/2011 09:41 AM, Paolo Bonzini wrote:

On 07/28/2011 04:03 PM, Anthony Liguori wrote:

No doubt about that. :) I'd put a lot more hope into Goldfish though.


What's unclear to me about the Goldfish enumerator is whether it should
be filled out through interaction with hardware devices or via some
other mechanism.

In many ways, it's similar to ACPI and a Device Tree. In both of those
cases, firmware actually is responsible for constructing those tables.


Yes, it is a flat device tree.

Since it supports hotplug (at least in theory, the Android emulator
predates qdev so it doesn't support it), I would say it is more similar
to PCI configuration space. The difference is that IRQ numbers and MMIO
base addresses are handed out by hardware (by a piece of the SoC) rather
than by the firmware.

So yes, the hardware would have some kind of bus to talk to the devices
and arbitrate hotplug/hotunplug. The only peculiarity being that the bus
enumerator hardcodes itself in the list it exposes, in addition to the
devices on the bus.

But that still means that the devices have two views:

1) the enumerator's view is either this is my name, my MMIO base, my
IRQ base or I need 4k of MMIO and 1 IRQ line, please tell me
where/which are those, depending on the device;


I think it's important to ask, how would this be implemented in 
hardware.  The only way I can see is to teach each device about this 
interface and then have a common bus.  That implies that you have:


class GoldfishEnumerator : public Device {
 GoldfishDevice *slots[N];
};

interface GoldfishDevice {
 const char *get_name();
 uint64_t get_mmio_base();
 ...
};

class GoldfishNic : public Device, implements GoldfishDevice
{
const char *get_name(void) {
return nic;
}
};

With respect to hotplug, that means that you have to hot plug the device 
to multiple busses.



2) the PIC's view is please bring this IRQ line up/down (the device
says which line, since the enumerator can assign those dynamically).

The PIC's view is more complicated than a Pin, and more similar to ISA.


ISA is just a pin.  The ISA bus extender literally has five pins 
corresponding to the ISA IRQs 7, 6, 5, 4, 3.


EISA adds 5 more pins for 10, 11, 12, 14, 15.

ISA devices choose their IRQ line by hardwiring their IRQ output pin 
to a specific IRQ line on the bus.


Regards,

Anthony Liguori



Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Paolo Bonzini

On 07/28/2011 05:04 PM, Anthony Liguori wrote:

The only way I can see is to teach each device about this interface and
then have a common bus.  That implies that you have:

class GoldfishEnumerator : public Device {
  GoldfishDevice *slots[N];


FWIW, there's no hardcoded limit in the interface, and the list of 
devices is unordered.  But that only means you should attach it with


plug-set goldfish_tty::enumerator goldfish_enum

rather than

plug-set goldfish_enum::slots[12] goldfish_tty

If you can confirm that, that's fine.


};

interface GoldfishDevice {
  const char *get_name();
  uint64_t get_mmio_base();
  ...
};

class GoldfishNic : public Device, implements GoldfishDevice
{
 const char *get_name(void) {
 return nic;
 }


 uint64_t mmio_base;
 uint64_t get_mmio_base() { return mmio_base; }
 uint64_t set_mmio_base(uint64_t addr) { mmio_base = addr; }


};


And that's exactly my point.  It's a stupid interface full of 
getters/setters, which is what you get if you use only interface 
inheritance instead of, where appropriate, data containment.


Interfaces should be reserved for what really depends on the 
_implementation_ of the GoldfishNic, not for accessing a bunch of 
numbers.  There is no implementation-dependent detail of that kind in 
the GoldfishDevice (unlike other buses, even simple ones like I2C).



The PIC's view is more complicated than a Pin, and more similar to ISA.


ISA is just a pin.  The ISA bus extender literally has five pins
corresponding to the ISA IRQs 7, 6, 5, 4, 3.


ISA is many pins. :)  Goldfish looks similar (32 pins).

Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-28 Thread Anthony Liguori

On 07/28/2011 10:47 AM, Paolo Bonzini wrote:

On 07/28/2011 05:04 PM, Anthony Liguori wrote:

The only way I can see is to teach each device about this interface and
then have a common bus. That implies that you have:

class GoldfishEnumerator : public Device {
GoldfishDevice *slots[N];


FWIW, there's no hardcoded limit in the interface, and the list of
devices is unordered. But that only means you should attach it with

plug-set goldfish_tty::enumerator goldfish_enum

rather than

plug-set goldfish_enum::slots[12] goldfish_tty

If you can confirm that, that's fine.


Yes, you can certainly have an enumerator socket that when set, 
automatically connects the appropriate properties in the enumerator.


That way you don't have to connect things by hand.


};

interface GoldfishDevice {
const char *get_name();
uint64_t get_mmio_base();
...
};

class GoldfishNic : public Device, implements GoldfishDevice
{
const char *get_name(void) {
return nic;
}


uint64_t mmio_base;
uint64_t get_mmio_base() { return mmio_base; }
uint64_t set_mmio_base(uint64_t addr) { mmio_base = addr; }


};


And that's exactly my point. It's a stupid interface full of
getters/setters, which is what you get if you use only interface
inheritance instead of, where appropriate, data containment.



You can certainly do:

struct GoldfishEnumInfo
{
const char *name;
uint64_t mmio_base;
};

interface GoldfishDevice {
GoldfishEnumInfo *get_info();
}

And then:

GoldfishEnumInfo *goldfish_nic_get_info(GoldFishNic *nic)
{
return nic-enuminfo;
}


Interfaces should be reserved for what really depends on the
_implementation_ of the GoldfishNic, not for accessing a bunch of
numbers.


Just define an interface that returns a struct then.  It's no more 
complicated than that.


What I struggle with is whether you're suggesting that the info isn't 
part of the device or whether it is part of the device and you just 
think that we shouldn't need 10 different accessors.



There is no implementation-dependent detail of that kind in the
GoldfishDevice (unlike other buses, even simple ones like I2C).


The PIC's view is more complicated than a Pin, and more similar to ISA.


ISA is just a pin. The ISA bus extender literally has five pins
corresponding to the ISA IRQs 7, 6, 5, 4, 3.


ISA is many pins. :) Goldfish looks similar (32 pins).


Sorry, I meant to say ISA IRQs are just exposed as pins.

My real point is, doing:

class IsaDevice : public Device {
   Pin irq[16];
};

class MyIsaDevice : public IsaDevice {
   int irq_index;
};

And then doing:

my_isa_device-irq_index = 5;

Is a very good way to model ISA IRQ selection.

You can simplify it by having a single IRQ output for each ISA device 
instead of any possible IRQ and then route the IRQ as part of the bus 
connection.


Regards,

Anthony Liguori


Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Paolo Bonzini

On 07/26/2011 09:23 PM, Anthony Liguori wrote:

On 07/26/2011 01:26 PM, Paolo Bonzini wrote:

On 07/26/2011 05:34 PM, Anthony Liguori wrote:
You could just as well say that real life works like this:

class PciSocket {
PciBus *pci_bus;
uint8_t *config;
uint8_t *cmask;
uint8_t *wmask;
uint8_t *w1cmask;
uint8_t *used;
uint32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
...

};

class IsaSocket {
IsaBus *isa_bus;
uint32_t isairq[2]; // not sure this is a good idea, just
int nirqs; // mimicking qdev
uint16_t ioports[32];// statically assigned unlike PCI bars
int nioports;
}

class MyWeirdDevice : public MyBaseDevice {
PciSocket pci;
IsaSocket isa;
};


Hrm, I'm not sure I buy that entirely. I think it would be:

class MyWeirdPciView : public PciDevice {
PciBus *bus;
MyWeirdDevice *dev;
};

class MyWeirdIsaView : public IsaDevice {
IsaBus *bus;
MyWeirdDevice *dev;
};

class MyWeirdDevice : public MyBaseDevice {
MyWeirdPciView pci;
MyWeirdIsaView isa;
}

The views are basically bridges between PCI/ISA and an internal
interface (MyWeirdDevice).


That's yet another possibility.  There are two difference with what I 
had written:


1) the back-pointer from MyWeird*View to MyWeirdDevice replaced by 
container_of.  That's cosmetic;


2) I'm not considering the sockets to be separate devices.  That's the 
difference between proxying PCI to another device (wrong, hardware 
does not do that) and isolating PCI knowledge within a sub-object of 
the device (just an encapsulation choice, hardware is irrelevant).



I don't think the proxy design pattern is the right thing to use.
95% of the time, the device is intrinsically a PCI device.


It's not a proxy.  It's replacing inheritance with containment to get 
the flexibility of data MI without the complexity of diamond hierarchies.



The other 5% of the
time, the device has a well defined interface, and then there is
effectively a PCI bridge. But that PCI bridge isn't generic, it's
specific to that custom interface.


Yes, that can be represented by composition if you wish (an 
ISASerialState containing an 8250 is the canonical example; the 8139 
example below is another).



There's a pin in the IDE cable that determines master or slave depending
on whether it's raised high.


Yes, that's the newer way. There used to be jumpers to choose between
master, slave and cable-select.


That jumper raises the bit on the wire.


Ah ok, I was confusing it with the cable-select wire.  My point was that 
you can choose the jumper representation (low-level) or the cable-select 
representation (high-level, actually matches modern hardware, even 
better from the user POV).  One is easier to manage and better in all 
aspects, but both make sense.  It's irrelevant to this discussion anyway.



Interfaces are the right way to do this. Getting MI right is fairly
hard


But we don't need is-a, we need has-a. Multiple is-a is harder than
single is-a. Multiple has-a does not add any complication.


Yeah, that's what plug properties are for :-)


I agree, but at the cost of pointer chasing and making it harder to
implement get_device_for_socket for buses that need it (in the above
sketch it can be a simple container_of).


Can we be a bit more concrete as I'm having a hard time following your
logic. You're assuming a generic PciSocket class, right? I think that's
not the right approach, as an example:

class Rtl8139PciBridge : public PciDevice
{
Rtl8139 rtldev;
};

class Rtl8139IsaBridge : public IsaDevice
{
Rtl8139 rtldev;
};

With Avi's new memory API, we'd have:

class Rtl8139 : public Device
{
MemoryRegion region[2];
Pin irq;
};

And then the construction code for Rtl8139PciBridge would register the
regions as bars, and connect the PCI lnk to rtldev.irq.

The ISA code would do something similar.


Yes, this looks nice (modulo s/Rtl8139/Rtl8139 */).  But it is not that 
much more flexible than qdev 1.0.


You're right that for the case of two parents above we were looking at a 
contrived example.  The Goldfish platform provides a more interesting 
one.  There you have an interrupt controller and a bus enumerator 
device.  Most devices are connected to both, but conflating them is 
wrong for many reasons;


1) the bus enumerator itself uses an interrupt (raised on hotplug);

2) you can enumerate devices that do not have an interrupt line, and you 
shouldn't need to connect such a device to an interrupt controller;


3) the interrupt controller and bus enumerator use two separate MMIO areas;

4) in principle, other devices could use the interrupt controller (which 
is the only component connected to the CPU's interrupt line) without 
being enumerated.


5) A device with two interrupts has two interrupt interfaces and only 
one enumerator interface.


6) The enumerator interface does not have bus semantics.  The enumerator 
also enumerates itself so it would act as both the bus host and a device 
on the bus.


Composition then lets you use something like this:

class 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Anthony Liguori

On 07/27/2011 03:55 AM, Paolo Bonzini wrote:

Yes, this looks nice (modulo s/Rtl8139/Rtl8139 */). But it is not that
much more flexible than qdev 1.0.

You're right that for the case of two parents above we were looking at a
contrived example. The Goldfish platform provides a more interesting
one. There you have an interrupt controller and a bus enumerator device.
Most devices are connected to both, but conflating them is wrong for
many reasons;

1) the bus enumerator itself uses an interrupt (raised on hotplug);

2) you can enumerate devices that do not have an interrupt line, and you
shouldn't need to connect such a device to an interrupt controller;

3) the interrupt controller and bus enumerator use two separate MMIO areas;

4) in principle, other devices could use the interrupt controller (which
is the only component connected to the CPU's interrupt line) without
being enumerated.

5) A device with two interrupts has two interrupt interfaces and only
one enumerator interface.

6) The enumerator interface does not have bus semantics. The enumerator
also enumerates itself so it would act as both the bus host and a device
on the bus.


I think I understand what your saying here.  But interrupt routing is an 
interesting problem and I've been thinking about it differently then we 
do it today.


The core is:

class Pin : public Device {
   bool level;
};

You can connect a signal to the level to detect edge changes.  You can 
also connect two pins together such that if one raises high, the other 
raises high.


An interrupt controller looks like:

struct InterruptController
{
   Pin *irq[256];
};

In the simple case, you have:

struct UART : public Device
{
   Pin irq;
};

And then you'd set the irq by doing:

apic = new InterruptController()
uart = new UART()

apic-irq[0] = uart-irq;

Or at the qmp layer:

(qemu) plug_get uart irq
uart::irq
(qemu) plug_set apic irq[0] uart::irq

I mention this because I don't think your example below assumes a model 
like this.



Composition then lets you use something like this:

class GoldfishPIC : Device {
Pin parent;
GoldfishInterruptPin *children[32];
Pin (*init_socket_for_irq_num) (GoldfishInterruptPin *, int);
};


So the idea here is that the PIC will multiplex a bunch of interrupts 
into a single line?  I would do this simply as:


class GoldfishPIC : Device {
   Pin out;
   Pin *in[32];
};

The IRQ number is implicit in the socket index, no?  I'm also not sure 
that there's a strong need to have a typed Pin.




class GoldfishInterruptPin {
GoldfishPIC *pic;
Pin irqnum;
};

class GoldfishEnumerator : Device {
GoldfishInterruptPin irq;
GoldfishBusDeviceInfo info;
ListGoldfishBusDeviceInfo allDevices;
...
};

class GoldfishBusDeviceInfo {
GoldfishEnumerator *parent;
char *name;
int id;
ram_addr_t mmio;
int mmio_size;
int irq_base;
int irq_count;
};


Is the enumerator something that has an interface to devices where the 
devices hold this info?  Or is the enumerator just a bank of flash 
that's preprogrammed with fixed info?


If it's the later, I would suggest that we model is in that fashion.  No 
need to teach every single device about the enumerator if they wouldn't 
normally have information about it.



We need lots of new transitions, we need to strive to make things
better. But we need to do things in such a way that:

(1) we have a good idea of what we're going to end up with at the end of
the day

(2) there is incremental value being added to QEMU at every step of
the way

This cannot be done by simply hacking some bits here and there. It
requires design, planning, and flag days when appropriate.


Agreed. The problem I have with QOM is (2). I am not sure we do get
incremental value at every step of the way. We do get incremental value
in the char layer, but we also get additional complexity until the
transition is over.


So roughly speaking, my plan is:

1) Char layer
 - we get dynamic add of CDS, which enables hot plug of virtio-serial
 - we get ability to change CDS properties dynamically

2) Block layer
 - we get -blockdev

3) Display layer
 - we get dynamic add of VGA devices

4) fsdev
 - dynamic add of virtio-9p devices

5) network layer
 - no new features, but better commonality

At each phase, we also get significantly better modularity.  The block 
layer is already good here, but the other backends aren't.


My only real concern is how to attack the device layer incrementally.  I 
don't think it's impossible but it requires careful thought.


I think we can probably retrofit DeviceState as a QOM base class and 
just systematically convert the types over to QOM.  The next step would 
be to change the property registration to be QOM-like.  I think they we 
could probably push out a lot of what's in DeviceState today into 
another base class, then introduce a better Device base class.  Since a 
lot of subsystems should just inherit from Device, that gives us a nice 
way to attack things one subsystem at a time.


I think an approach like this 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Paolo Bonzini

On 07/27/2011 02:48 PM, Anthony Liguori wrote:


So the idea here is that the PIC will multiplex a bunch of interrupts
 into a single line?


Yes, but the device needs to know the interrupt number so it can expose
it through the enumerator interface.  So the configuration cannot be simply

   pic-irq[n] = tty-irq;

Logically, it's more similar to the ISA case, but I doubt the PIC 
distributes all interrupts to everyone in real hardware.



Is the enumerator something that has an interface to devices where
the devices hold this info?  Or is the enumerator just a bank of
flash that's preprogrammed with fixed info?


The former, at least in theory.  Not sure if it also works that way in
real hardware, but that's the model it exposes and the way the Android
guys implemented it.

The device model provides hotplug support, so it is definitely not just 
flash.  Not sure again if this support is used in the hardware.



At each phase, we also get significantly better modularity.


Fine, but when do we decide it's good enough to merge it?  And what if 
it turns out that it's not suitable for devices?  We unified some 
things, but we also dug ourselves in NIH when we could have used 
GObject.  (GObject definitely does not work for devices, but at least we 
don't need to write the infrastructure).



My only real concern is how to attack the device layer incrementally.
I don't think it's impossible but it requires careful thought.


No idea here, honestly. :)

Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Anthony Liguori

On 07/27/2011 10:33 AM, Paolo Bonzini wrote:

On 07/27/2011 02:48 PM, Anthony Liguori wrote:


So the idea here is that the PIC will multiplex a bunch of interrupts
into a single line?


Yes, but the device needs to know the interrupt number so it can expose
it through the enumerator interface. So the configuration cannot be simply

pic-irq[n] = tty-irq;

Logically, it's more similar to the ISA case, but I doubt the PIC
distributes all interrupts to everyone in real hardware.


Is the enumerator something that has an interface to devices where
the devices hold this info? Or is the enumerator just a bank of
flash that's preprogrammed with fixed info?


The former, at least in theory. Not sure if it also works that way in
real hardware, but that's the model it exposes and the way the Android
guys implemented it.

The device model provides hotplug support, so it is definitely not just
flash. Not sure again if this support is used in the hardware.


Sounds like I need to read a little about how this enumerator works.  I 
can't see how this would all operate without the enumerating being some 
form of a bus.





At each phase, we also get significantly better modularity.


Fine, but when do we decide it's good enough to merge it?


I think we should evaluate the complexity vs. value trade off with the 
character device layer (when fully converted) and make the decision in a 
vacuum.


If the complexity seems too high, I can try to also convert the block 
layer and we can reevaluate.  I believe that just with the character 
device layer, it's a net win and I don't think it can be dramatically 
simplified.  The patches are actually not a lot of code.  The only 
complexity is conceptual and that's because it takes into account a lot 
of different problems.


I can even pair things down a bit by removing support for Interfaces and 
simplifying class initialization of need be for the first merge.



And what if it
turns out that it's not suitable for devices? We unified some things,
but we also dug ourselves in NIH when we could have used GObject.
(GObject definitely does not work for devices, but at least we don't
need to write the infrastructure).


I tried to use GObject btw, I can share the results with you if you'd 
like.  Even with backends, I couldn't make properties work.  GObject 
uses GValues for properties which roughly models immutable values in a 
variant.  But I couldn't find a reasonable way to express Plugs and 
Sockets in terms of GValues.


I expect that at some point in the future, GObject will grow GVariant 
properties.  But I still think GVariant isn't quite what it needs to be 
since it still assumes immutable variants that can be copied.


I thought about just using GType but I thought using GType without using 
GObject was probably not a great long term plan as I doubt anyone else 
does this.


Regards,

Anthony Liguori




My only real concern is how to attack the device layer incrementally.
I don't think it's impossible but it requires careful thought.


No idea here, honestly. :)

Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Anthony Liguori

On 07/27/2011 10:33 AM, Paolo Bonzini wrote:

On 07/27/2011 02:48 PM, Anthony Liguori wrote:


So the idea here is that the PIC will multiplex a bunch of interrupts
into a single line?


Yes, but the device needs to know the interrupt number so it can expose
it through the enumerator interface. So the configuration cannot be simply

pic-irq[n] = tty-irq;

Logically, it's more similar to the ISA case, but I doubt the PIC
distributes all interrupts to everyone in real hardware.


Is the enumerator something that has an interface to devices where
the devices hold this info? Or is the enumerator just a bank of
flash that's preprogrammed with fixed info?


The former, at least in theory. Not sure if it also works that way in
real hardware, but that's the model it exposes and the way the Android
guys implemented it.


I can't really find what you're describing.  I think all the specs are 
on http://www.milkymist.org/mmsoc.html


It's seems like there are a couple different kinds of busses, and that 
there is a CSR bus that is used to access configuration information but 
I believe only for CSR devices (which are low speed).


Can you point me towards the current code for this?

Regards,

Anthony Liguori



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Paolo Bonzini

On 07/27/2011 06:28 PM, Anthony Liguori wrote:

On 07/27/2011 10:33 AM, Paolo Bonzini wrote:

On 07/27/2011 02:48 PM, Anthony Liguori wrote:


So the idea here is that the PIC will multiplex a bunch of interrupts
into a single line?


Yes, but the device needs to know the interrupt number so it can expose
it through the enumerator interface. So the configuration cannot be
simply

pic-irq[n] = tty-irq;

Logically, it's more similar to the ISA case, but I doubt the PIC
distributes all interrupts to everyone in real hardware.


Is the enumerator something that has an interface to devices where
the devices hold this info? Or is the enumerator just a bank of
flash that's preprogrammed with fixed info?


The former, at least in theory. Not sure if it also works that way in
real hardware, but that's the model it exposes and the way the Android
guys implemented it.


I can't really find what you're describing. I think all the specs are on
http://www.milkymist.org/mmsoc.html


That's milkymist, not GoldFish.

You can see the code at 
https://github.com/patricksjackson/qemu/blob/android/hw/goldfish_device.c (see 
also 
https://github.com/patricksjackson/qemu/blob/android/hw/goldfish_device.h for 
the structs composing the list).


Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Anthony Liguori

On 07/27/2011 01:51 PM, Paolo Bonzini wrote:

On 07/27/2011 06:28 PM, Anthony Liguori wrote:

On 07/27/2011 10:33 AM, Paolo Bonzini wrote:

On 07/27/2011 02:48 PM, Anthony Liguori wrote:


So the idea here is that the PIC will multiplex a bunch of interrupts
into a single line?


Yes, but the device needs to know the interrupt number so it can expose
it through the enumerator interface. So the configuration cannot be
simply

pic-irq[n] = tty-irq;

Logically, it's more similar to the ISA case, but I doubt the PIC
distributes all interrupts to everyone in real hardware.


Is the enumerator something that has an interface to devices where
the devices hold this info? Or is the enumerator just a bank of
flash that's preprogrammed with fixed info?


The former, at least in theory. Not sure if it also works that way in
real hardware, but that's the model it exposes and the way the Android
guys implemented it.


I can't really find what you're describing. I think all the specs are on
http://www.milkymist.org/mmsoc.html


That's milkymist, not GoldFish.


Oh, Goldfish is fake. It's not real hardware.

The enumerator device is not a real device.  It's weird because it's 
imaginary and was designed specifically within QEMU.


It's not a good example for discussing modelling.

Regards,

Anthony Liguori



You can see the code at
https://github.com/patricksjackson/qemu/blob/android/hw/goldfish_device.c (see
also
https://github.com/patricksjackson/qemu/blob/android/hw/goldfish_device.h for
the structs composing the list).

Paolo






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Peter Maydell
On 26 July 2011 15:02, Anthony Liguori anth...@codemonkey.ws wrote:
 In my attempt at PCI modelling, I had something like:

 struct I440FX
 {
   Device parent;

   PciDevice slots[32];
 };

 Which means that to attach to bus 0, slot 3, fn 0, you do:

 i440fx-slots[3] = mydevice

So what I don't really understand about this model is why the PCI
connection is privileged in the sense that 'mydevice' is actually
an instance of something you can stick directly into one of the PCIBus
device's slots. I would expect that 'mydevice' would have a bunch of
(effectively) interfaces it exposed, and you'd connect i440fx-slots[3]
to mydevice.pciconnector or something. [Which ought to both let the
PCIBus call functions implemented by the device, and vice versa.]

(What would a model of a two-PCI-slot graphics card look like?)

Maybe it would be better to use some other example. After all, the
cases like PCI are the ones our device model already handles pretty
well, so the interesting cases to look at are where we're not so
good at it. What does the implementation of omap2_gpio look like,
for instance? (it's not qdev at the moment but there's a set of
patches on the list which make it so; the guts of the qdevification
are http://patchwork.ozlabs.org/patch/103905/ .)
 That's a device which exposes:
 * 4,5, or 6 MMIO regions (depending on how many 'modules' the
   particular revision you ask for has)
 * a variably sized array of gpio inputs
 * ditto, gpio outputs
 * for each 'module', three specific named outgoing gpio lines
   mpu_irq, dsp_irq and wakeup
 * a number of omap_clk connections, where an omap_clk* represents
   a connection to the OMAP clock tree, and in practice is an
   interface where the omap_gpio can (a) call a function to
   ask what rate is this clock running at? and (b) provide
   a gpio line which will be raised when the clock ticks.
   [omap_gpio doesn't actually use its clock connections but
   other omap devices do; they're interesting because we have
   function calls going in both directions over the interface.]

None of these exposed interfaces are particularly obviously
more important than any of the others -- they're just all
things that might need to be wired up.

I'm particularly interested in how much effort is involved
in defining ad-hoc platform-specific interface types like
omap_clk.

-- PMM



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-27 Thread Anthony Liguori

On 07/27/2011 04:33 PM, Peter Maydell wrote:

On 26 July 2011 15:02, Anthony Liguorianth...@codemonkey.ws  wrote:

In my attempt at PCI modelling, I had something like:

struct I440FX
{
   Device parent;

   PciDevice slots[32];
};

Which means that to attach to bus 0, slot 3, fn 0, you do:

i440fx-slots[3] = mydevice


So what I don't really understand about this model is why the PCI
connection is privileged in the sense that 'mydevice' is actually
an instance of something you can stick directly into one of the PCIBus
device's slots.



Oh, it's not privileged at all.  It just happens to be that modelling 
something simple is simple.  That's goodness.


The example that I used for most of my early testing was meant to be a 
bit more interesting.  I created a Source, Sink, XorGate, AndGate, and 
OrGate and then used a config file to build a full working 8-bit adder.


You can see this at:

http://repo.or.cz/w/qemu/aliguori.git/blob/refs/heads/qdev2

Check out devices/gates and vm.cfg.

Here's a rough model of how it works:

struct XorGate
{
   Device parent;
   Pin out;
   Pin *in[2];
};

In XorGate's initfn, it registers three properties, 'in[0]' and 'in[1]' 
as 'socketPin's and 'out' as 'plugPin'.


When XorGate is realized, it makes sure that both in[0] and in[1] have 
been set (sockets are RW whereas plugs are RO).  It then connects to the 
edge event on the in[0] and in[1] pins and when either event fires, it 
will compute a value, and set the level of out.


XorGate is-a Device, but so is Pin.  The following things are valid:

(qemu) plug_create xor-gate gate0
(qemu) plug_create xor-gate gate1
(qemu) plug_create xor-gate gate2
(qemu) plug_get gate1 out
gate1::out
(qemu) plug_set xor-gate in[0] gate1::out
(qemu) plug_get gate2 out
gate2::out
(qemu) plug_set xor-gate in[1] gate2::out

Which creates a simple tree of two xor gates who's outputs are tied to 
another xor gate.  Or:


   XorGate /
- XorGate /\
  \
   XorGate /
   \

The 'out' property of XorGate is really a child device.  All devices 
(all plugs for that matter) have a global namespace.  By convention, 
uniqueness in name is guaranteed for child devices by reserving the '::' 
separator and naming children based on 'parentname::propertyname'.  But 
for correctness, the right way to figure out the name of a child is by 
reading the property.


So to answer your above question, a multi PCI slot graphics adapter is 
simply:


struct GraphicsSlot {
   PciDevice parent;
};

struct MultislotGraphicsCard {
   Device parent;

   GraphicsSlot slot[2];
};

Then conceptually:

mgc = new MultislotGraphicsCard();

i440fx-slot[1] = mgc.slot[0];
i440fx-slot[2] = mgc.slot[1];

You do not need to ever assign a device directly to a socket.  This is a 
fundamental different between QOM and qdev.  There is no concept of 
parent bus.  There's no concept of parent--even with composition. 
Devices can have links to zero or more other Devices.  They can also 
create devices within themselves but those devices don't have any 
special knowledge of that fact.




 I would expect that 'mydevice' would have a bunch of
(effectively) interfaces it exposed, and you'd connect i440fx-slots[3]
to mydevice.pciconnector or something. [Which ought to both let the
PCIBus call functions implemented by the device, and vice versa.]

(What would a model of a two-PCI-slot graphics card look like?)

Maybe it would be better to use some other example. After all, the
cases like PCI are the ones our device model already handles pretty
well, so the interesting cases to look at are where we're not so
good at it. What does the implementation of omap2_gpio look like,
for instance? (it's not qdev at the moment but there's a set of
patches on the list which make it so; the guts of the qdevification
are http://patchwork.ozlabs.org/patch/103905/ .)
  That's a device which exposes:
  * 4,5, or 6 MMIO regions (depending on how many 'modules' the
particular revision you ask for has)
  * a variably sized array of gpio inputs
  * ditto, gpio outputs


struct OmapGpio
{
Device parent;

size_t nb_regions;
MemoryRegion *regions;

size_t nb_out;
Pin *out;

size_t nb_in;
Pin **in;
};

void omap_gpio_set_nb_out(OmapGpio *obj, size_t value);
void omap_gpio_set_nb_in(OmapGpio *obj, size_t value);
void omap_gpio_set_nb_regions(OmapGpio *obj, size_t value);

At initfn(), you register three integer properties, 'nb_out', 'nb_in', 
'nb_regions'.


In the respective setters, you allocate the appropriate array and then 
unregister the old properties, and then register teh new ones.  For 
instance:


void omap_gpio_set_nb_out(OmapGpio *obj, size_t value)
{
   /* remove old properties */
   for (i = 0; i  obj-nb_out; i++) {
   plug_del_property_plug(PLUG(obj), out[%d], i);
   }

   obj-out = realloc(obj-out, new_size);
   obj-nb_out = value;

   /* add new properties */
   for (i = 0; i  obj-nb_out; i++) {
   

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Paolo Bonzini

On 07/25/2011 03:44 AM, Anthony Liguori wrote:

Hi,

This series is the rough beginnings of the QEMU Object Model.  This is basically
qdev generalized on steroids.

This series includes the core infrastructure, a strawman Device type, and
the beginnings of the conversion of CharDriverState.  This is in a rougher
state than I would like it to be but I wanted to get the concepts on the list
as soon as possible.

My plan is to drop the Device parts from future versions of the series and just
focus on backends to start with.


I am not sure of how the Device and Char/Block/NetworkDriver bits relate 
to each other.  It seems to me that they are two very different families 
of objects, and we should treat them differently.


For host devices (Char/Block/Network) we have a relatively simple 
interface but we need a richer way to create and destroy the objects at 
runtime.  We have it already for block and network, we don't for char, 
but it is done ad hoc for each hierarchy.  We do not have a deep 
hierarchy, in fact there is no hierarchy at all (only one abstract class 
per subsystem).


Honestly, it is not too bad.  It may not be the cleanest code, but is it 
worth the kind of ramifications that your patch has?  Of course, the 
answer could be yes if the same model can be applied to devices. 
Devices do have the same introspection needs more or less, and I like 
your ideas there.  However, the requirements are very different in terms 
of composition.


Also because there is no hierarchy, composition in host devices can be 
done very easily.  A decorator for char/block devices, such as a tee 
device, can treat the wrapped object(s) the same independent of the 
actual class.  A simple vtable works very well.  GObject would also do 
well, unifying the introspection at the cost of significantly more 
boilerplate.


(Of course, we could rewrite QEMU in Vala).

For *guest* devices, however, this is not the case.  The PCI host needs 
to know that the device on the other end is a PCI device.  Even the 
simplest bus, for example I2C, has methods defined on its children.


So, the most important point, it seems to me, is to support composition 
effectively.  There need not be any hierarchy at all---not even the 
two-level hierarchy we have now, everything can inherit from 
DeviceState---but the combination between devices must be:


1) in a flexible manner, so that it can express complex topologies (as 
long as plugs and sockets have the same shape of course);


2) in an easily introspectable manner, so that migration and QMP and so 
on work very well in the presence of said topologies;


3) in a precise manner, so that the two devices being connected can 
interact effectively;



The current qdev fails completely at (1).  (2) is very limited if you 
consider qdev only; qdev+VMState is at least decent, though nowhere near 
the potential of QOM.


However, qdev gets (3) right by making interaction between the parent 
and the child go through a bus object that knows the details of both. 
In particular, bus objects and their vtable structures are very 
effective in qdev because they provide flexibility and avoid impedence 
mismatch, with a very limited amount of boilerplate.


By contrast, the plug/socket model in QOM achieves (1) and (2), but in 
my opinion it fails at (3).  The model for example is not effective in 
specifying the properties of the socket, which are roughly are the bus 
properties and the fields added by DeviceState abstract subclasses in 
the current qdev; it is not clear where they would live in QOM.  Perhaps 
in the parent device or in an intermediate object between the parent and 
the child; if the latter, it looks like a lot of pointer chasing and a 
conversion nightmare.



Based on my earlier conversations with Peter, I thought a bit on how to 
do more incremental changes to qdev in order to overcome the 
inflexibility.  Here is a rough overview of the steps:



1) make properties more flexible.  In particular, we *absolutely* need 
array properties, either static or dynamic.  The current special casing 
of GPIO pins is required exactly because we do not have arrays of 
properties.


Also, since arrays occur a lot in the device state, array properties 
would also be required to be able to introspect on run-time properties 
(which are now part of VMState only).  However, I am not going to 
consider run-time introspection much more.  It is a simple matter of 
programming if your general introspection design is done right.



2) add more kinds of first-class (user specifiable) properties.  GPIO 
pins, for example, which are already part of qdev but cannot be 
specified by the user on the command line.  Possibly memory regions too. 
 Anything that can be used to configure a device (with respect to the 
main bus or to its parent) should be a property.



3) at this point, you can get rid of the specialties of SysBus devices. 
 IRQs are an array of GPIO properties, same for memory regions.  SysBus 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Anthony Liguori

On 07/26/2011 07:59 AM, Paolo Bonzini wrote:

For host devices (Char/Block/Network) we have a relatively simple
interface but we need a richer way to create and destroy the objects at
runtime. We have it already for block and network, we don't for char,
but it is done ad hoc for each hierarchy. We do not have a deep
hierarchy, in fact there is no hierarchy at all (only one abstract class
per subsystem).

Honestly, it is not too bad. It may not be the cleanest code, but is it
worth the kind of ramifications that your patch has? Of course, the
answer could be yes if the same model can be applied to devices.
Devices do have the same introspection needs more or less, and I like
your ideas there. However, the requirements are very different in terms
of composition.

Also because there is no hierarchy, composition in host devices can be
done very easily. A decorator for char/block devices, such as a tee
device, can treat the wrapped object(s) the same independent of the
actual class. A simple vtable works very well. GObject would also do
well, unifying the introspection at the cost of significantly more
boilerplate.


The polymorphism model of QOM is identical to GObject so I'm not sure 
what you mean here.


In the case of tee, it's just an object with two sockets.



(Of course, we could rewrite QEMU in Vala).

For *guest* devices, however, this is not the case. The PCI host needs
to know that the device on the other end is a PCI device. Even the
simplest bus, for example I2C, has methods defined on its children.


I have PCI patches, but didn't post them in the series.  Here's how it 
works:


The PCI host controller, the i440fx, has 32 sockets of PCIDevice. 
PCIDevice is a base class.


The PCI host controller implements a PCIBus interface.  The PCIDevices 
have a socket of a PCIBus


Connecting a PCIDevice to the host bus involves setting the socket on 
the PCI host controller with the PCIDevice and then setting the 
PCIDevice's bus socket with the host controller.


A PCIDevice can also be a PCIBus by implementing the PCIBus interface. 
This is what enables a PCI bridge to make sense in this model.


If you're interested, the tree that has this is 
http://repo.or.cz/w/qemu/aliguori.git/tree/qdev2:/devices



So, the most important point, it seems to me, is to support composition
effectively. There need not be any hierarchy at all---not even the
two-level hierarchy we have now, everything can inherit from
DeviceState---but the combination between devices must be:


I think composition is being overloaded here.  When I say composition, I 
mean that one device is created out of multiple other devices. 
Something like the PIIX3 is composed of an RTC, UART, etc.


That's different that connecting up the links in the device tree graph.


1) in a flexible manner, so that it can express complex topologies (as
long as plugs and sockets have the same shape of course);


Right, this is what we do today in QOM.  Plugs and Sockets are typed. 
Those types can be interfaces or base classes so there's a lot of 
flexibility.



2) in an easily introspectable manner, so that migration and QMP and so
on work very well in the presence of said topologies;


The 'qsh' tree can view the entire device model as a synthetic file 
system.  Plugs are represented as sub directories and sockets as 
symbolic links.  I plan on writing a quick FUSE file system too.


There is type information with all of the attributes that's not visible 
in this view but it's there nonetheless.



3) in a precise manner, so that the two devices being connected can
interact effectively;


The current qdev fails completely at (1). (2) is very limited if you
consider qdev only; qdev+VMState is at least decent, though nowhere near
the potential of QOM.

However, qdev gets (3) right by making interaction between the parent
and the child go through a bus object that knows the details of both. In
particular, bus objects and their vtable structures are very effective
in qdev because they provide flexibility and avoid impedence mismatch,
with a very limited amount of boilerplate.

By contrast, the plug/socket model in QOM achieves (1) and (2), but in
my opinion it fails at (3). The model for example is not effective in
specifying the properties of the socket, which are roughly are the bus
properties and the fields added by DeviceState abstract subclasses in
the current qdev;


There are no properties of the socket.

If you look at something like adding a PCI device in qdev, you add a 
child and set properties of the child to identify how the device sits on 
the PCI bus.


I'd characterize this as awkward, at best.  The slot index is not a 
property of the device, it's a property of how the device is connected 
to the PCI bus.


In my attempt at PCI modelling, I had something like:

struct I440FX
{
   Device parent;

   PciDevice slots[32];
};

Which means that to attach to bus 0, slot 3, fn 0, you do:

i440fx-slots[3] = mydevice

Likewise, if slot 4 contains a 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Paolo Bonzini

On 07/26/2011 04:02 PM, Anthony Liguori wrote:

Also because there is no hierarchy, composition in host devices can be
done very easily. A decorator for char/block devices, such as a tee
device, can treat the wrapped object(s) the same independent of the
actual class. A simple vtable works very well. GObject would also do
well, unifying the introspection at the cost of significantly more
boilerplate.


The polymorphism model of QOM is identical to GObject so I'm not sure
what you mean here.


GObject instead of QOM (just so that we have something that is already 
written).



In the case of tee, it's just an object with two sockets.


Yes, understood.


I have PCI patches, but didn't post them in the series. Here's how it
works:

The PCI host controller, the i440fx, has 32 sockets of PCIDevice.
PCIDevice is a base class.


And as such it can add data members.  But when a device is on two buses, 
you cannot have both of them adding data members.  I know MI is hard to 
get right, and in fact I'm not proposing to do MI---not even interface 
inheritance.  I don't want to have any base class but DeviceState.



The PCI host controller implements a PCIBus interface. The PCIDevices
have a socket of a PCIBus

Connecting a PCIDevice to the host bus involves setting the socket on
the PCI host controller with the PCIDevice and then setting the
PCIDevice's bus socket with the host controller.

A PCIDevice can also be a PCIBus by implementing the PCIBus interface.
This is what enables a PCI bridge to make sense in this model.

If you're interested, the tree that has this is
http://repo.or.cz/w/qemu/aliguori.git/tree/qdev2:/devices


Yes, this is pretty much what I had imagined.  But it does not scale to 
a topology where you have two parents, both of which want to add data 
members.



1) in a flexible manner, so that it can express complex topologies (as
long as plugs and sockets have the same shape of course);


Right, this is what we do today in QOM. Plugs and Sockets are typed.
Those types can be interfaces or base classes so there's a lot of
flexibility.


Interfaces (is-a) are less flexible than embedded objects (has-a).


There are no properties of the socket.

If you look at something like adding a PCI device in qdev, you add a
child and set properties of the child to identify how the device sits on
the PCI bus.

I'd characterize this as awkward, at best. The slot index is not a
property of the device, it's a property of how the device is connected
to the PCI bus.


Yes, for a PCI address I agree.  But in a (parallel) SCSI bus, the LUN 
is logically a property of the device.  Same as IDE when you used to set 
jumpers to choose master/slave.  Or ISA interrupt lines.


Once you have something like this for a device that bridges two buses, 
interfaces require a lot of boilerplate for useless getters/setters.



i440fx-slots[3] = mydevice

Likewise, if slot 4 contains a PCI-to-PCI bridge that ends up being bus
1, and you want to assign to bus 1, slot 2, fn 0:

i440fx-slots[4]-slots[2] = myotherdevice;

Now you may observe that this is awkward compared to saying bus 1.


No, I have no problem with that. :)


The same applies equally to IDE.

ide-primary.master = disk1;
ide-secondary.master = cdrom;


For IDE, an equally good model would be:

ide-primary.add(disk1);
disk1.masterSlave = MASTER;
ide-secondary.add(cdrom);
cdrom.masterSlave = MASTER;


5) convert buses to compound properties. Rather than inheriting from
PCIDevice, a PCI device would inherit straight from DeviceState and
include a PCIDevice struct that defines the backlink from a device to
its parent. Note that since we're using C, this is not a big change from
what we're doing now! (Inheritance by containment is a special case of
containment.) And it allows to define very flexibly a device that would
have to sit on two or more buses in the current qdev model. More
importantly, it keeps the effectiveness of the qbus ops model, while
removing the constraint of a tree topology.


Interfaces are the right way to do this. Getting MI right is fairly hard


But we don't need is-a, we need has-a.  Multiple is-a is harder than 
single is-a.  Multiple has-a does not add any complication.



I think all of the requirements you've outlined are currently handled in
QOM.


They more than likely are.  The question is whether they're handled in 
the most programmer-efficient manner, and whether the advantages of a 
single grand unified object model for host and guest devices is worth 
the effort.


Paolo



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Anthony Liguori

On 07/26/2011 09:35 AM, Paolo Bonzini wrote:

On 07/26/2011 04:02 PM, Anthony Liguori wrote:

Also because there is no hierarchy, composition in host devices can be
done very easily. A decorator for char/block devices, such as a tee
device, can treat the wrapped object(s) the same independent of the
actual class. A simple vtable works very well. GObject would also do
well, unifying the introspection at the cost of significantly more
boilerplate.


The polymorphism model of QOM is identical to GObject so I'm not sure
what you mean here.


GObject instead of QOM (just so that we have something that is already
written).


In the case of tee, it's just an object with two sockets.


Yes, understood.


I have PCI patches, but didn't post them in the series. Here's how it
works:

The PCI host controller, the i440fx, has 32 sockets of PCIDevice.
PCIDevice is a base class.


And as such it can add data members. But when a device is on two buses,
you cannot have both of them adding data members. I know MI is hard to
get right, and in fact I'm not proposing to do MI---not even interface
inheritance. I don't want to have any base class but DeviceState.


I could use a concrete example here, but here's how this would be expressed:

class MyWeirdDevice : public MyBaseDevice, implements PciDevice, IsaDevice
{
PciBus *pci_bus;
IsaDevice *isa_bus;
};

Which actually models hw pretty well.  A device that exists on two 
busses has to have two sockets that can accept the plugs from the busses 
they're joining.


It's pretty much exactly how it works in real life.




The PCI host controller implements a PCIBus interface. The PCIDevices
have a socket of a PCIBus

Connecting a PCIDevice to the host bus involves setting the socket on
the PCI host controller with the PCIDevice and then setting the
PCIDevice's bus socket with the host controller.

A PCIDevice can also be a PCIBus by implementing the PCIBus interface.
This is what enables a PCI bridge to make sense in this model.

If you're interested, the tree that has this is
http://repo.or.cz/w/qemu/aliguori.git/tree/qdev2:/devices


Yes, this is pretty much what I had imagined. But it does not scale to a
topology where you have two parents, both of which want to add data
members.


Which would be true MI.  The problem with true MI is that you'll end up 
with a diamond if you try to have anything useful (like properties) in 
the base.


The common solution is to have the ability to has-a implementation of 
the interface.



1) in a flexible manner, so that it can express complex topologies (as
long as plugs and sockets have the same shape of course);


Right, this is what we do today in QOM. Plugs and Sockets are typed.
Those types can be interfaces or base classes so there's a lot of
flexibility.


Interfaces (is-a) are less flexible than embedded objects (has-a).


It depends on what you're trying to model I guess.  In some cases where 
the interface is more or less stateless or that state isn't common among 
implementations, interfaces are quite nice.



There are no properties of the socket.

If you look at something like adding a PCI device in qdev, you add a
child and set properties of the child to identify how the device sits on
the PCI bus.

I'd characterize this as awkward, at best. The slot index is not a
property of the device, it's a property of how the device is connected
to the PCI bus.


Yes, for a PCI address I agree. But in a (parallel) SCSI bus, the LUN is
logically a property of the device.


 Same as IDE when you used to set

jumpers to choose master/slave. Or ISA interrupt lines.


The ISA dip switches literally select which line of the bus gets routed 
to the device.  All devices have access to all interrupt lines through 
the bus.


So when modelling, it makes sense to have the irq be a property of the 
device and then to have the bus interface expose the irqs.  For instance:


struct IsaBusClass
{
   void (*set_irq_level)(IsaBus *bus, int irq, bool level);
};

I don't know enough about SCSI to know whether it makes sense to have 
LUN be a property of the bus or the device.  If LUN negotiation is aided 
by the controller and fixed after startup, then I think it makes sense 
for there to be a fixed number of sockets in the bus and then for the 
bus to do LUN assignment at realize (possibly looking at each device to 
see what the requested LUN is).



Once you have something like this for a device that bridges two buses,
interfaces require a lot of boilerplate for useless getters/setters.


Can you elaborate?




i440fx-slots[3] = mydevice

Likewise, if slot 4 contains a PCI-to-PCI bridge that ends up being bus
1, and you want to assign to bus 1, slot 2, fn 0:

i440fx-slots[4]-slots[2] = myotherdevice;

Now you may observe that this is awkward compared to saying bus 1.


No, I have no problem with that. :)


The same applies equally to IDE.

ide-primary.master = disk1;
ide-secondary.master = cdrom;


For IDE, an equally good model would be:


Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Paolo Bonzini

On 07/26/2011 05:34 PM, Anthony Liguori wrote:

And as such it can add data members. But when a device is on two buses,
you cannot have both of them adding data members. I know MI is hard to
get right, and in fact I'm not proposing to do MI---not even interface
inheritance. I don't want to have any base class but DeviceState.


I could use a concrete example here, but here's how this would be
expressed:

class MyWeirdDevice : public MyBaseDevice, implements PciDevice, IsaDevice
{
PciBus *pci_bus;
IsaDevice *isa_bus;
};

Which actually models hw pretty well. A device that exists on two busses
has to have two sockets that can accept the plugs from the busses
they're joining.

It's pretty much exactly how it works in real life.


You could just as well say that real life works like this:

class PciSocket {
PciBus *pci_bus;
uint8_t *config;
uint8_t *cmask;
uint8_t *wmask;
uint8_t *w1cmask;
uint8_t *used;
uint32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
...

};

class IsaSocket {
IsaBus *isa_bus;
uint32_t isairq[2];  // not sure this is a good idea, just
int nirqs;   // mimicking qdev
uint16_t ioports[32];// statically assigned unlike PCI bars
int nioports;
}

class MyWeirdDevice : public MyBaseDevice {
PciSocket pci;
IsaSocket isa;
};



Yes, this is pretty much what I had imagined. But it does not scale to a
topology where you have two parents, both of which want to add data
members.


Which would be true MI. The problem with true MI is that you'll end up
with a diamond if you try to have anything useful (like properties) in
the base.


See above for how you would avoid that.


1) in a flexible manner, so that it can express complex topologies (as
long as plugs and sockets have the same shape of course);


Right, this is what we do today in QOM. Plugs and Sockets are typed.
Those types can be interfaces or base classes so there's a lot of
flexibility.


Interfaces (is-a) are less flexible than embedded objects (has-a).


It depends on what you're trying to model I guess. In some cases where
the interface is more or less stateless or that state isn't common among
implementations, interfaces are quite nice.


Yes, I'm not sure this is the case here. :)


  Same as IDE when you used to set

jumpers to choose master/slave. Or ISA interrupt lines.


The ISA dip switches literally select which line of the bus gets routed
to the device. All devices have access to all interrupt lines through
the bus.

So when modelling, it makes sense to have the irq be a property of the
device and then to have the bus interface expose the irqs. For instance:

struct IsaBusClass
{
void (*set_irq_level)(IsaBus *bus, int irq, bool level);
};


Agreed.  Though I'm not sure that the same is true for all fields in 
qemu's current PCIDevice.



Once you have something like this for a device that bridges two buses,
interfaces require a lot of boilerplate for useless getters/setters.


Can you elaborate?


If you store data (configuration space etc.) in the device, and the bus 
has to access it, you need getters/setters in the interface.  Letting 
the bus hold an interior reference to the PciSocket (perhaps adding a 
single get_device_for_socket function to the PciSocketOps) solves the 
problem.



The same applies equally to IDE.

ide-primary.master = disk1;
ide-secondary.master = cdrom;


For IDE, an equally good model would be:

ide-primary.add(disk1);
disk1.masterSlave = MASTER;
ide-secondary.add(cdrom);
cdrom.masterSlave = MASTER;


There's a pin in the IDE cable that determines master or slave depending
on whether it's raised high.


Yes, that's the newer way.  There used to be jumpers to choose between 
master, slave and cable-select.



I think modelling it that way makes more sense from an end user
perspective since it prevents the possibility of have two master devices
(which is incorrect).


... but you could do that, if for some reason you wanted to model the 
jumper-based world.  But this is a mostly irrelevant digression.



Interfaces are the right way to do this. Getting MI right is fairly hard


But we don't need is-a, we need has-a. Multiple is-a is harder than
single is-a. Multiple has-a does not add any complication.


Yeah, that's what plug properties are for :-)


I agree, but at the cost of pointer chasing and making it harder to 
implement get_device_for_socket for buses that need it (in the above 
sketch it can be a simple container_of).



I think all of the requirements you've outlined are currently handled in
QOM.


They more than likely are. The question is whether they're handled in
the most programmer-efficient manner, and whether the advantages of a
single grand unified object model for host and guest devices is worth
the effort.


Indeed. I think that it's a no brainer for the backends and that's why
I'm starting there.


I don't think it's a no brainer.  It's simply much easier, but right now 
it is also a 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-26 Thread Anthony Liguori

On 07/26/2011 01:26 PM, Paolo Bonzini wrote:

On 07/26/2011 05:34 PM, Anthony Liguori wrote:

And as such it can add data members. But when a device is on two buses,
you cannot have both of them adding data members. I know MI is hard to
get right, and in fact I'm not proposing to do MI---not even interface
inheritance. I don't want to have any base class but DeviceState.


I could use a concrete example here, but here's how this would be
expressed:

class MyWeirdDevice : public MyBaseDevice, implements PciDevice,
IsaDevice
{
PciBus *pci_bus;
IsaDevice *isa_bus;
};

Which actually models hw pretty well. A device that exists on two busses
has to have two sockets that can accept the plugs from the busses
they're joining.

It's pretty much exactly how it works in real life.


You could just as well say that real life works like this:

class PciSocket {
PciBus *pci_bus;
uint8_t *config;
uint8_t *cmask;
uint8_t *wmask;
uint8_t *w1cmask;
uint8_t *used;
uint32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
...

};

class IsaSocket {
IsaBus *isa_bus;
uint32_t isairq[2]; // not sure this is a good idea, just
int nirqs; // mimicking qdev
uint16_t ioports[32];// statically assigned unlike PCI bars
int nioports;
}

class MyWeirdDevice : public MyBaseDevice {
PciSocket pci;
IsaSocket isa;
};


Hrm, I'm not sure I buy that entirely.  I think it would be:

class MyWeirdPciView : public PciDevice {
  PciBus *bus;
  MyWeirdDevice *dev;
};

class MyWeirdIsaView : public IsaDevice {
  IsaBus *bus;
  MyWeirdDevice *dev;
};

class MyWeirdDevice : public MyBaseDevice {
  MyWeirdPciView pci;
  MyWeirdIsaView isa;
}

The views are basically bridges between PCI/ISA and an internal 
interface (MyWeirdDevice).


I don't think having a generic PciSocket class that offloads PCI 
knowledge to another device is the right model (assuming that's why 
you're suggesting).  It's basically proxying PCI to another device.



Once you have something like this for a device that bridges two buses,
interfaces require a lot of boilerplate for useless getters/setters.


Can you elaborate?


If you store data (configuration space etc.) in the device, and the bus
has to access it, you need getters/setters in the interface. Letting the
bus hold an interior reference to the PciSocket (perhaps adding a single
get_device_for_socket function to the PciSocketOps) solves the problem.


I don't think the proxy design pattern is the right thing to use.  95% 
of the time, the device is intrinsically a PCI device.  The other 5% of 
the time, the device has a well defined interface, and then there is 
effectively a PCI bridge.  But that PCI bridge isn't generic, it's 
specific to that custom interface.



The same applies equally to IDE.

ide-primary.master = disk1;
ide-secondary.master = cdrom;


For IDE, an equally good model would be:

ide-primary.add(disk1);
disk1.masterSlave = MASTER;
ide-secondary.add(cdrom);
cdrom.masterSlave = MASTER;


There's a pin in the IDE cable that determines master or slave depending
on whether it's raised high.


Yes, that's the newer way. There used to be jumpers to choose between
master, slave and cable-select.


That jumper raises the bit on the wire.


Interfaces are the right way to do this. Getting MI right is fairly
hard


But we don't need is-a, we need has-a. Multiple is-a is harder than
single is-a. Multiple has-a does not add any complication.


Yeah, that's what plug properties are for :-)


I agree, but at the cost of pointer chasing and making it harder to
implement get_device_for_socket for buses that need it (in the above
sketch it can be a simple container_of).


Can we be a bit more concrete as I'm having a hard time following your 
logic.  You're assuming a generic PciSocket class, right?  I think 
that's not the right approach, as an example:


class Rtl8139PciBridge : public PciDevice
{
   Rtl8139 rtldev;
};

class Rtl8139IsaBridge : public IsaDevice
{
   Rtl8139 rtldev;
};

With Avi's new memory API, we'd have:

class Rtl8139 : public Device
{
   MemoryRegion region[2];
   Pin irq;
};

And then the construction code for Rtl8139PciBridge would register the 
regions as bars, and connect the PCI lnk to rtldev.irq.


The ISA code would do something similar.


I think all of the requirements you've outlined are currently
handled in
QOM.


They more than likely are. The question is whether they're handled in
the most programmer-efficient manner, and whether the advantages of a
single grand unified object model for host and guest devices is worth
the effort.


Indeed. I think that it's a no brainer for the backends and that's why
I'm starting there.


I don't think it's a no brainer. It's simply much easier, but right now
it is also a solution in search of a problem (if all you want is dynamic
creation of character devices, you could do that without a generic
object model).


And that solves the problem yet again for one layer.  But what about 
block, fsdev, and DisplayState?  We can keep 

Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-25 Thread Kevin Wolf
Am 25.07.2011 03:44, schrieb Anthony Liguori:
 Hi,
 
 This series is the rough beginnings of the QEMU Object Model.  This is 
 basically
 qdev generalized on steroids.
 
 This series includes the core infrastructure, a strawman Device type, and
 the beginnings of the conversion of CharDriverState.  This is in a rougher
 state than I would like it to be but I wanted to get the concepts on the list
 as soon as possible.
 
 My plan is to drop the Device parts from future versions of the series and 
 just
 focus on backends to start with.
 
 Please note that this series has an awful lot of ramifications.  Most of our
 current command line options would become deprecated, the build system will
 change significantly, and a lot of our QMP functions will become deprecated.
 
 It seems like a lot of change, but hopefully this series illustrates how we
 can do it very incrementally with value being added at each stage of the
 conversion.

I haven't looked in much detail at it yet, but it has still the same
problem I was talking about last week: Patches 17-21 don't actually
convert existing code, but they add new code. This means that we can't
review only the changes, but have to review the whole code. It also
makes conflicts with patches modifying the old version hard to even notice.


On another note, I'm not so sure if your renaming is really helpful. It
doesn't matter that much with qemu-char because someone thought having
the function pointers in CharDriverState was a good idea, but if you're
consistent, the rename would go like this in the block layer:

BlockDriverState - BlockDriver
BlockDriver - BlockDriverClass

IMHO, that's not very helpful, but just going to create confusion. We
could probably discuss other parts of the terminology, too, but let's
save the bikeshedding for later.

Kevin



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-25 Thread Anthony Liguori

On 07/25/2011 06:21 AM, Kevin Wolf wrote:

Am 25.07.2011 03:44, schrieb Anthony Liguori:

Hi,

This series is the rough beginnings of the QEMU Object Model.  This is basically
qdev generalized on steroids.

This series includes the core infrastructure, a strawman Device type, and
the beginnings of the conversion of CharDriverState.  This is in a rougher
state than I would like it to be but I wanted to get the concepts on the list
as soon as possible.

My plan is to drop the Device parts from future versions of the series and just
focus on backends to start with.

Please note that this series has an awful lot of ramifications.  Most of our
current command line options would become deprecated, the build system will
change significantly, and a lot of our QMP functions will become deprecated.

It seems like a lot of change, but hopefully this series illustrates how we
can do it very incrementally with value being added at each stage of the
conversion.


I haven't looked in much detail at it yet, but it has still the same
problem I was talking about last week: Patches 17-21 don't actually
convert existing code, but they add new code.


Actually, it's mostly existing code.  In terms of incremental 
conversion, the most straight forward way is to adds the new version 
side-by-side with the old version and then remove the old version.


Converting in device in place requires some gymnastics.  If you think 
it's absolutely critical, I could try to do it but I'm not sure I agree 
it's the thing to do.



This means that we can't
review only the changes, but have to review the whole code. It also
makes conflicts with patches modifying the old version hard to even notice.


On another note, I'm not so sure if your renaming is really helpful. It
doesn't matter that much with qemu-char because someone thought having
the function pointers in CharDriverState was a good idea, but if you're
consistent, the rename would go like this in the block layer:

BlockDriverState -  BlockDriver
BlockDriver -  BlockDriverClass


I think we do need to introduce consistent naming conventions.

If those conventions are FooState and Foo, that could be okay, but the 
code base today is absolutely not consistent on it.


I think Foo and FooClass is better because Foo is the most common usage 
of the type and it's less characters to type.


Regards,

Anthony Liguori



IMHO, that's not very helpful, but just going to create confusion. We
could probably discuss other parts of the terminology, too, but let's
save the bikeshedding for later.

Kevin






Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-25 Thread Kevin Wolf
Am 25.07.2011 14:45, schrieb Anthony Liguori:
 On 07/25/2011 06:21 AM, Kevin Wolf wrote:
 Am 25.07.2011 03:44, schrieb Anthony Liguori:
 Hi,

 This series is the rough beginnings of the QEMU Object Model.  This is 
 basically
 qdev generalized on steroids.

 This series includes the core infrastructure, a strawman Device type, and
 the beginnings of the conversion of CharDriverState.  This is in a rougher
 state than I would like it to be but I wanted to get the concepts on the 
 list
 as soon as possible.

 My plan is to drop the Device parts from future versions of the series and 
 just
 focus on backends to start with.

 Please note that this series has an awful lot of ramifications.  Most of our
 current command line options would become deprecated, the build system will
 change significantly, and a lot of our QMP functions will become deprecated.

 It seems like a lot of change, but hopefully this series illustrates how we
 can do it very incrementally with value being added at each stage of the
 conversion.

 I haven't looked in much detail at it yet, but it has still the same
 problem I was talking about last week: Patches 17-21 don't actually
 convert existing code, but they add new code.
 
 Actually, it's mostly existing code.  In terms of incremental 
 conversion, the most straight forward way is to adds the new version 
 side-by-side with the old version and then remove the old version.
 
 Converting in device in place requires some gymnastics.  If you think 
 it's absolutely critical, I could try to do it but I'm not sure I agree 
 it's the thing to do.

Okay, if it isn't possible with reasonable effort, I guess we'll have to
bite the bullet and give it a very careful manual review immediately
before the merge.

By the way, I see that you create new directories. You probably have an
idea of what the directory structure will look like after the whole
conversion is completed. Can you share this idea with us?

 This means that we can't
 review only the changes, but have to review the whole code. It also
 makes conflicts with patches modifying the old version hard to even notice.


 On another note, I'm not so sure if your renaming is really helpful. It
 doesn't matter that much with qemu-char because someone thought having
 the function pointers in CharDriverState was a good idea, but if you're
 consistent, the rename would go like this in the block layer:

 BlockDriverState -  BlockDriver
 BlockDriver -  BlockDriverClass
 
 I think we do need to introduce consistent naming conventions.
 
 If those conventions are FooState and Foo, that could be okay, but the 
 code base today is absolutely not consistent on it.
 
 I think Foo and FooClass is better because Foo is the most common usage 
 of the type and it's less characters to type.

Maybe. But then, CharDriver is a really bad names for an instance. There
is only one driver, which made it a good name for the class until now.
Maybe CharBackend and CharBackendClass (or CharBackendDriver) would be a
more sensible replacement that follows your pattern.

Kevin



Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model

2011-07-25 Thread Anthony Liguori

On 07/25/2011 08:08 AM, Kevin Wolf wrote:

Am 25.07.2011 14:45, schrieb Anthony Liguori:
Okay, if it isn't possible with reasonable effort, I guess we'll have to
bite the bullet and give it a very careful manual review immediately
before the merge.

By the way, I see that you create new directories. You probably have an
idea of what the directory structure will look like after the whole
conversion is completed. Can you share this idea with us?


Just the logic extension of what we have already:

block/
chrdrv/
net/
qom/
qapi/
devices/
  \  pc/
   | pci/
   | scsi/
   | etc.


I think Foo and FooClass is better because Foo is the most common usage
of the type and it's less characters to type.


Maybe. But then, CharDriver is a really bad names for an instance. There
is only one driver, which made it a good name for the class until now.
Maybe CharBackend and CharBackendClass (or CharBackendDriver) would be a
more sensible replacement that follows your pattern.


Good suggestion.  I've been thinking that there's like to be a need for 
a generic Backend base class too so that would work well from a naming 
convention perspective.


Regards,

Anthony Liguori



Kevin