All of lore.kernel.org
 help / color / mirror / Atom feed
From: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
To: David Hildenbrand <david@redhat.com>
Cc: qemu-devel@nongnu.org, Pankaj Gupta <pagupta@redhat.com>,
	Collin Walling <walling@linux.ibm.com>,
	Eduardo Habkost <ehabkost@redhat.com>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Cornelia Huck <cohuck@redhat.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Halil Pasic <pasic@linux.ibm.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	qemu-s390x@nongnu.org, qemu-ppc@nongnu.org,
	Marcel Apfelbaum <marcel.apfelbaum@gmail.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>,
	David Gibson <david@gibson.dropbear.id.au>,
	Eric Blake <eblake@redhat.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [Qemu-ppc] [PATCH RFC 04/10] virtio-pmem: Prototype
Date: Wed, 16 Jan 2019 17:20:25 -0200	[thread overview]
Message-ID: <20190116192025.GB27437@kermit-br-ibm-com> (raw)
In-Reply-To: <20190116113523.9213-5-david@redhat.com>

Hi, David.

On Wed, Jan 16, 2019 at 12:35:17PM +0100, David Hildenbrand wrote:
> From: Pankaj Gupta <pagupta@redhat.com>
>
> This is the current protoype of virtio-pmem. Support will require
> machine changes for the architectures that will support it, so it will
> not yet be compiled.
>
> TODO:
> - Use separate struct for tracking requests internally
> - Move request/response structs to linux headers
> - Factor out linux header sync
> - Drop debug printfs
>
> Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
> [ MemoryDevice/MemoryRegion changes, cleanups, addr property "memaddr",
>   split up patches, unplug handler ]
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  hw/virtio/Makefile.objs                     |   2 +
>  hw/virtio/virtio-pmem.c                     | 189 ++++++++++++++++++++
>  include/hw/virtio/virtio-pmem.h             |  54 ++++++
>  include/standard-headers/linux/virtio_ids.h |   1 +
>  qapi/misc.json                              |  26 ++-
>  5 files changed, 271 insertions(+), 1 deletion(-)
>  create mode 100644 hw/virtio/virtio-pmem.c
>  create mode 100644 include/hw/virtio/virtio-pmem.h
>
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 1b2799cfd8..5463c682f7 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -9,6 +9,8 @@ obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
>  obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
>  obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += virtio-crypto-pci.o
>
> +obj-$(CONFIG_VIRTIO_PMEM) += virtio-pmem.o
> +
>  obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
>  obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
>  endif
> diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
> new file mode 100644
> index 0000000000..6fb78acf87
> --- /dev/null
> +++ b/hw/virtio/virtio-pmem.c
> @@ -0,0 +1,189 @@
> +/*
> + * Virtio PMEM device
> + *
> + * Copyright (C) 2018 Red Hat, Inc.
> + *
> + * Authors:
> + *  Pankaj Gupta <pagupta@redhat.com>
> + *  David Hildenbrand <david@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qemu-common.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/virtio-pmem.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "standard-headers/linux/virtio_ids.h"
> +#include "block/aio.h"
> +#include "block/thread-pool.h"
> +
> +typedef struct VirtIOPMEMresp {
> +    int ret;
> +} VirtIOPMEMResp;
> +
> +typedef struct VirtIODeviceRequest {
> +    VirtQueueElement elem;
> +    int fd;
> +    VirtIOPMEM *pmem;
> +    VirtIOPMEMResp resp;
> +} VirtIODeviceRequest;
> +
> +static int worker_cb(void *opaque)
> +{
> +    VirtIODeviceRequest *req = opaque;
> +    int err = 0;
> +
> +    printf("\n performing flush ...");
> +    /* flush raw backing image */
> +    err = fsync(req->fd);
> +    printf("\n performed flush ...:errcode::%d", err);
> +    if (err != 0) {
> +        err = EIO;
> +    }
> +    req->resp.ret = err;
> +
> +    return 0;
> +}
> +
> +static void done_cb(void *opaque, int ret)
> +{
> +    VirtIODeviceRequest *req = opaque;
> +    int len = iov_from_buf(req->elem.in_sg, req->elem.in_num, 0,
> +                              &req->resp, sizeof(VirtIOPMEMResp));
> +
> +    /* Callbacks are serialized, so no need to use atomic ops. */
> +    virtqueue_push(req->pmem->rq_vq, &req->elem, len);
> +    virtio_notify((VirtIODevice *)req->pmem, req->pmem->rq_vq);
> +    g_free(req);
> +}
> +
> +static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq)
> +{
> +    VirtIODeviceRequest *req;
> +    VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
> +    HostMemoryBackend *backend = MEMORY_BACKEND(pmem->memdev);
> +    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
> +
> +    req = virtqueue_pop(vq, sizeof(VirtIODeviceRequest));
> +    if (!req) {
> +        virtio_error(vdev, "virtio-pmem missing request data");
> +        return;
> +    }
> +
> +    if (req->elem.out_num < 1 || req->elem.in_num < 1) {
> +        virtio_error(vdev, "virtio-pmem request not proper");
> +        g_free(req);
> +        return;
> +    }
> +    req->fd = memory_region_get_fd(&backend->mr);
> +    req->pmem = pmem;
> +    thread_pool_submit_aio(pool, worker_cb, req, done_cb, req);
> +}
> +
> +static void virtio_pmem_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> +    VirtIOPMEM *pmem = VIRTIO_PMEM(vdev);
> +    struct virtio_pmem_config *pmemcfg = (struct virtio_pmem_config *) config;
> +
> +    virtio_stq_p(vdev, &pmemcfg->start, pmem->start);
> +    virtio_stq_p(vdev, &pmemcfg->size, memory_region_size(&pmem->memdev->mr));
> +}
> +
> +static uint64_t virtio_pmem_get_features(VirtIODevice *vdev, uint64_t features,
> +                                        Error **errp)
> +{
> +    return features;
> +}
> +
> +static void virtio_pmem_realize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
> +
> +    if (!pmem->memdev) {
> +        error_setg(errp, "virtio-pmem memdev not set");
> +        return;
> +    } else if (host_memory_backend_is_mapped(pmem->memdev)) {
> +        char *path = object_get_canonical_path_component(OBJECT(pmem->memdev));
> +        error_setg(errp, "can't use already busy memdev: %s", path);
> +        g_free(path);
> +        return;
> +    }

