[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL v3 10/32] virtio: don't enable notifications during polling
From: |
Michael S. Tsirkin |
Subject: |
[PULL v3 10/32] virtio: don't enable notifications during polling |
Date: |
Sun, 5 Jan 2020 07:58:06 -0500 |
From: Stefan Hajnoczi <address@hidden>
Virtqueue notifications are not necessary during polling, so we disable
them. This allows the guest driver to avoid MMIO vmexits.
Unfortunately the virtio-blk and virtio-scsi handler functions re-enable
notifications, defeating this optimization.
Fix virtio-blk and virtio-scsi emulation so they leave notifications
disabled. The key thing to remember for correctness is that polling
always checks one last time after ending its loop, therefore it's safe
to lose the race when re-enabling notifications at the end of polling.
There is a measurable performance improvement of 5-10% with the null-co
block driver. Real-life storage configurations will see a smaller
improvement because the MMIO vmexit overhead contributes less to
latency.
Signed-off-by: Stefan Hajnoczi <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
include/hw/virtio/virtio.h | 1 +
hw/block/virtio-blk.c | 9 +++++++--
hw/scsi/virtio-scsi.c | 9 +++++++--
hw/virtio/virtio.c | 12 ++++++------
4 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 777772475c..b69d517496 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -228,6 +228,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int
version_id);
void virtio_notify_config(VirtIODevice *vdev);
+bool virtio_queue_get_notification(VirtQueue *vq);
void virtio_queue_set_notification(VirtQueue *vq, int enable);
int virtio_queue_ready(VirtQueue *vq);
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index d62e6377c2..b12157b5eb 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -764,13 +764,16 @@ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
{
VirtIOBlockReq *req;
MultiReqBuffer mrb = {};
+ bool suppress_notifications = virtio_queue_get_notification(vq);
bool progress = false;
aio_context_acquire(blk_get_aio_context(s->blk));
blk_io_plug(s->blk);
do {
- virtio_queue_set_notification(vq, 0);
+ if (suppress_notifications) {
+ virtio_queue_set_notification(vq, 0);
+ }
while ((req = virtio_blk_get_request(s, vq))) {
progress = true;
@@ -781,7 +784,9 @@ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
}
}
- virtio_queue_set_notification(vq, 1);
+ if (suppress_notifications) {
+ virtio_queue_set_notification(vq, 1);
+ }
} while (!virtio_queue_empty(vq));
if (mrb.num_reqs) {
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index e8b2b64d09..f080545f48 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -597,12 +597,15 @@ bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue
*vq)
{
VirtIOSCSIReq *req, *next;
int ret = 0;
+ bool suppress_notifications = virtio_queue_get_notification(vq);
bool progress = false;
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
do {
- virtio_queue_set_notification(vq, 0);
+ if (suppress_notifications) {
+ virtio_queue_set_notification(vq, 0);
+ }
while ((req = virtio_scsi_pop_req(s, vq))) {
progress = true;
@@ -622,7 +625,9 @@ bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
}
}
- virtio_queue_set_notification(vq, 1);
+ if (suppress_notifications) {
+ virtio_queue_set_notification(vq, 1);
+ }
} while (ret != -EINVAL && !virtio_queue_empty(vq));
QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7bc6a9455e..95d8ff8508 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -432,6 +432,11 @@ static void virtio_queue_packed_set_notification(VirtQueue
*vq, int enable)
}
}
+bool virtio_queue_get_notification(VirtQueue *vq)
+{
+ return vq->notification;
+}
+
void virtio_queue_set_notification(VirtQueue *vq, int enable)
{
vq->notification = enable;
@@ -3410,17 +3415,12 @@ static bool virtio_queue_host_notifier_aio_poll(void
*opaque)
{
EventNotifier *n = opaque;
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
- bool progress;
if (!vq->vring.desc || virtio_queue_empty(vq)) {
return false;
}
- progress = virtio_queue_notify_aio_vq(vq);
-
- /* In case the handler function re-enabled notifications */
- virtio_queue_set_notification(vq, 0);
- return progress;
+ return virtio_queue_notify_aio_vq(vq);
}
static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n)
--
MST
- [PULL v3 00/32] virtio, pci, pc: fixes, features, Michael S. Tsirkin, 2020/01/05
- [PULL v3 01/32] virtio: add ability to delete vq through a pointer, Michael S. Tsirkin, 2020/01/05
- [PULL v3 02/32] virtio: make virtio_delete_queue idempotent, Michael S. Tsirkin, 2020/01/05
- [PULL v3 03/32] virtio-balloon: fix memory leak while attach virtio-balloon device, Michael S. Tsirkin, 2020/01/05
- [PULL v3 04/32] virtio-serial-bus: fix memory leak while attach virtio-serial-bus, Michael S. Tsirkin, 2020/01/05
- [PULL v3 05/32] virtio-input: convert to new virtio_delete_queue, Michael S. Tsirkin, 2020/01/05
- [PULL v3 06/32] intel_iommu: fix bug to read DMAR_RTADDR_REG, Michael S. Tsirkin, 2020/01/05
- [PULL v3 07/32] virtio: update queue size on guest write, Michael S. Tsirkin, 2020/01/05
- [PULL v3 08/32] virtio-pci: disable vring processing when bus-mastering is disabled, Michael S. Tsirkin, 2020/01/05
- [PULL v3 09/32] Implement backend program convention command for vhost-user-blk, Michael S. Tsirkin, 2020/01/05
- [PULL v3 10/32] virtio: don't enable notifications during polling,
Michael S. Tsirkin <=
- [PULL v3 11/32] numa: Extend CLI to provide initiator information for numa nodes, Michael S. Tsirkin, 2020/01/05
- [PULL v3 12/32] numa: Extend CLI to provide memory latency and bandwidth information, Michael S. Tsirkin, 2020/01/05
- [PULL v3 13/32] numa: Extend CLI to provide memory side cache information, Michael S. Tsirkin, 2020/01/05
- [PULL v3 15/32] hmat acpi: Build System Locality Latency and Bandwidth Information Structure(s), Michael S. Tsirkin, 2020/01/05
- [PULL v3 14/32] hmat acpi: Build Memory Proximity Domain Attributes Structure(s), Michael S. Tsirkin, 2020/01/05
- [PULL v3 16/32] hmat acpi: Build Memory Side Cache Information Structure(s), Michael S. Tsirkin, 2020/01/05
- [PULL v3 17/32] tests/numa: Add case for QMP build HMAT, Michael S. Tsirkin, 2020/01/05
- [PULL v3 18/32] tests/bios-tables-test: add test cases for ACPI HMAT, Michael S. Tsirkin, 2020/01/05
- [PULL v3 19/32] ACPI: add expected files for HMAT tests (acpihmat), Michael S. Tsirkin, 2020/01/05
- [PULL v3 20/32] virtio-mmio: Clear v2 transport state on soft reset, Michael S. Tsirkin, 2020/01/05