From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:59170) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlijI-0000Si-6l for qemu-devel@nongnu.org; Tue, 26 Jul 2011 10:35:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlijG-0005KY-C1 for qemu-devel@nongnu.org; Tue, 26 Jul 2011 10:35:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36753) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlijG-0005KL-2o for qemu-devel@nongnu.org; Tue, 26 Jul 2011 10:35:26 -0400 Message-ID: <4E2ED0AA.3020101@redhat.com> Date: Tue, 26 Jul 2011 16:35:22 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> <4E2EBA1E.90006@redhat.com> <4E2EC90E.8090409@codemonkey.ws> In-Reply-To: <4E2EC90E.8090409@codemonkey.ws> 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: Anthony Liguori Cc: qemu-devel@nongnu.org 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