[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3 03/12] vfio-user: define vfio-user-server object
From: |
Jag Raman |
Subject: |
Re: [PATCH v3 03/12] vfio-user: define vfio-user-server object |
Date: |
Fri, 29 Oct 2021 14:42:49 +0000 |
> On Oct 27, 2021, at 11:40 AM, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>
> On Mon, Oct 11, 2021 at 01:31:08AM -0400, Jagannathan Raman wrote:
>> diff --git a/qapi/qom.json b/qapi/qom.json
>> index 0222bb4506..97de79cc36 100644
>> --- a/qapi/qom.json
>> +++ b/qapi/qom.json
>> @@ -705,6 +705,20 @@
>> { 'struct': 'RemoteObjectProperties',
>> 'data': { 'fd': 'str', 'devid': 'str' } }
>>
>> +##
>> +# @VfioUserServerProperties:
>> +#
>> +# Properties for vfio-user-server objects.
>> +#
>> +# @socket: socket to be used by the libvfiouser library
>> +#
>> +# @device: the id of the device to be emulated at the server
>> +#
>> +# Since: 6.0
>
> 6.2
>
>> +##
>> +{ 'struct': 'VfioUserServerProperties',
>> + 'data': { 'socket': 'SocketAddress', 'device': 'str' } }
>> +
>> ##
>> # @RngProperties:
>> #
>> @@ -830,7 +844,8 @@
>> 'tls-creds-psk',
>> 'tls-creds-x509',
>> 'tls-cipher-suites',
>> - 'x-remote-object'
>> + 'x-remote-object',
>> + 'vfio-user-server'
>
> Should it have the experimental prefix ('x-') or is the QAPI interface
> stable? I think some things to think about are whether a single process
> can host multiple device servers, whether hotplug is possible, etc. If
> the interface is stable then it must be able to accomodate future
> features (at least ones we can anticipate right now :)).
We did test out hotplug support.
We’ll get back to you on the multiple device servers scenario.
>
>> ] }
>>
>> ##
>> @@ -887,7 +902,8 @@
>> 'tls-creds-psk': 'TlsCredsPskProperties',
>> 'tls-creds-x509': 'TlsCredsX509Properties',
>> 'tls-cipher-suites': 'TlsCredsProperties',
>> - 'x-remote-object': 'RemoteObjectProperties'
>> + 'x-remote-object': 'RemoteObjectProperties',
>> + 'vfio-user-server': 'VfioUserServerProperties'
>> } }
>>
>> ##
>> diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c
>> new file mode 100644
>> index 0000000000..c2a300f0ff
>> --- /dev/null
>> +++ b/hw/remote/vfio-user-obj.c
>> @@ -0,0 +1,173 @@
>> +/**
>> + * QEMU vfio-user-server server object
>> + *
>> + * Copyright © 2021 Oracle and/or its affiliates.
>> + *
>> + * This work is licensed under the terms of the GNU GPL-v2, version 2 or
>> later.
>> + *
>> + * See the COPYING file in the top-level directory.
>> + *
>> + */
>> +
>> +/**
>> + * Usage: add options:
>> + * -machine x-remote
>> + * -device <PCI-device>,id=<pci-dev-id>
>> + * -object vfio-user-server,id=<id>,type=unix,path=<socket-path>,
>
> I expected socket.type= and socket.path= based on the QAPI schema. Is
> this command-line example correct?
When I tried the “socket.path” approach, QEMU was not able to parse the
arguments. So I had to break it down to a series of individual members.
If “socket.path” is the expected way, I’ll see why the parser is not working
as expected.
>
>> + * device=<pci-dev-id>
>> + *
>> + * Note that vfio-user-server object must be used with x-remote machine
>> only.
>> + * This server could only support PCI devices for now.
>> + *
>> + * type - SocketAddress type - presently "unix" alone is supported. Required
>> + * option
>> + *
>> + * path - named unix socket, it will be created by the server. It is
>> + * a required option
>> + *
>> + * device - id of a device on the server, a required option. PCI devices
>> + * alone are supported presently.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu-common.h"
>> +
>> +#include "qom/object.h"
>> +#include "qom/object_interfaces.h"
>> +#include "qemu/error-report.h"
>> +#include "trace.h"
>> +#include "sysemu/runstate.h"
>> +#include "hw/boards.h"
>> +#include "hw/remote/machine.h"
>> +#include "qapi/error.h"
>> +#include "qapi/qapi-visit-sockets.h"
>> +
>> +#define TYPE_VFU_OBJECT "vfio-user-server"
>> +OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT)
>> +
>> +struct VfuObjectClass {
>> + ObjectClass parent_class;
>> +
>> + unsigned int nr_devs;
>> +
>> + /* Maximum number of devices the server could support */
>> + unsigned int max_devs;
>> +};
>> +
>> +struct VfuObject {
>> + /* private */
>> + Object parent;
>> +
>> + SocketAddress *socket;
>> +
>> + char *device;
>> +};
>> +
>> +static void vfu_object_set_socket(Object *obj, Visitor *v, const char *name,
>> + void *opaque, Error **errp)
>> +{
>> + VfuObject *o = VFU_OBJECT(obj);
>> +
>> + g_free(o->socket);
>
> qapi_free_SocketAddress(o->socket)?
OK, will use that.
Didn’t know the visitors also define a function for free’ing. Thank you!
>
>> +
>> + o->socket = NULL;
>> +
>> + visit_type_SocketAddress(v, name, &o->socket, errp);
>> +
>> + if (o->socket->type != SOCKET_ADDRESS_TYPE_UNIX) {
>> + error_setg(&error_abort, "vfu: Unsupported socket type - %s",
>> + o->socket->u.q_unix.path);
>
> o->socket must be freed and set it to NULL again, otherwise setting the
> property appears to fail but the SocketAddress actually retains the
> invalid value.
OK, got it.
>
>> + return;
>> + }
>> +
>> + trace_vfu_prop("socket", o->socket->u.q_unix.path);
>> +}
>> +
>> +static void vfu_object_set_device(Object *obj, const char *str, Error
>> **errp)
>> +{
>> + VfuObject *o = VFU_OBJECT(obj);
>> +
>> + g_free(o->device);
>> +
>> + o->device = g_strdup(str);
>> +
>> + trace_vfu_prop("device", str);
>> +}
>> +
>> +static void vfu_object_init(Object *obj)
>> +{
>> + VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj);
>> +
>> + if (!object_dynamic_cast(OBJECT(current_machine), TYPE_REMOTE_MACHINE))
>> {
>> + error_setg(&error_abort, "vfu: %s only compatible with %s machine",
>> + TYPE_VFU_OBJECT, TYPE_REMOTE_MACHINE);
>> + return;
>> + }
>> +
>> + if (k->nr_devs >= k->max_devs) {
>> + error_setg(&error_abort,
>> + "Reached maximum number of vfio-user-server devices: %u",
>> + k->max_devs);
>> + return;
>> + }
>> +
>> + k->nr_devs++;
>> +}
>> +
>> +static void vfu_object_finalize(Object *obj)
>> +{
>> + VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj);
>> + VfuObject *o = VFU_OBJECT(obj);
>> +
>> + k->nr_devs--;
>> +
>> + g_free(o->socket);
>
> qapi_free_SocketAddress(o->socket)?
>
>> +
>> + g_free(o->device);
>> +
>> + if (k->nr_devs == 0) {
>> + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>> + }
>
> This won't work for all use cases. The user may wish to create/delete
> vhost-user servers at runtime without terminating the process when there
> are none left. An boolean option can be added in the future to control
> this behavior, so it's okay to leave this as is.
Thank you, we’ll make a note of this. I’ll add a TODO comment here to ensure we
don’t lose this thought.
--
Jag
- [PATCH v3 00/12] vfio-user server in QEMU, Jagannathan Raman, 2021/10/11
- [PATCH v3 01/12] configure, meson: override C compiler for cmake, Jagannathan Raman, 2021/10/11
- [PATCH v3 02/12] vfio-user: build library, Jagannathan Raman, 2021/10/11
- [PATCH v3 03/12] vfio-user: define vfio-user-server object, Jagannathan Raman, 2021/10/11
- [PATCH v3 04/12] vfio-user: instantiate vfio-user context, Jagannathan Raman, 2021/10/11
- [PATCH v3 05/12] vfio-user: find and init PCI device, Jagannathan Raman, 2021/10/11
- [PATCH v3 07/12] vfio-user: handle PCI config space accesses, Jagannathan Raman, 2021/10/11
- [PATCH v3 08/12] vfio-user: handle DMA mappings, Jagannathan Raman, 2021/10/11
- [PATCH v3 06/12] vfio-user: run vfio-user context, Jagannathan Raman, 2021/10/11