[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL v2 10/27] virtio: don't enable notifications during polling
From: |
Michael S. Tsirkin |
Subject: |
[PULL v2 10/27] virtio: don't enable notifications during polling |
Date: |
Mon, 23 Dec 2019 11:41:40 -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 v2 00/27] virtio, pci, pc: fixes, features, Michael S. Tsirkin, 2019/12/23
- [PULL v2 01/27] virtio: add ability to delete vq through a pointer, Michael S. Tsirkin, 2019/12/23
- [PULL v2 02/27] virtio: make virtio_delete_queue idempotent, Michael S. Tsirkin, 2019/12/23
- [PULL v2 03/27] virtio-balloon: fix memory leak while attach virtio-balloon device, Michael S. Tsirkin, 2019/12/23
- [PULL v2 04/27] virtio-serial-bus: fix memory leak while attach virtio-serial-bus, Michael S. Tsirkin, 2019/12/23
- [PULL v2 05/27] virtio-input: convert to new virtio_delete_queue, Michael S. Tsirkin, 2019/12/23
- [PULL v2 06/27] intel_iommu: fix bug to read DMAR_RTADDR_REG, Michael S. Tsirkin, 2019/12/23
- [PULL v2 07/27] virtio: update queue size on guest write, Michael S. Tsirkin, 2019/12/23
- [PULL v2 09/27] Implement backend program convention command for vhost-user-blk, Michael S. Tsirkin, 2019/12/23
- [PULL v2 08/27] virtio-pci: disable vring processing when bus-mastering is disabled, Michael S. Tsirkin, 2019/12/23
- [PULL v2 10/27] virtio: don't enable notifications during polling,
Michael S. Tsirkin <=
- [PULL v2 11/27] numa: Extend CLI to provide initiator information for numa nodes, Michael S. Tsirkin, 2019/12/23
- [PULL v2 12/27] numa: Extend CLI to provide memory latency and bandwidth information, Michael S. Tsirkin, 2019/12/23
- [PULL v2 13/27] numa: Extend CLI to provide memory side cache information, Michael S. Tsirkin, 2019/12/23
- [PULL v2 14/27] hmat acpi: Build Memory Proximity Domain Attributes Structure(s), Michael S. Tsirkin, 2019/12/23
- [PULL v2 15/27] hmat acpi: Build System Locality Latency and Bandwidth Information Structure(s), Michael S. Tsirkin, 2019/12/23
- [PULL v2 16/27] hmat acpi: Build Memory Side Cache Information Structure(s), Michael S. Tsirkin, 2019/12/23
- [PULL v2 17/27] tests/numa: Add case for QMP build HMAT, Michael S. Tsirkin, 2019/12/23
- [PULL v2 18/27] tests/bios-tables-test: add test cases for ACPI HMAT, Michael S. Tsirkin, 2019/12/23
- [PULL v2 20/27] virtio-mmio: Clear v2 transport state on soft reset, Michael S. Tsirkin, 2019/12/23
- [PULL v2 19/27] ACPI: add expected files for HMAT tests (acpihmat), Michael S. Tsirkin, 2019/12/23