Perhaps splitting this if-else block could improve readability:

    if (!pmem->memdev) {
        error_setg(...);
	return;
    }

    if (host_memory_backend_is_mapped(pmem->memdev)) {
       /* do stuff */
       return;
    }

    /* do other stuffs */

> +
> +    host_memory_backend_set_mapped(pmem->memdev, true);
> +    virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM,
> +                                          sizeof(struct virtio_pmem_config));

I'm not quite sure what's the QEMU style for indenting this.  There
are, for example, calls to warn_report() in other source files that
are indented at the left side after the opening parenthesis.

Perhaps indenting it like this is preferable?

    virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM,
                sizeof(struct virtio_pmem_config));

> +    pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
> +}
> +
> +static void virtio_pmem_unrealize(DeviceState *dev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> +    VirtIOPMEM *pmem = VIRTIO_PMEM(dev);
> +
> +    host_memory_backend_set_mapped(pmem->memdev, false);
> +    pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush);
> +    virtio_cleanup(vdev);
> +}
> +
> +static void virtio_pmem_fill_device_info(const VirtIOPMEM *pmem,
> +                                         VirtioPMEMDeviceInfo *vi)
> +{
> +    vi->memaddr = pmem->start;
> +    vi->size = pmem->memdev ? memory_region_size(&pmem->memdev->mr) : 0;
> +    vi->memdev = object_get_canonical_path(OBJECT(pmem->memdev));
> +}
> +
> +static MemoryRegion *virtio_pmem_get_memory_region(VirtIOPMEM *pmem,
> +                                                   Error **errp)
> +{
> +    if (!pmem->memdev) {
> +        error_setg(errp, "'%s' property must be set", VIRTIO_PMEM_MEMDEV_PROP);
> +        return NULL;
> +    }
> +
> +    return &pmem->memdev->mr;
> +}
> +
> +static Property virtio_pmem_properties[] = {
> +    DEFINE_PROP_UINT64(VIRTIO_PMEM_ADDR_PROP, VirtIOPMEM, start, 0),
> +    DEFINE_PROP_LINK(VIRTIO_PMEM_MEMDEV_PROP, VirtIOPMEM, memdev,
> +                     TYPE_MEMORY_BACKEND, HostMemoryBackend *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void virtio_pmem_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +    VirtIOPMEMClass *vpc = VIRTIO_PMEM_CLASS(klass);
> +
> +    dc->props = virtio_pmem_properties;
> +
> +    vdc->realize = virtio_pmem_realize;
> +    vdc->unrealize = virtio_pmem_unrealize;
> +    vdc->get_config = virtio_pmem_get_config;
> +    vdc->get_features = virtio_pmem_get_features;
> +
> +    vpc->fill_device_info = virtio_pmem_fill_device_info;
> +    vpc->get_memory_region = virtio_pmem_get_memory_region;
> +}
> +
> +static TypeInfo virtio_pmem_info = {
> +    .name          = TYPE_VIRTIO_PMEM,
> +    .parent        = TYPE_VIRTIO_DEVICE,
> +    .class_size    = sizeof(VirtIOPMEMClass),
> +    .class_init    = virtio_pmem_class_init,
> +    .instance_size = sizeof(VirtIOPMEM),
> +};
> +
> +static void virtio_register_types(void)
> +{
> +    type_register_static(&virtio_pmem_info);
> +}
> +
> +type_init(virtio_register_types)
> diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pmem.h
> new file mode 100644
> index 0000000000..85cee3ef39
> --- /dev/null
> +++ b/include/hw/virtio/virtio-pmem.h
> @@ -0,0 +1,54 @@
> +/*
> + * Virtio pmem device

What if "pmem" was in upper case to match the header in virtio-pmem.c?

> + *
> + * Copyright Red Hat, Inc. 2018

This is slightly different from what is in virtio-pmem.c header.
Perhaps "(C)" is missing here.

> + *
> + * Authors:
> + *  Pankaj Gupta <pagupta@redhat.com>
> + *  David Hildenbrand <david@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_VIRTIO_PMEM_H
> +#define HW_VIRTIO_PMEM_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "sysemu/hostmem.h"
> +
> +#define TYPE_VIRTIO_PMEM "virtio-pmem"
> +
> +#define VIRTIO_PMEM(obj) \
> +        OBJECT_CHECK(VirtIOPMEM, (obj), TYPE_VIRTIO_PMEM)

This indentation is slightly different from the other two macros
below.

> +#define VIRTIO_PMEM_CLASS(oc) \
> +    OBJECT_CLASS_CHECK(VirtIOPMEMClass, (oc), TYPE_VIRTIO_PMEM)
> +#define VIRTIO_PMEM_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(VirtIOPMEMClass, (obj), TYPE_VIRTIO_PMEM)
> +
> +#define VIRTIO_PMEM_ADDR_PROP "memaddr"
> +#define VIRTIO_PMEM_MEMDEV_PROP "memdev"
> +
> +typedef struct VirtIOPMEM {
> +    VirtIODevice parent_obj;
> +
> +    VirtQueue *rq_vq;
> +    uint64_t start;
> +    HostMemoryBackend *memdev;
> +} VirtIOPMEM;
> +
> +typedef struct VirtIOPMEMClass {
> +    /* private */
> +    VirtIODevice parent;
> +
> +    /* public */
> +    void (*fill_device_info)(const VirtIOPMEM *pmem, VirtioPMEMDeviceInfo *vi);
> +    MemoryRegion *(*get_memory_region)(VirtIOPMEM *pmem, Error **errp);
> +} VirtIOPMEMClass;
> +
> +struct virtio_pmem_config {
> +    uint64_t start;
> +    uint64_t size;
> +};
> +
> +#endif
> diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
> index 6d5c3b2d4f..346389565a 100644
> --- a/include/standard-headers/linux/virtio_ids.h
> +++ b/include/standard-headers/linux/virtio_ids.h
> @@ -43,5 +43,6 @@
>  #define VIRTIO_ID_INPUT        18 /* virtio input */
>  #define VIRTIO_ID_VSOCK        19 /* virtio vsock transport */
>  #define VIRTIO_ID_CRYPTO       20 /* virtio crypto */
> +#define VIRTIO_ID_PMEM         25 /* virtio pmem */
>
>  #endif /* _LINUX_VIRTIO_IDS_H */
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 24d20a880a..8ae709636d 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -2949,6 +2949,29 @@
>            }
>  }
>
> +##
> +# @VirtioPMEMDeviceInfo:
> +#
> +# VirtioPMEM state information
> +#
> +# @id: device's ID
> +#
> +# @memaddr: physical address in memory, where device is mapped
> +#
> +# @size: size of memory that the device provides
> +#
> +# @memdev: memory backend linked with device
> +#
> +# Since: 3.1
> +##
> +{ 'struct': 'VirtioPMEMDeviceInfo',
> +  'data': { '*id': 'str',
> +            'memaddr': 'size',
> +            'size': 'size',
> +            'memdev': 'str'
> +          }
> +}
> +
>  ##
>  # @MemoryDeviceInfo:
>  #
> @@ -2958,7 +2981,8 @@
>  ##
>  { 'union': 'MemoryDeviceInfo',
>    'data': { 'dimm': 'PCDIMMDeviceInfo',
> -            'nvdimm': 'PCDIMMDeviceInfo'
> +            'nvdimm': 'PCDIMMDeviceInfo',
> +            'virtio-pmem': 'VirtioPMEMDeviceInfo'
>            }
>  }
>
> --
> 2.17.2
>
>

