virtio: unify virtio_notify_irqfd() and virtio_notify()
The difference between these two functions: - virtio_notify() uses the interrupt code path (MSI or classic IRQs) - virtio_notify_irqfd() uses guest notifiers (irqfds) virtio_notify() can only be called with the BQL held because the interrupt code path requires the BQL. Device models use virtio_notify_irqfd() from IOThreads since the BQL is not held. The two functions can be unified by pushing down the if (qemu_in_iothread()) check from virtio-blk and virtio-scsi into core virtio code. This is in preparation for the next commit that will add irqfd support to virtio_notify_config() and where it's unattractive to introduce another irqfd-only API for device model callers. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20250922220149.498967-3-stefanha@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
2e41580328
commit
1e9181dc52
5 changed files with 15 additions and 27 deletions
|
|
@ -62,11 +62,7 @@ void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
|
|||
iov_discard_undo(&req->inhdr_undo);
|
||||
iov_discard_undo(&req->outhdr_undo);
|
||||
virtqueue_push(req->vq, &req->elem, req->in_len);
|
||||
if (qemu_in_iothread()) {
|
||||
virtio_notify_irqfd(vdev, req->vq);
|
||||
} else {
|
||||
virtio_notify(vdev, req->vq);
|
||||
}
|
||||
virtio_notify(vdev, req->vq);
|
||||
}
|
||||
|
||||
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
|
||||
|
|
|
|||
|
|
@ -116,11 +116,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req, QemuMutex *vq_lock)
|
|||
}
|
||||
|
||||
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
|
||||
if (s->dataplane_started && !s->dataplane_fenced) {
|
||||
virtio_notify_irqfd(vdev, vq);
|
||||
} else {
|
||||
virtio_notify(vdev, vq);
|
||||
}
|
||||
virtio_notify(vdev, vq);
|
||||
|
||||
if (vq_lock) {
|
||||
qemu_mutex_unlock(vq_lock);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
|
|||
virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
|
||||
virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
|
||||
virtio_notify_irqfd_deferred_fn(void *vdev, void *vq) "vdev %p vq %p"
|
||||
virtio_notify_irqfd(void *vdev, void *vq) "vdev %p vq %p"
|
||||
virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
|
||||
virtio_set_status(void *vdev, uint8_t val) "vdev %p val %u"
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "hw/qdev-properties.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
#include "system/dma.h"
|
||||
#include "system/iothread.h"
|
||||
#include "system/runstate.h"
|
||||
#include "virtio-qmp.h"
|
||||
|
||||
|
|
@ -2654,16 +2655,8 @@ static void virtio_notify_irqfd_deferred_fn(void *opaque)
|
|||
event_notifier_set(notifier);
|
||||
}
|
||||
|
||||
void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
static void virtio_irq(VirtQueue *vq)
|
||||
{
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
if (!virtio_should_notify(vdev, vq)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
trace_virtio_notify_irqfd(vdev, vq);
|
||||
|
||||
/*
|
||||
* virtio spec 1.0 says ISR bit 0 should be ignored with MSI, but
|
||||
* windows drivers included in virtio-win 1.8.0 (circa 2015) are
|
||||
|
|
@ -2680,13 +2673,18 @@ void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq)
|
|||
* to an atomic operation.
|
||||
*/
|
||||
virtio_set_isr(vq->vdev, 0x1);
|
||||
defer_call(virtio_notify_irqfd_deferred_fn, &vq->guest_notifier);
|
||||
}
|
||||
|
||||
static void virtio_irq(VirtQueue *vq)
|
||||
{
|
||||
virtio_set_isr(vq->vdev, 0x1);
|
||||
virtio_notify_vector(vq->vdev, vq->vector);
|
||||
/*
|
||||
* The interrupt code path requires the Big QEMU Lock (BQL), so use the
|
||||
* notifier instead when in an IOThread. This assumes that device models
|
||||
* have already called ->set_guest_notifiers() sometime before calling this
|
||||
* function.
|
||||
*/
|
||||
if (qemu_in_iothread()) {
|
||||
defer_call(virtio_notify_irqfd_deferred_fn, &vq->guest_notifier);
|
||||
} else {
|
||||
virtio_notify_vector(vq->vdev, vq->vector);
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
|
|
|||
|
|
@ -294,7 +294,6 @@ int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
|
|||
unsigned int *out_bytes, unsigned max_in_bytes,
|
||||
unsigned max_out_bytes);
|
||||
|
||||
void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
|
||||
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
|
||||
|
||||
int virtio_save(VirtIODevice *vdev, QEMUFile *f);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue