From: Igor Mammedov <imammedo@redhat.com>
To: Jiajun Chen <chenjiajun8@huawei.com>
Cc: raphael.s.norwitz@gmail.com, zhang.zhanghailiang@huawei.com,
mst@redhat.com, jasowang@redhat.com, qemu-devel@nongnu.org,
xiexiangyou@huawei.com, marcandre.lureau@redhat.com
Subject: Re: [PATCH] vhost-user: add separate memslot counter for vhost-user
Date: Tue, 6 Oct 2020 11:48:01 +0200 [thread overview]
Message-ID: <20201006114801.6833a72d@redhat.com> (raw)
In-Reply-To: <20200928131731.69684-1-chenjiajun8@huawei.com>
On Mon, 28 Sep 2020 21:17:31 +0800
Jiajun Chen <chenjiajun8@huawei.com> wrote:
> Used_memslots is equal to dev->mem->nregions now, it is true for
> vhost kernel, but not for vhost user, which uses the memory regions
> that have file descriptor. In fact, not all of the memory regions
> have file descriptor.
> It is usefully in some scenarios, e.g. used_memslots is 8, and only
> 5 memory slots can be used by vhost user, it is failed to hot plug
> a new memory RAM because vhost_has_free_slot just returned false,
> but we can hot plug it safely in fact.
I had an impression that all guest RAM has to be shared with vhost,
so combination of anon and fd based RAM couldn't work.
Am I wrong?
>
> --
> ChangeList:
> v3:
> -make used_memslots a member of struct vhost_dev instead of a global static value
it's global resource, so why?
>
> v2:
> -eliminating useless used_memslots_exceeded variable and used_memslots_is_exceeded() API
>
> v1:
> -vhost-user: add separate memslot counter for vhost-user
>
> Signed-off-by: Jiajun Chen <chenjiajun8@huawei.com>
> Signed-off-by: Jianjay Zhou <jianjay.zhou@huawei.com>
> ---
> hw/virtio/vhost-backend.c | 12 ++++++++++
> hw/virtio/vhost-user.c | 25 +++++++++++++++++++++
> hw/virtio/vhost.c | 37 +++++++++++++++++++++++--------
> include/hw/virtio/vhost-backend.h | 5 +++++
> include/hw/virtio/vhost.h | 1 +
> net/vhost-user.c | 7 ++++++
> 6 files changed, 78 insertions(+), 9 deletions(-)
>
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 782b1d67d9..7016f23ec5 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -238,6 +238,16 @@ static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev,
> qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL);
> }
>
> +static void vhost_kernel_set_used_memslots(struct vhost_dev *dev)
> +{
> + dev->used_memslots = dev->mem->nregions;
> +}
> +
> +static unsigned int vhost_kernel_get_used_memslots(struct vhost_dev *dev)
> +{
> + return dev->used_memslots;
> +}
> +
> static const VhostOps kernel_ops = {
> .backend_type = VHOST_BACKEND_TYPE_KERNEL,
> .vhost_backend_init = vhost_kernel_init,
> @@ -269,6 +279,8 @@ static const VhostOps kernel_ops = {
> #endif /* CONFIG_VHOST_VSOCK */
> .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
> .vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg,
> + .vhost_set_used_memslots = vhost_kernel_set_used_memslots,
> + .vhost_get_used_memslots = vhost_kernel_get_used_memslots,
> };
> #endif
>
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 31231218dc..5dea64d8a8 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -2354,6 +2354,29 @@ void vhost_user_cleanup(VhostUserState *user)
> user->chr = NULL;
> }
>
> +static void vhost_user_set_used_memslots(struct vhost_dev *dev)
> +{
> + int i;
> + dev->used_memslots = 0;
> +
> + for (i = 0; i < dev->mem->nregions; ++i) {
> + struct vhost_memory_region *reg = dev->mem->regions + i;
> + ram_addr_t offset;
> + MemoryRegion *mr;
> + int fd;
> +
> + mr = vhost_user_get_mr_data(reg->userspace_addr, &offset, &fd);
> + if (mr && fd > 0) {
> + dev->used_memslots++;
> + }
> + }
> +}
> +
> +static unsigned int vhost_user_get_used_memslots(struct vhost_dev *dev)
> +{
> + return dev->used_memslots;
> +}
> +
> const VhostOps user_ops = {
> .backend_type = VHOST_BACKEND_TYPE_USER,
> .vhost_backend_init = vhost_user_backend_init,
> @@ -2387,4 +2410,6 @@ const VhostOps user_ops = {
> .vhost_backend_mem_section_filter = vhost_user_mem_section_filter,
> .vhost_get_inflight_fd = vhost_user_get_inflight_fd,
> .vhost_set_inflight_fd = vhost_user_set_inflight_fd,
> + .vhost_set_used_memslots = vhost_user_set_used_memslots,
> + .vhost_get_used_memslots = vhost_user_get_used_memslots,
> };
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 1a1384e7a6..98b967669b 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -45,20 +45,20 @@
> static struct vhost_log *vhost_log;
> static struct vhost_log *vhost_log_shm;
>
> -static unsigned int used_memslots;
> static QLIST_HEAD(, vhost_dev) vhost_devices =
> QLIST_HEAD_INITIALIZER(vhost_devices);
>
> bool vhost_has_free_slot(void)
> {
> - unsigned int slots_limit = ~0U;
> struct vhost_dev *hdev;
>
> QLIST_FOREACH(hdev, &vhost_devices, entry) {
> - unsigned int r = hdev->vhost_ops->vhost_backend_memslots_limit(hdev);
> - slots_limit = MIN(slots_limit, r);
> + if (hdev->vhost_ops->vhost_get_used_memslots(hdev) >=
> + hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
> + return false;
> + }
> }
> - return slots_limit > used_memslots;
> + return true;
> }
>
> static void vhost_dev_sync_region(struct vhost_dev *dev,
> @@ -502,7 +502,6 @@ static void vhost_commit(MemoryListener *listener)
> dev->n_mem_sections * sizeof dev->mem->regions[0];
> dev->mem = g_realloc(dev->mem, regions_size);
> dev->mem->nregions = dev->n_mem_sections;
> - used_memslots = dev->mem->nregions;
> for (i = 0; i < dev->n_mem_sections; i++) {
> struct vhost_memory_region *cur_vmr = dev->mem->regions + i;
> struct MemoryRegionSection *mrs = dev->mem_sections + i;
> @@ -678,6 +677,7 @@ static void vhost_region_add_section(struct vhost_dev *dev,
> dev->tmp_sections[dev->n_tmp_sections - 1].fv = NULL;
> memory_region_ref(section->mr);
> }
> + dev->vhost_ops->vhost_set_used_memslots(dev);
> }
>
> /* Used for both add and nop callbacks */
> @@ -693,6 +693,17 @@ static void vhost_region_addnop(MemoryListener *listener,
> vhost_region_add_section(dev, section);
> }
>
> +static void vhost_region_del(MemoryListener *listener,
> + MemoryRegionSection *section)
> +{
> + struct vhost_dev *dev = container_of(listener, struct vhost_dev,
> + memory_listener);
> + if (!vhost_section(dev, section)) {
> + return;
> + }
> + dev->vhost_ops->vhost_set_used_memslots(dev);
> +}
> +
> static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> {
> struct vhost_iommu *iommu = container_of(n, struct vhost_iommu, n);
> @@ -1300,6 +1311,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> hdev->memory_listener = (MemoryListener) {
> .begin = vhost_begin,
> .commit = vhost_commit,
> + .region_del = vhost_region_del,
> .region_add = vhost_region_addnop,
> .region_nop = vhost_region_addnop,
> .log_start = vhost_log_start,
> @@ -1346,9 +1358,16 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> memory_listener_register(&hdev->memory_listener, &address_space_memory);
> QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
>
> - if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
> - error_report("vhost backend memory slots limit is less"
> - " than current number of present memory slots");
> + /*
> + * If we started a VM without any vhost device,
> + * for the first time vhost device hot-plug
> + * (vhost_get_used_memslots is always 0),
> + * so it needs to double check here.
> + */
> + if (hdev->vhost_ops->vhost_get_used_memslots(hdev) >
> + hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
> + error_report("vhost backend memory slots limit is less than"
> + " current number of present memory slots");
> r = -1;
> if (busyloop_timeout) {
> goto fail_busyloop;
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index 8825bd278f..6569c95a43 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -124,6 +124,9 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
>
> typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
>
> +typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev);
> +typedef unsigned int (*vhost_get_used_memslots_op)(struct vhost_dev *dev);
> +
> typedef struct VhostOps {
> VhostBackendType backend_type;
> vhost_backend_init vhost_backend_init;
> @@ -168,6 +171,8 @@ typedef struct VhostOps {
> vhost_vq_get_addr_op vhost_vq_get_addr;
> vhost_get_device_id_op vhost_get_device_id;
> vhost_force_iommu_op vhost_force_iommu;
> + vhost_set_used_memslots_op vhost_set_used_memslots;
> + vhost_get_used_memslots_op vhost_get_used_memslots;
> } VhostOps;
>
> extern const VhostOps user_ops;
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 767a95ec0b..5ded21f86d 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -90,6 +90,7 @@ struct vhost_dev {
> QLIST_HEAD(, vhost_iommu) iommu_list;
> IOMMUNotifier n;
> const VhostDevConfigOps *config_ops;
> + unsigned int used_memslots;
> };
>
> struct vhost_net {
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index 17532daaf3..7e93955537 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -20,6 +20,7 @@
> #include "qemu/error-report.h"
> #include "qemu/option.h"
> #include "trace.h"
> +#include "include/hw/virtio/vhost.h"
>
> typedef struct NetVhostUserState {
> NetClientState nc;
> @@ -347,6 +348,12 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
> qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
> net_vhost_user_event, NULL, nc0->name, NULL,
> true);
> +
> + if (!vhost_has_free_slot()) {
> + error_report("used memslots exceeded the backend limit, quit "
> + "loop");
> + goto err;
> + }
> } while (!s->started);
>
> assert(s->vhost_net);
next prev parent reply other threads:[~2020-10-06 9:50 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-28 13:17 [PATCH] vhost-user: add separate memslot counter for vhost-user Jiajun Chen
2020-10-02 2:05 ` Raphael Norwitz
2020-10-12 11:12 ` chenjiajun
2020-10-14 1:22 ` Raphael Norwitz
2020-10-06 9:48 ` Igor Mammedov [this message]
2020-10-14 0:58 ` Raphael Norwitz
2020-10-14 7:08 ` Michael S. Tsirkin
2020-10-14 16:11 ` Raphael Norwitz
2020-10-14 16:26 ` Michael S. Tsirkin
2020-10-14 17:21 ` Raphael Norwitz
2020-10-14 17:54 ` Michael S. Tsirkin
2020-10-21 14:34 ` Igor Mammedov
2020-10-30 8:39 ` Michael S. Tsirkin
-- strict thread matches above, loose matches on Subject: below --
2020-09-08 6:11 Jiajun Chen
2020-09-08 8:37 ` Michael S. Tsirkin
2020-09-15 1:27 ` Raphael Norwitz
2020-08-11 1:43 Jiajun Chen
2020-08-27 12:11 ` Michael S. Tsirkin
2020-09-02 5:02 ` Raphael Norwitz
2020-08-07 9:47 Jiajun Chen
2020-08-07 9:55 ` no-reply
2020-08-07 8:19 Jiajun Chen
2020-08-07 8:25 ` no-reply
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=20201006114801.6833a72d@redhat.com \
--to=imammedo@redhat.com \
--cc=chenjiajun8@huawei.com \
--cc=jasowang@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=raphael.s.norwitz@gmail.com \
--cc=xiexiangyou@huawei.com \
--cc=zhang.zhanghailiang@huawei.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.