--
Murilo

  parent reply	other threads:[~2019-01-16 19:20 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-16 11:35 [Qemu-devel] [PATCH RFC 00/10] qdev: Hotplug handler chaining + virtio-pmem David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 01/10] qdev: Let the hotplug_handler_unplug() caller delete the device David Hildenbrand
2019-01-18  9:58   ` Igor Mammedov
2019-01-18 12:41     ` David Hildenbrand
2019-01-18 15:05       ` Igor Mammedov
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 02/10] qdev: Let machine hotplug handler to override bus hotplug handler David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 03/10] qdev: Provide qdev_get_bus_hotplug_handler() David Hildenbrand
2019-01-16 18:41   ` [Qemu-devel] [Qemu-ppc] " Murilo Opsfelder Araujo
2019-01-17 12:16     ` David Hildenbrand
2019-01-18 10:07   ` [Qemu-devel] " Igor Mammedov
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 04/10] virtio-pmem: Prototype David Hildenbrand
2019-01-16 14:46   ` Eric Blake
2019-01-17 12:18     ` David Hildenbrand
2019-01-21 11:52     ` David Hildenbrand
2019-01-21 12:02       ` Dr. David Alan Gilbert
2019-01-21 13:31         ` David Hildenbrand
2019-01-21 17:15           ` Eric Blake
2019-01-16 19:20   ` Murilo Opsfelder Araujo [this message]
2019-01-17 12:23     ` [Qemu-devel] [Qemu-ppc] " David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 05/10] virtio-pci: Allow to specify additional interfaces for the base type David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 06/10] virtio-pci: Proxy for virtio-pmem David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 07/10] hmp: Handle virtio-pmem when printing memory device infos David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 08/10] numa: Handle virtio-pmem in NUMA stats David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 09/10] pc: Support for PCI based memory devices David Hildenbrand
2019-01-18 10:20   ` Igor Mammedov
2019-01-18 12:53     ` David Hildenbrand
2019-01-18 14:37       ` Igor Mammedov
2019-01-21 10:31         ` David Hildenbrand
2019-01-16 11:35 ` [Qemu-devel] [PATCH RFC 10/10] pc: Enable support for virtio-pmem David Hildenbrand
2019-01-16 11:41 ` [Qemu-devel] [PATCH RFC 00/10] qdev: Hotplug handler chaining + virtio-pmem David Hildenbrand

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=20190116192025.GB27437@kermit-br-ibm-com \
    --to=muriloo@linux.ibm.com \
    --cc=armbru@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=david@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mst@redhat.com \
    --cc=pagupta@redhat.com \
    --cc=pasic@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=walling@linux.ibm.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.