mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
vhost/vsock: add VHOST_RESET_OWNER ioctl
This ioctl is needed for QEMU's CPR (checkpoint-restore) migration of
the guest with vhost-vsock device. For this to work, we need to reset
the device ownership on the source side by calling RESET_OWNER, and then
claim it on the dest side by calling SET_OWNER. We expect not to lose any
AF_VSOCK connection while this happens.
To that end, unlike the release path, RESET_OWNER keeps the guest CID
hashed: established connections survive, and host sends issued while
the device is between owners simply stay on send_pkt_queue until the
next device start drains them.
Since the device stays reachable through the CID hash, the lockless
send/cancel paths can race with the worker teardown in
vhost_workers_free(). The previous commit ("vhost: synchronize with
RCU readers when freeing workers") makes that safe.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260724114542.734623-6-andrey.drobyshev@virtuozzo.com>
This commit is contained in:
parent
5efd97e6f0
commit
8f2c2fb94a
|
|
@ -905,6 +905,36 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
static long vhost_vsock_reset_owner(struct vhost_vsock *vsock)
|
||||
{
|
||||
struct vhost_iotlb *umem;
|
||||
long err;
|
||||
|
||||
mutex_lock(&vsock->dev.mutex);
|
||||
err = vhost_dev_check_owner(&vsock->dev);
|
||||
if (err)
|
||||
goto done;
|
||||
umem = vhost_dev_reset_owner_prepare();
|
||||
if (!umem) {
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
vhost_vsock_drop_backends(vsock);
|
||||
vhost_vsock_flush(vsock);
|
||||
vhost_dev_stop(&vsock->dev);
|
||||
|
||||
/*
|
||||
* vsock keeps the CID hashed across RESET_OWNER, so a lockless sender
|
||||
* can still reach the device while its workers are freed. Pass
|
||||
* sync=true so vhost_workers_free() fences RCU readers and flushes
|
||||
* before freeing them.
|
||||
*/
|
||||
vhost_dev_reset_owner(&vsock->dev, umem, true);
|
||||
done:
|
||||
mutex_unlock(&vsock->dev.mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
||||
unsigned long arg)
|
||||
{
|
||||
|
|
@ -948,6 +978,8 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
|
|||
return -EOPNOTSUPP;
|
||||
vhost_set_backend_features(&vsock->dev, features);
|
||||
return 0;
|
||||
case VHOST_RESET_OWNER:
|
||||
return vhost_vsock_reset_owner(vsock);
|
||||
default:
|
||||
mutex_lock(&vsock->dev.mutex);
|
||||
r = vhost_dev_ioctl(&vsock->dev, ioctl, argp);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user