virtio: remove event notifier cleanup call on de-assign
The virtio_bus_set_host_notifier function no longer calls event_notifier_cleanup when a event notifier is removed. The commit updates the code to match the new behavior and calls virtio_bus_cleanup_host_notifier after the notifier was de-assign and no longer in use. This change is a preparation to allow executing the virtio_bus_set_host_notifier function in a memory region transaction. Signed-off-by: Gal Hammer <ghammer@redhat.com> Reviewed-by: Greg Kurz <groug@kaod.org> Tested-by: Greg Kurz <groug@kaod.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									f41d912023
								
							
						
					
					
						commit
						76143618a5
					
				@ -192,6 +192,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
 | 
				
			|||||||
            fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
 | 
					            fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
 | 
				
			||||||
            while (i--) {
 | 
					            while (i--) {
 | 
				
			||||||
                virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
					                virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
				
			||||||
 | 
					                virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            goto fail_guest_notifiers;
 | 
					            goto fail_guest_notifiers;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -267,6 +268,7 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < nvqs; i++) {
 | 
					    for (i = 0; i < nvqs; i++) {
 | 
				
			||||||
        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
					        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Clean up guest notifier (irq) */
 | 
					    /* Clean up guest notifier (irq) */
 | 
				
			||||||
 | 
				
			|||||||
@ -175,6 +175,7 @@ fail_vrings:
 | 
				
			|||||||
    aio_context_release(s->ctx);
 | 
					    aio_context_release(s->ctx);
 | 
				
			||||||
    for (i = 0; i < vs->conf.num_queues + 2; i++) {
 | 
					    for (i = 0; i < vs->conf.num_queues + 2; i++) {
 | 
				
			||||||
        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
					        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
 | 
					    k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
 | 
				
			||||||
fail_guest_notifiers:
 | 
					fail_guest_notifiers:
 | 
				
			||||||
@ -213,6 +214,7 @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < vs->conf.num_queues + 2; i++) {
 | 
					    for (i = 0; i < vs->conf.num_queues + 2; i++) {
 | 
				
			||||||
        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
					        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Clean up guest notifier (irq) */
 | 
					    /* Clean up guest notifier (irq) */
 | 
				
			||||||
 | 
				
			|||||||
@ -1418,6 +1418,7 @@ fail_vq:
 | 
				
			|||||||
            error_report("vhost VQ %d notifier cleanup error: %d", i, -r);
 | 
					            error_report("vhost VQ %d notifier cleanup error: %d", i, -r);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        assert (e >= 0);
 | 
					        assert (e >= 0);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtio_device_release_ioeventfd(vdev);
 | 
					    virtio_device_release_ioeventfd(vdev);
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
@ -1441,6 +1442,7 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
 | 
				
			|||||||
            error_report("vhost VQ %d notifier cleanup failed: %d", i, -r);
 | 
					            error_report("vhost VQ %d notifier cleanup failed: %d", i, -r);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        assert (r >= 0);
 | 
					        assert (r >= 0);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    virtio_device_release_ioeventfd(vdev);
 | 
					    virtio_device_release_ioeventfd(vdev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -283,20 +283,26 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign)
 | 
				
			|||||||
        r = k->ioeventfd_assign(proxy, notifier, n, true);
 | 
					        r = k->ioeventfd_assign(proxy, notifier, n, true);
 | 
				
			||||||
        if (r < 0) {
 | 
					        if (r < 0) {
 | 
				
			||||||
            error_report("%s: unable to assign ioeventfd: %d", __func__, r);
 | 
					            error_report("%s: unable to assign ioeventfd: %d", __func__, r);
 | 
				
			||||||
            goto cleanup_event_notifier;
 | 
					            virtio_bus_cleanup_host_notifier(bus, n);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        k->ioeventfd_assign(proxy, notifier, n, false);
 | 
					        k->ioeventfd_assign(proxy, notifier, n, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cleanup_event_notifier:
 | 
					    return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void virtio_bus_cleanup_host_notifier(VirtioBusState *bus, int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    VirtIODevice *vdev = virtio_bus_get_device(bus);
 | 
				
			||||||
 | 
					    VirtQueue *vq = virtio_get_queue(vdev, n);
 | 
				
			||||||
 | 
					    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Test and clear notifier after disabling event,
 | 
					    /* Test and clear notifier after disabling event,
 | 
				
			||||||
     * in case poll callback didn't have time to run.
 | 
					     * in case poll callback didn't have time to run.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    virtio_queue_host_notifier_read(notifier);
 | 
					    virtio_queue_host_notifier_read(notifier);
 | 
				
			||||||
    event_notifier_cleanup(notifier);
 | 
					    event_notifier_cleanup(notifier);
 | 
				
			||||||
    return r;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *virtio_bus_get_dev_path(DeviceState *dev)
 | 
					static char *virtio_bus_get_dev_path(DeviceState *dev)
 | 
				
			||||||
 | 
				
			|||||||
@ -2608,6 +2608,7 @@ assign_error:
 | 
				
			|||||||
        event_notifier_set_handler(&vq->host_notifier, NULL);
 | 
					        event_notifier_set_handler(&vq->host_notifier, NULL);
 | 
				
			||||||
        r = virtio_bus_set_host_notifier(qbus, n, false);
 | 
					        r = virtio_bus_set_host_notifier(qbus, n, false);
 | 
				
			||||||
        assert(r >= 0);
 | 
					        assert(r >= 0);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(qbus, n);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return err;
 | 
					    return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -2634,6 +2635,7 @@ static void virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
 | 
				
			|||||||
        event_notifier_set_handler(&vq->host_notifier, NULL);
 | 
					        event_notifier_set_handler(&vq->host_notifier, NULL);
 | 
				
			||||||
        r = virtio_bus_set_host_notifier(qbus, n, false);
 | 
					        r = virtio_bus_set_host_notifier(qbus, n, false);
 | 
				
			||||||
        assert(r >= 0);
 | 
					        assert(r >= 0);
 | 
				
			||||||
 | 
					        virtio_bus_cleanup_host_notifier(qbus, n);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -148,5 +148,7 @@ int virtio_bus_grab_ioeventfd(VirtioBusState *bus);
 | 
				
			|||||||
void virtio_bus_release_ioeventfd(VirtioBusState *bus);
 | 
					void virtio_bus_release_ioeventfd(VirtioBusState *bus);
 | 
				
			||||||
/* Switch from/to the generic ioeventfd handler */
 | 
					/* Switch from/to the generic ioeventfd handler */
 | 
				
			||||||
int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
 | 
					int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
 | 
				
			||||||
 | 
					/* Tell the bus that the ioeventfd handler is no longer required. */
 | 
				
			||||||
 | 
					void virtio_bus_cleanup_host_notifier(VirtioBusState *bus, int n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* VIRTIO_BUS_H */
 | 
					#endif /* VIRTIO_BUS_H */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user