virtio: move ioeventfd_started flag to VirtioBusState
This simplifies the code and removes the ioeventfd_started and ioeventfd_set_started callback. The only difference is in how virtio-ccw handles an error---it doesn't disable ioeventfd forever anymore. It was the only backend to do so, and if desired this behavior should be implemented in virtio-bus.c. Instead of ioeventfd_started, the ioeventfd_assign callback now determines whether the virtio bus supports host notifiers. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									4ddcc2d5cb
								
							
						
					
					
						commit
						b13d396227
					
				@ -93,7 +93,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Don't try if transport does not support notifiers. */
 | 
					    /* Don't try if transport does not support notifiers. */
 | 
				
			||||||
    if (!k->set_guest_notifiers || !k->ioeventfd_started) {
 | 
					    if (!k->set_guest_notifiers || !k->ioeventfd_assign) {
 | 
				
			||||||
        error_setg(errp,
 | 
					        error_setg(errp,
 | 
				
			||||||
                   "device is incompatible with dataplane "
 | 
					                   "device is incompatible with dataplane "
 | 
				
			||||||
                   "(transport does not support notifiers)");
 | 
					                   "(transport does not support notifiers)");
 | 
				
			||||||
 | 
				
			|||||||
@ -59,25 +59,6 @@ static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
 | 
				
			|||||||
    virtio_bus_stop_ioeventfd(&dev->bus);
 | 
					    virtio_bus_stop_ioeventfd(&dev->bus);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool virtio_ccw_ioeventfd_started(DeviceState *d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return dev->ioeventfd_started;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void virtio_ccw_ioeventfd_set_started(DeviceState *d, bool started,
 | 
					 | 
				
			||||||
                                             bool err)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dev->ioeventfd_started = started;
 | 
					 | 
				
			||||||
    if (err) {
 | 
					 | 
				
			||||||
        /* Disable ioeventfd for this device. */
 | 
					 | 
				
			||||||
        dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool virtio_ccw_ioeventfd_disabled(DeviceState *d)
 | 
					static bool virtio_ccw_ioeventfd_disabled(DeviceState *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 | 
					    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 | 
				
			||||||
@ -1608,8 +1589,6 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    k->pre_plugged = virtio_ccw_pre_plugged;
 | 
					    k->pre_plugged = virtio_ccw_pre_plugged;
 | 
				
			||||||
    k->device_plugged = virtio_ccw_device_plugged;
 | 
					    k->device_plugged = virtio_ccw_device_plugged;
 | 
				
			||||||
    k->device_unplugged = virtio_ccw_device_unplugged;
 | 
					    k->device_unplugged = virtio_ccw_device_unplugged;
 | 
				
			||||||
    k->ioeventfd_started = virtio_ccw_ioeventfd_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_set_started = virtio_ccw_ioeventfd_set_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_disabled = virtio_ccw_ioeventfd_disabled;
 | 
					    k->ioeventfd_disabled = virtio_ccw_ioeventfd_disabled;
 | 
				
			||||||
    k->ioeventfd_assign = virtio_ccw_ioeventfd_assign;
 | 
					    k->ioeventfd_assign = virtio_ccw_ioeventfd_assign;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,6 @@ struct VirtioCcwDevice {
 | 
				
			|||||||
    int revision;
 | 
					    int revision;
 | 
				
			||||||
    uint32_t max_rev;
 | 
					    uint32_t max_rev;
 | 
				
			||||||
    VirtioBusState bus;
 | 
					    VirtioBusState bus;
 | 
				
			||||||
    bool ioeventfd_started;
 | 
					 | 
				
			||||||
    uint32_t flags;
 | 
					    uint32_t flags;
 | 
				
			||||||
    uint8_t thinint_isc;
 | 
					    uint8_t thinint_isc;
 | 
				
			||||||
    AdapterRoutes routes;
 | 
					    AdapterRoutes routes;
 | 
				
			||||||
 | 
				
			|||||||
@ -31,7 +31,7 @@ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
 | 
				
			|||||||
    s->ctx = iothread_get_aio_context(vs->conf.iothread);
 | 
					    s->ctx = iothread_get_aio_context(vs->conf.iothread);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Don't try if transport does not support notifiers. */
 | 
					    /* Don't try if transport does not support notifiers. */
 | 
				
			||||||
    if (!k->set_guest_notifiers || !k->ioeventfd_started) {
 | 
					    if (!k->set_guest_notifiers || !k->ioeventfd_assign) {
 | 
				
			||||||
        fprintf(stderr, "virtio-scsi: Failed to set iothread "
 | 
					        fprintf(stderr, "virtio-scsi: Failed to set iothread "
 | 
				
			||||||
                   "(transport does not support notifiers)");
 | 
					                   "(transport does not support notifiers)");
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
 | 
				
			|||||||
@ -1190,7 +1190,7 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
 | 
				
			|||||||
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
 | 
					    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
 | 
				
			||||||
    int i, r, e;
 | 
					    int i, r, e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!k->ioeventfd_started) {
 | 
					    if (!k->ioeventfd_assign) {
 | 
				
			||||||
        error_report("binding does not support host notifiers");
 | 
					        error_report("binding does not support host notifiers");
 | 
				
			||||||
        r = -ENOSYS;
 | 
					        r = -ENOSYS;
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 | 
				
			|||||||
@ -192,10 +192,10 @@ void virtio_bus_start_ioeventfd(VirtioBusState *bus)
 | 
				
			|||||||
    VirtIODevice *vdev;
 | 
					    VirtIODevice *vdev;
 | 
				
			||||||
    int n, r;
 | 
					    int n, r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!k->ioeventfd_started || k->ioeventfd_started(proxy)) {
 | 
					    if (!k->ioeventfd_assign || k->ioeventfd_disabled(proxy)) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (bus->ioeventfd_disabled || k->ioeventfd_disabled(proxy)) {
 | 
					    if (bus->ioeventfd_started || bus->ioeventfd_disabled) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    vdev = virtio_bus_get_device(bus);
 | 
					    vdev = virtio_bus_get_device(bus);
 | 
				
			||||||
@ -208,7 +208,7 @@ void virtio_bus_start_ioeventfd(VirtioBusState *bus)
 | 
				
			|||||||
            goto assign_error;
 | 
					            goto assign_error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    k->ioeventfd_set_started(proxy, true, false);
 | 
					    bus->ioeventfd_started = true;
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
assign_error:
 | 
					assign_error:
 | 
				
			||||||
@ -220,18 +220,16 @@ assign_error:
 | 
				
			|||||||
        r = set_host_notifier_internal(proxy, bus, n, false, false);
 | 
					        r = set_host_notifier_internal(proxy, bus, n, false, false);
 | 
				
			||||||
        assert(r >= 0);
 | 
					        assert(r >= 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    k->ioeventfd_set_started(proxy, false, true);
 | 
					 | 
				
			||||||
    error_report("%s: failed. Fallback to userspace (slower).", __func__);
 | 
					    error_report("%s: failed. Fallback to userspace (slower).", __func__);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void virtio_bus_stop_ioeventfd(VirtioBusState *bus)
 | 
					void virtio_bus_stop_ioeventfd(VirtioBusState *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
 | 
					 | 
				
			||||||
    DeviceState *proxy = DEVICE(BUS(bus)->parent);
 | 
					    DeviceState *proxy = DEVICE(BUS(bus)->parent);
 | 
				
			||||||
    VirtIODevice *vdev;
 | 
					    VirtIODevice *vdev;
 | 
				
			||||||
    int n, r;
 | 
					    int n, r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!k->ioeventfd_started || !k->ioeventfd_started(proxy)) {
 | 
					    if (!bus->ioeventfd_started) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    vdev = virtio_bus_get_device(bus);
 | 
					    vdev = virtio_bus_get_device(bus);
 | 
				
			||||||
@ -242,7 +240,7 @@ void virtio_bus_stop_ioeventfd(VirtioBusState *bus)
 | 
				
			|||||||
        r = set_host_notifier_internal(proxy, bus, n, false, false);
 | 
					        r = set_host_notifier_internal(proxy, bus, n, false, false);
 | 
				
			||||||
        assert(r >= 0);
 | 
					        assert(r >= 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    k->ioeventfd_set_started(proxy, false, false);
 | 
					    bus->ioeventfd_started = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@ -254,7 +252,7 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign)
 | 
				
			|||||||
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
 | 
					    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
 | 
				
			||||||
    DeviceState *proxy = DEVICE(BUS(bus)->parent);
 | 
					    DeviceState *proxy = DEVICE(BUS(bus)->parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!k->ioeventfd_started) {
 | 
					    if (!k->ioeventfd_assign) {
 | 
				
			||||||
        return -ENOSYS;
 | 
					        return -ENOSYS;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bus->ioeventfd_disabled = assign;
 | 
					    bus->ioeventfd_disabled = assign;
 | 
				
			||||||
 | 
				
			|||||||
@ -89,25 +89,9 @@ typedef struct {
 | 
				
			|||||||
    uint32_t guest_page_shift;
 | 
					    uint32_t guest_page_shift;
 | 
				
			||||||
    /* virtio-bus */
 | 
					    /* virtio-bus */
 | 
				
			||||||
    VirtioBusState bus;
 | 
					    VirtioBusState bus;
 | 
				
			||||||
    bool ioeventfd_started;
 | 
					 | 
				
			||||||
    bool format_transport_address;
 | 
					    bool format_transport_address;
 | 
				
			||||||
} VirtIOMMIOProxy;
 | 
					} VirtIOMMIOProxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool virtio_mmio_ioeventfd_started(DeviceState *d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return proxy->ioeventfd_started;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void virtio_mmio_ioeventfd_set_started(DeviceState *d, bool started,
 | 
					 | 
				
			||||||
                                              bool err)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proxy->ioeventfd_started = started;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool virtio_mmio_ioeventfd_disabled(DeviceState *d)
 | 
					static bool virtio_mmio_ioeventfd_disabled(DeviceState *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return !kvm_eventfds_enabled();
 | 
					    return !kvm_eventfds_enabled();
 | 
				
			||||||
@ -547,8 +531,6 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    k->save_config = virtio_mmio_save_config;
 | 
					    k->save_config = virtio_mmio_save_config;
 | 
				
			||||||
    k->load_config = virtio_mmio_load_config;
 | 
					    k->load_config = virtio_mmio_load_config;
 | 
				
			||||||
    k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
 | 
					    k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
 | 
				
			||||||
    k->ioeventfd_started = virtio_mmio_ioeventfd_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_set_started = virtio_mmio_ioeventfd_set_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_disabled = virtio_mmio_ioeventfd_disabled;
 | 
					    k->ioeventfd_disabled = virtio_mmio_ioeventfd_disabled;
 | 
				
			||||||
    k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
 | 
					    k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
 | 
				
			||||||
    k->has_variable_vring_alignment = true;
 | 
					    k->has_variable_vring_alignment = true;
 | 
				
			||||||
 | 
				
			|||||||
@ -262,21 +262,6 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool virtio_pci_ioeventfd_started(DeviceState *d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return proxy->ioeventfd_started;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void virtio_pci_ioeventfd_set_started(DeviceState *d, bool started,
 | 
					 | 
				
			||||||
                                             bool err)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proxy->ioeventfd_started = started;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool virtio_pci_ioeventfd_disabled(DeviceState *d)
 | 
					static bool virtio_pci_ioeventfd_disabled(DeviceState *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 | 
					    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 | 
				
			||||||
@ -2531,8 +2516,6 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
 | 
				
			|||||||
    k->device_plugged = virtio_pci_device_plugged;
 | 
					    k->device_plugged = virtio_pci_device_plugged;
 | 
				
			||||||
    k->device_unplugged = virtio_pci_device_unplugged;
 | 
					    k->device_unplugged = virtio_pci_device_unplugged;
 | 
				
			||||||
    k->query_nvectors = virtio_pci_query_nvectors;
 | 
					    k->query_nvectors = virtio_pci_query_nvectors;
 | 
				
			||||||
    k->ioeventfd_started = virtio_pci_ioeventfd_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_set_started = virtio_pci_ioeventfd_set_started;
 | 
					 | 
				
			||||||
    k->ioeventfd_disabled = virtio_pci_ioeventfd_disabled;
 | 
					    k->ioeventfd_disabled = virtio_pci_ioeventfd_disabled;
 | 
				
			||||||
    k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
 | 
					    k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -158,7 +158,6 @@ struct VirtIOPCIProxy {
 | 
				
			|||||||
    uint32_t guest_features[2];
 | 
					    uint32_t guest_features[2];
 | 
				
			||||||
    VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
 | 
					    VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool ioeventfd_started;
 | 
					 | 
				
			||||||
    VirtIOIRQFD *vector_irqfd;
 | 
					    VirtIOIRQFD *vector_irqfd;
 | 
				
			||||||
    int nvqs_with_notifiers;
 | 
					    int nvqs_with_notifiers;
 | 
				
			||||||
    VirtioBusState bus;
 | 
					    VirtioBusState bus;
 | 
				
			||||||
 | 
				
			|||||||
@ -70,17 +70,9 @@ typedef struct VirtioBusClass {
 | 
				
			|||||||
    void (*device_unplugged)(DeviceState *d);
 | 
					    void (*device_unplugged)(DeviceState *d);
 | 
				
			||||||
    int (*query_nvectors)(DeviceState *d);
 | 
					    int (*query_nvectors)(DeviceState *d);
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * ioeventfd handling: if the transport implements ioeventfd_started,
 | 
					     * ioeventfd handling: if the transport implements ioeventfd_assign,
 | 
				
			||||||
     * it must implement the other ioeventfd callbacks as well
 | 
					     * it must implement ioeventfd_disabled as well.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    /* Returns true if the ioeventfd has been started for the device. */
 | 
					 | 
				
			||||||
    bool (*ioeventfd_started)(DeviceState *d);
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
     * Sets the 'ioeventfd started' state after the ioeventfd has been
 | 
					 | 
				
			||||||
     * started/stopped for the device. err signifies whether an error
 | 
					 | 
				
			||||||
     * had occurred.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    void (*ioeventfd_set_started)(DeviceState *d, bool started, bool err);
 | 
					 | 
				
			||||||
    /* Returns true if the ioeventfd has been disabled for the device. */
 | 
					    /* Returns true if the ioeventfd has been disabled for the device. */
 | 
				
			||||||
    bool (*ioeventfd_disabled)(DeviceState *d);
 | 
					    bool (*ioeventfd_disabled)(DeviceState *d);
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
@ -106,6 +98,11 @@ struct VirtioBusState {
 | 
				
			|||||||
     * or dataplane.
 | 
					     * or dataplane.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    bool ioeventfd_disabled;
 | 
					    bool ioeventfd_disabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Set if ioeventfd has been started.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    bool ioeventfd_started;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp);
 | 
					void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user