From: Ilias Stamatis <ilstam@amazon.com>
To: <kvm@vger.kernel.org>, <pbonzini@redhat.com>
Cc: <pdurrant@amazon.co.uk>, <dwmw@amazon.co.uk>,
<Laurent.Vivier@bull.net>, <ghaskins@novell.com>,
<avi@redhat.com>, <mst@redhat.com>, <levinsasha928@gmail.com>,
<peng.hao2@zte.com.cn>, <nh-open-source@amazon.com>
Subject: [PATCH 3/6] KVM: Support poll() on coalesced mmio buffer fds
Date: Wed, 10 Jul 2024 09:52:56 +0100 [thread overview]
Message-ID: <20240710085259.2125131-4-ilstam@amazon.com> (raw)
In-Reply-To: <20240710085259.2125131-1-ilstam@amazon.com>
There is no direct way for userspace to be notified about coalesced MMIO
writes when using KVM_REGISTER_COALESCED_MMIO. If the next MMIO exit is
when the ring buffer has filled then a substantial (and unbounded)
amount of time may have passed since the first coalesced MMIO.
To improve this, make it possible for userspace to use poll() and
select() on the fd returned by the KVM_CREATE_COALESCED_MMIO_BUFFER
ioctl. This way a userspace VMM could have dedicated threads that deal
with writes to specific MMIO zones.
For example, a common use of MMIO, particularly in the realm of network
devices, is as a doorbell. A write to a doorbell register will trigger
the device to initiate a DMA transfer.
When a network device is emulated by userspace a write to a doorbell
register would typically result in an MMIO exit so that userspace can
emulate the DMA transfer in a timely manner. No further processing can
be done until userspace performs the necessary emulation and re-invokes
KVM_RUN. Even if userspace makes use of another thread to emulate the
DMA transfer such MMIO exits are disruptive to the vCPU and they may
also be quite frequent if, for example, the vCPU is sending a sequence
of short packets to the network device.
By supporting poll() on coalesced buffer fds, userspace can have
dedicated threads wait for new doorbell writes and avoid the performance
hit of userspace exits on the main vCPU threads.
Signed-off-by: Ilias Stamatis <ilstam@amazon.com>
---
virt/kvm/coalesced_mmio.c | 20 ++++++++++++++++++++
virt/kvm/coalesced_mmio.h | 1 +
2 files changed, 21 insertions(+)
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 6443d4b62548..00439e035d74 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/kvm.h>
#include <linux/anon_inodes.h>
+#include <linux/poll.h>
#include "coalesced_mmio.h"
@@ -98,6 +99,10 @@ static int coalesced_mmio_write(struct kvm_vcpu *vcpu,
smp_wmb();
ring->last = (insert + 1) % KVM_COALESCED_MMIO_MAX;
spin_unlock(lock);
+
+ if (dev->buffer_dev)
+ wake_up_interruptible(&dev->buffer_dev->wait_queue);
+
return 0;
}
@@ -224,9 +229,23 @@ static int coalesced_mmio_buffer_release(struct inode *inode, struct file *file)
return 0;
}
+static __poll_t coalesced_mmio_buffer_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct kvm_coalesced_mmio_buffer_dev *dev = file->private_data;
+ __poll_t mask = 0;
+
+ poll_wait(file, &dev->wait_queue, wait);
+
+ if (READ_ONCE(dev->ring->first) != READ_ONCE(dev->ring->last))
+ mask = POLLIN | POLLRDNORM;
+
+ return mask;
+}
+
static const struct file_operations coalesced_mmio_buffer_ops = {
.mmap = coalesced_mmio_buffer_mmap,
.release = coalesced_mmio_buffer_release,
+ .poll = coalesced_mmio_buffer_poll,
};
int kvm_vm_ioctl_create_coalesced_mmio_buffer(struct kvm *kvm)
@@ -240,6 +259,7 @@ int kvm_vm_ioctl_create_coalesced_mmio_buffer(struct kvm *kvm)
return -ENOMEM;
dev->kvm = kvm;
+ init_waitqueue_head(&dev->wait_queue);
spin_lock_init(&dev->ring_lock);
ret = anon_inode_getfd("coalesced_mmio_buf", &coalesced_mmio_buffer_ops,
diff --git a/virt/kvm/coalesced_mmio.h b/virt/kvm/coalesced_mmio.h
index 37d9d8f325bb..d1807ce26464 100644
--- a/virt/kvm/coalesced_mmio.h
+++ b/virt/kvm/coalesced_mmio.h
@@ -26,6 +26,7 @@ struct kvm_coalesced_mmio_dev {
struct kvm_coalesced_mmio_buffer_dev {
struct list_head list;
struct kvm *kvm;
+ wait_queue_head_t wait_queue;
spinlock_t ring_lock;
struct kvm_coalesced_mmio_ring *ring;
};
--
2.34.1
next prev parent reply other threads:[~2024-07-10 8:56 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-10 8:52 [PATCH 0/6] KVM: Improve MMIO Coalescing API Ilias Stamatis
2024-07-10 8:52 ` [PATCH 1/6] KVM: Fix coalesced_mmio_has_room() Ilias Stamatis
2024-07-12 13:13 ` Paul Durrant
2024-07-12 15:55 ` Roman Kagan
2024-07-12 19:03 ` Stamatis, Ilias
2024-07-15 9:30 ` Kagan, Roman
2024-07-10 8:52 ` [PATCH 2/6] KVM: Add KVM_CREATE_COALESCED_MMIO_BUFFER ioctl Ilias Stamatis
2024-07-12 13:22 ` Paul Durrant
2024-07-10 8:52 ` Ilias Stamatis [this message]
2024-07-12 13:26 ` [PATCH 3/6] KVM: Support poll() on coalesced mmio buffer fds Paul Durrant
2024-07-10 8:52 ` [PATCH 4/6] KVM: Add KVM_(UN)REGISTER_COALESCED_MMIO2 ioctls Ilias Stamatis
2024-07-13 6:19 ` Paul Durrant
2024-07-13 14:15 ` kernel test robot
2024-07-13 20:48 ` kernel test robot
2024-07-10 8:52 ` [PATCH 5/6] KVM: Documentation: Document v2 of coalesced MMIO API Ilias Stamatis
2024-07-13 6:19 ` Paul Durrant
2024-07-10 8:52 ` [PATCH 6/6] KVM: selftests: Add coalesced_mmio_test Ilias Stamatis
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=20240710085259.2125131-4-ilstam@amazon.com \
--to=ilstam@amazon.com \
--cc=Laurent.Vivier@bull.net \
--cc=avi@redhat.com \
--cc=dwmw@amazon.co.uk \
--cc=ghaskins@novell.com \
--cc=kvm@vger.kernel.org \
--cc=levinsasha928@gmail.com \
--cc=mst@redhat.com \
--cc=nh-open-source@amazon.com \
--cc=pbonzini@redhat.com \
--cc=pdurrant@amazon.co.uk \
--cc=peng.hao2@zte.com.cn \
/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