From: "KONRAD Frédéric" <fred.konrad@greensocs.com>
To: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
"Anthony Liguori" <aliguori@us.ibm.com>,
"Evgeny Voevodin" <e.voevodin@samsung.com>,
mark.burton@greensocs.com, qemu-devel@nongnu.org,
"Andreas Färber" <afaerber@suse.de>
Subject: Re: [Qemu-devel] [RFC PATCH 1/3] virtio-bus : Introduce VirtioBus.
Date: Tue, 20 Nov 2012 15:30:35 +0100 [thread overview]
Message-ID: <50AB940B.306@greensocs.com> (raw)
In-Reply-To: <20121120151201.3886aeaf@BR9GNB5Z>
On 20/11/2012 15:12, Cornelia Huck wrote:
> On Mon, 19 Nov 2012 17:33:01 +0000
> Peter Maydell <peter.maydell@linaro.org> wrote:
>
>> On 16 November 2012 15:35, <fred.konrad@greensocs.com> wrote:
>>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>> You forgot to CC enough people...
>>
>>> This patch create a new VirtioBus, which can be added to Virtio transports like
>>> virtio-pci, virtio-mmio,...
>>>
>>> One VirtIODevice can be connected to this device, like virtio-blk in the 3rd
>>> patch.
>>>
>>> The VirtioBus shares through a VirtioBusInfo structure :
>>>
>>> * two callbacks with the transport : init_cb and exit_cb, which must be
>>> called by the VirtIODevice, after the initialization and before the
>>> destruction, to put the right PCI IDs and/or stop the event fd.
> Can we specify the general purpose of the {init,exit}_cb a bit better?
> Is it analogous to any of the functions performed by the transport
> busses today?
For example, look at the function static int
virtio_blk_init_pci(PCIDevice *pci_dev) in virtio-pci.c,
it creates the VirtIODevice and then call virtio_init_pci(proxy, vdev);
It is what I tryed to reproduce, and abstract it from the new device.
eg : for the new virtio-blk I add, in the function static int
virtio_blk_qdev_init(DeviceState *qdev) in virtio-blk.c :
it creates the VirtIODevice, create the virtiobus and call the
virtio_bus_init_cb(bus, vdev)
which call the virtio_init_pci callback when virtio-pci bridge is used.
it is the same thing for the exit.
Is it making sense ?
>
>>> * a VirtIOBindings structure.
>>>
>>> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
>>> ---
>>> hw/Makefile.objs | 1 +
>>> hw/virtio-bus.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> hw/virtio-bus.h | 49 ++++++++++++++++++++++++
>>> 3 files changed, 161 insertions(+)
>>> create mode 100644 hw/virtio-bus.c
>>> create mode 100644 hw/virtio-bus.h
>>>
>>> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
>>> index af4ab0c..1b25d77 100644
>>> --- a/hw/Makefile.objs
>>> +++ b/hw/Makefile.objs
>>> @@ -1,6 +1,7 @@
>>> common-obj-y = usb/ ide/
>>> common-obj-y += loader.o
>>> common-obj-$(CONFIG_VIRTIO) += virtio-console.o
>>> +common-obj-$(CONFIG_VIRTIO) += virtio-bus.o
>>> common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
>>> common-obj-y += fw_cfg.o
>>> common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o
>>> diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
>>> new file mode 100644
>>> index 0000000..b2e7e9c
>>> --- /dev/null
>>> +++ b/hw/virtio-bus.c
>>> @@ -0,0 +1,111 @@
>>> +/*
>>> + * VirtioBus
>>> + *
>>> + * Copyright (C) 2012 : GreenSocs Ltd
>>> + * http://www.greensocs.com/ , email: info@greensocs.com
>>> + *
>>> + * Developed by :
>>> + * Frederic Konrad <fred.konrad@greensocs.com>
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2. See
>>> + * the COPYING file in the top-level directory.
>> Unless you copied this code from an existing v2-only file, preferred
>> license for new code is v2-or-any-later-version.
>>
>>> + */
>>> +
>>> +#include "hw.h"
>>> +#include "qemu-error.h"
>>> +#include "qdev.h"
>>> +#include "virtio-bus.h"
>>> +#include "virtio.h"
>>> +
>>> +#define DEBUG_VIRTIO_BUS
>>> +
>>> +#ifdef DEBUG_VIRTIO_BUS
>>> +
>>> +#define DPRINTF(fmt, ...) \
>>> +do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0)
>>> +#else
>>> +#define DPRINTF(fmt, ...) do {} while (0)
>>> +#endif
>>> +
>>> +static char *virtio_bus_get_fw_dev_path(DeviceState *dev);
>> Is this function necessary? I think your implementation
>> is doing the same as the default.
>>
>>> +static void virtio_bus_class_init(ObjectClass *klass, void *data)
>>> +{
>>> + BusClass *k = BUS_CLASS(klass);
>>> + k->get_fw_dev_path = virtio_bus_get_fw_dev_path;
>>> +}
>>> +
>>> +static const TypeInfo virtio_bus_info = {
>>> + .name = TYPE_VIRTIO_BUS,
>>> + .parent = TYPE_BUS,
>>> + .instance_size = sizeof(VirtioBus),
>>> + .class_init = virtio_bus_class_init,
>>> +};
>>> +
>>> +/* VirtioBus */
>>> +
>>> +static int next_virtio_bus;
>>> +
>>> +/* Create a virtio bus, and attach to transport. */
>>> +void virtio_bus_new(VirtioBus *bus, DeviceState *host,
>>> + const VirtioBusInfo *info)
>>> +{
>>> + /*
>>> + * Setting name to NULL return always "virtio.0"
>>> + * as bus name in info qtree.
>>> + */
>>> + char *bus_name = g_strdup_printf("%s.%d", BUS_NAME, next_virtio_bus);
>>> + qbus_create_inplace(&bus->qbus, TYPE_VIRTIO_BUS, host, bus_name);
>>> + bus->busnr = next_virtio_bus++;
>> This looks suspicious to me -- is keeping a count of the global
>> bus number really the right way to do this?
> If we want an unique number, we need to track usage of numbers, else we
> end up with duplicates on wraparound.
I put that because the number was all identical in "info qtree", is it
the right thing to do ?
>>> + bus->info = info;
>>> + /* no hotplug for the moment ? */
>>> + bus->qbus.allow_hotplug = 0;
>> Correct -- we don't need to hotplug the virtio backend.
>>
>>> + bus->bus_in_use = false;
>>> + DPRINTF("bus %s created\n", bus_name);
>>> +}
>>> +
>>> +/* Bind the VirtIODevice to the VirtioBus. */
>>> +void virtio_bus_bind_device(VirtioBus *bus)
>>> +{
>>> + assert(bus != NULL);
>>> + assert(bus->vdev != NULL);
>>> + virtio_bind_device(bus->vdev, &(bus->info->virtio_bindings),
>>> + bus->qbus.parent);
>> This looks wrong -- virtio_bind_device() is part of the
>> old-style transport API.
>>
>>> +}
>>> +
>>> +/* This must be called to when the VirtIODevice init */
>>> +int virtio_bus_init_cb(VirtioBus *bus, VirtIODevice *vdev)
>>> +{
>>> + if (bus->bus_in_use == true) {
>>> + error_report("%s in use.\n", bus->qbus.name);
>>> + return -1;
>>> + }
>>> + assert(bus->info->init_cb != NULL);
>>> + /* keep the VirtIODevice in the VirtioBus */
>>> + bus->vdev = vdev;
>> This shouldn't be happening here, it should happen as
>> part of plugging the device into the bus.
>>
>>> + bus->info->init_cb(bus->qbus.parent);
>>> +
>>> + bus->bus_in_use = true;
>>> + return 0;
>>> +}
>>> +
>>> +/* This must be called when the VirtIODevice exit */
>>> +void virtio_bus_exit_cb(VirtioBus *bus)
>>> +{
>>> + assert(bus->info->exit_cb != NULL);
>>> + bus->info->exit_cb(bus->qbus.parent);
>>> + bus->bus_in_use = false;
>>> +}
>> These shouldn't be necessary -- the VirtioDevice should
>> have a pointer to the VirtioBus and can just invoke the
>> init/exit callbacks directly.
>>
>>> +
>>> +static char *virtio_bus_get_fw_dev_path(DeviceState *dev)
>>> +{
>>> + return g_strdup_printf("%s", qdev_fw_name(dev));
>>> +}
>>> +
>>> +
>>> +static void virtio_register_types(void)
>>> +{
>>> + type_register_static(&virtio_bus_info);
>>> +}
>>> +
>>> +type_init(virtio_register_types)
>>> diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
>>> new file mode 100644
>>> index 0000000..6ea5035
>>> --- /dev/null
>>> +++ b/hw/virtio-bus.h
>>> @@ -0,0 +1,49 @@
>>> +/*
>>> + * VirtioBus
>>> + *
>>> + * Copyright (C) 2012 : GreenSocs Ltd
>>> + * http://www.greensocs.com/ , email: info@greensocs.com
>>> + *
>>> + * Developed by :
>>> + * Frederic Konrad <fred.konrad@greensocs.com>
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2. See
>>> + * the COPYING file in the top-level directory.
>>> + */
>>> +
>>> +#ifndef _VIRTIO_BUS_H_
>>> +#define _VIRTIO_BUS_H_
>> Leading underscores are reserved by the C standard. VIRTIO_BUS_H will
>> do fine.
>>
>>> +
>>> +#include "qdev.h"
>>> +#include "sysemu.h"
>>> +#include "virtio.h"
>>> +
>>> +#define TYPE_VIRTIO_BUS "VIRTIO"
>> Type names are generally "virtio-bus" by convention.
>>
>>> +#define BUS_NAME "virtio"
>> I don't think you want this.
>>
>>
>>> +typedef struct VirtioBus VirtioBus;
>>> +typedef struct VirtioBusInfo VirtioBusInfo;
>>> +
>>> +struct VirtioBusInfo {
>>> + void (*init_cb)(DeviceState *dev);
>>> + void (*exit_cb)(DeviceState *dev);
>>> + VirtIOBindings virtio_bindings;
>> This doesn't look right -- VirtIOBindings is the
>> old-style way for the transport to specify a bunch
>> of function pointers for its specific implementation.
>> Those function pointers should probably just be in
>> the VirtioBus struct.
>>
>>> +};
>> I was just talking to Anthony on IRC and he said SCSIBusInfo
>> is really kind of a historical accident. So we can just fold
>> this struct into VirtioBus. Sorry for misleading you earlier.
>>
>>> +struct VirtioBus {
>>> + BusState qbus;
>>> + int busnr;
>> Why does the bus need to know what number it is?
>>
>>> + bool bus_in_use;
>>> + uint16_t pci_device_id;
>>> + uint16_t pci_class;
>> This shouldn't be here -- VirtioBus should be transport
>> independent, so no PCI related info.
> Agreed - this should be a property of the bridge device.
Yes, So I must add the virtiodevice identifier and put a switch case in
the transport to set the right PCI IDs?
In that case, the transport won't be device independent.
>>> + VirtIODevice *vdev;
>> This could use a comment saying that we only ever have one
>> child device on the bus.
>>
>> + const VirtioBusInfo *info;
>> +};
>> +
>> +void virtio_bus_new(VirtioBus *bus, DeviceState *host,
>> + const VirtioBusInfo *info);
>> +void virtio_bus_bind_device(VirtioBus *bus);
>> +int virtio_bus_init_cb(VirtioBus *bus, VirtIODevice *dev);
>> +void virtio_bus_exit_cb(VirtioBus *bus);
>> +
>> +#endif
>> --
>> 1.7.11.7
>> -- PMM
>>
next prev parent reply other threads:[~2012-11-20 14:31 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-16 15:35 [Qemu-devel] [RFC PATCH 0/3] Virtio refactoring fred.konrad
2012-11-16 15:35 ` [Qemu-devel] [RFC PATCH 1/3] virtio-bus : Introduce VirtioBus fred.konrad
2012-11-19 17:33 ` Peter Maydell
2012-11-20 14:12 ` Cornelia Huck
2012-11-20 14:30 ` KONRAD Frédéric [this message]
2012-11-20 16:15 ` Cornelia Huck
2012-11-20 16:45 ` KONRAD Frédéric
2012-11-20 17:27 ` Cornelia Huck
2012-11-21 9:31 ` KONRAD Frédéric
2012-11-21 13:04 ` Andreas Färber
2012-11-21 14:05 ` KONRAD Frédéric
2012-11-21 14:13 ` Andreas Färber
2012-11-21 14:18 ` KONRAD Frédéric
2012-11-16 15:35 ` [Qemu-devel] [RFC PATCH 2/3] virtio-pci : Add a virtio-bus interface fred.konrad
2012-11-16 15:35 ` [Qemu-devel] [RFC PATCH 3/3] virtio-blk : add the virtio-blk device fred.konrad
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50AB940B.306@greensocs.com \
--to=fred.konrad@greensocs.com \
--cc=afaerber@suse.de \
--cc=aliguori@us.ibm.com \
--cc=cornelia.huck@de.ibm.com \
--cc=e.voevodin@samsung.com \
--cc=mark.burton@greensocs.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).