mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
hw/virtio: generalise CHR_EVENT_CLOSED handling
..and use for both virtio-user-blk and virtio-user-gpio. This avoids the circular close by deferring shutdown due to disconnection until a later point. virtio-user-blk already had this mechanism in place so generalise it as a vhost-user helper function and use for both blk and gpio devices. While we are at it we also fix up vhost-user-gpio to re-establish the event handler after close down so we can reconnect later. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com> Message-Id: <20221130112439.2527228-5-alex.bennee@linaro.org> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
060f4a9440
commit
71e076a07d
4 changed files with 104 additions and 37 deletions
|
@ -369,17 +369,10 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
|
|||
vhost_user_blk_stop(vdev);
|
||||
|
||||
vhost_dev_cleanup(&s->dev);
|
||||
}
|
||||
|
||||
static void vhost_user_blk_chr_closed_bh(void *opaque)
|
||||
{
|
||||
DeviceState *dev = opaque;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
||||
|
||||
vhost_user_blk_disconnect(dev);
|
||||
/* Re-instate the event handler for new connections */
|
||||
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
|
||||
NULL, opaque, NULL, true);
|
||||
NULL, dev, NULL, true);
|
||||
}
|
||||
|
||||
static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
|
||||
|
@ -398,33 +391,9 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
|
|||
}
|
||||
break;
|
||||
case CHR_EVENT_CLOSED:
|
||||
if (!runstate_check(RUN_STATE_SHUTDOWN)) {
|
||||
/*
|
||||
* A close event may happen during a read/write, but vhost
|
||||
* code assumes the vhost_dev remains setup, so delay the
|
||||
* stop & clear.
|
||||
*/
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
|
||||
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, false);
|
||||
aio_bh_schedule_oneshot(ctx, vhost_user_blk_chr_closed_bh, opaque);
|
||||
|
||||
/*
|
||||
* Move vhost device to the stopped state. The vhost-user device
|
||||
* will be clean up and disconnected in BH. This can be useful in
|
||||
* the vhost migration code. If disconnect was caught there is an
|
||||
* option for the general vhost code to get the dev state without
|
||||
* knowing its type (in this case vhost-user).
|
||||
*
|
||||
* FIXME: this is sketchy to be reaching into vhost_dev
|
||||
* now because we are forcing something that implies we
|
||||
* have executed vhost_dev_stop() but that won't happen
|
||||
* until vhost_user_blk_stop() gets called from the bh.
|
||||
* Really this state check should be tracked locally.
|
||||
*/
|
||||
s->dev.started = false;
|
||||
}
|
||||
/* defer close until later to avoid circular close */
|
||||
vhost_user_async_close(dev, &s->chardev, &s->dev,
|
||||
vhost_user_blk_disconnect);
|
||||
break;
|
||||
case CHR_EVENT_BREAK:
|
||||
case CHR_EVENT_MUX_IN:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue