From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:40467) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm3XN-0004jn-MJ for qemu-devel@nongnu.org; Wed, 27 Jul 2011 08:48:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qm3XM-0004Hk-7H for qemu-devel@nongnu.org; Wed, 27 Jul 2011 08:48:33 -0400 Received: from mail-yi0-f45.google.com ([209.85.218.45]:49943) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm3XL-0004HH-Ua for qemu-devel@nongnu.org; Wed, 27 Jul 2011 08:48:32 -0400 Received: by yia25 with SMTP id 25so1201154yia.4 for ; Wed, 27 Jul 2011 05:48:31 -0700 (PDT) Message-ID: <4E30091C.3070404@codemonkey.ws> Date: Wed, 27 Jul 2011 07:48:28 -0500 From: Anthony Liguori MIME-Version: 1.0 References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> <4E2EBA1E.90006@redhat.com> <4E2EC90E.8090409@codemonkey.ws> <4E2ED0AA.3020101@redhat.com> <4E2EDE86.7020807@codemonkey.ws> <4E2F06C8.30403@redhat.com> <4E2F1448.3040106@codemonkey.ws> <4E2FD28F.2070206@redhat.com> In-Reply-To: <4E2FD28F.2070206@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC][PATCH 0/21] QEMU Object Model List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: Peter Maydell , qemu-devel@nongnu.org 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; > List 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 can have incremental value. The first step of retrofitting is pretty systematic and allows for devices be created and composed through the plug interfaces. I think we could pretty much eliminate machines after this phase which would be a huge win for compatibility. Regards, Anthony Liguori > > Paolo >