"Michael S. Tsirkin" <m...@redhat.com> wrote: > On Thu, Dec 03, 2009 at 12:56:57PM +0100, Juan Quintela wrote: >> "Michael S. Tsirkin" <m...@redhat.com> wrote: >> > On Wed, Dec 02, 2009 at 08:03:22PM +0100, Juan Quintela wrote: >> >> "Michael S. Tsirkin" <m...@redhat.com> wrote: >> >> >> >> > I don't understand. >> >> > container_of is just more generic than DO_UPCAST. >> >> > So why *ever* use DO_UPCAST? Let's get rid of it. >> >> .... >> >> >> See how you create a device of size struct_size, but then you access it >> >> with vdev. If vdev is _not_ the 1st element of the struct, you have got >> >> corruption. >> > >> > A cleaner solution IMO would be to have callers allocate the memory >> > and pass VirtIODevice * to virtio_common_init. >> >> Been there, asked for that. Basically qdev + passing initialized memory >> = nono > > It does not have to be initialized.
sorry, already allocated memory. basically -device foo requires that qdev creates foo and then it call foo_init(). You can see in the mail archive that I wanted a qdev_create_here() function, to do exactly what you wanted. It has problems with getting -device working realiablely. >> >> DO_UPCAST() prevent you for having that error. >> > >> > >> > If we want to assert specific structure layout, this >> > should be a compile-time check. There's no >> > reason to do this check every time at a random place where >> > DO_UPCAST is called. >> >> See DO_UPCAST() definition :) >> >> >> It is a compile time check. It just do cpp magic to be sure that things >> are right. DO_UPCAST() == (cast *) with some typechecking. > > Yes, but it gives the error on the wrong place. So it is > only good as long as you do not change the code. No, it gives it in the right place. Where you do a cast from PCIDevice -> FOOState or when you do a cast from VirtioDevice -> VirtIOFooDevice. Really it is a "smarter" cast than just do (VirtioFooDevice *). > In the example you give with virtio_init_common, there's no UPCAST > to document the layout assumption *in the place where assumption is made*. > On the other hand, DO_UPCAST is scattered all over the code > in places which could work fine without any assumptions. > > Let's assume you want to change layout. You find all places > with DO_UPCAST, fix them, and it will compile-but not work. > Let's assume you change all code that makes layout assumptions > to not make them: DO_UPCAST will still be hang around in other > code. Not requiring DO_UPCAST() mean changing how qdev work. If you have counted the Gerd qdev patches over the last months, you will see that it is an almost "infinity" ammount of work. I don't see why you want to change that. In this specific example, DO_UPCAST() is needed. It is required that VirtIODevice is the 1st field of any other structure. I really don't see why you want to change that. Later, Juan.