vhost-user: Interface for migration state transfer

Add the interface for transferring the back-end's state during migration
as defined previously in vhost-user.rst.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20231016134243.68248-6-hreitz@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Hanna Czenczek
2023-10-16 15:42:41 +02:00
committed by Michael S. Tsirkin
parent 019233096c
commit cda83adc62
5 changed files with 286 additions and 0 deletions

View File

@@ -26,6 +26,18 @@ typedef enum VhostSetConfigType {
VHOST_SET_CONFIG_TYPE_MIGRATION = 1,
} VhostSetConfigType;
typedef enum VhostDeviceStateDirection {
/* Transfer state from back-end (device) to front-end */
VHOST_TRANSFER_STATE_DIRECTION_SAVE = 0,
/* Transfer state from front-end to back-end (device) */
VHOST_TRANSFER_STATE_DIRECTION_LOAD = 1,
} VhostDeviceStateDirection;
typedef enum VhostDeviceStatePhase {
/* The device (and all its vrings) is stopped */
VHOST_TRANSFER_STATE_PHASE_STOPPED = 0,
} VhostDeviceStatePhase;
struct vhost_inflight;
struct vhost_dev;
struct vhost_log;
@@ -129,6 +141,15 @@ typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
typedef void (*vhost_reset_status_op)(struct vhost_dev *dev);
typedef bool (*vhost_supports_device_state_op)(struct vhost_dev *dev);
typedef int (*vhost_set_device_state_fd_op)(struct vhost_dev *dev,
VhostDeviceStateDirection direction,
VhostDeviceStatePhase phase,
int fd,
int *reply_fd,
Error **errp);
typedef int (*vhost_check_device_state_op)(struct vhost_dev *dev, Error **errp);
typedef struct VhostOps {
VhostBackendType backend_type;
vhost_backend_init vhost_backend_init;
@@ -176,6 +197,9 @@ typedef struct VhostOps {
vhost_force_iommu_op vhost_force_iommu;
vhost_set_config_call_op vhost_set_config_call;
vhost_reset_status_op vhost_reset_status;
vhost_supports_device_state_op vhost_supports_device_state;
vhost_set_device_state_fd_op vhost_set_device_state_fd;
vhost_check_device_state_op vhost_check_device_state;
} VhostOps;
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,

View File

@@ -31,6 +31,7 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_STATUS = 16,
/* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */
VHOST_USER_PROTOCOL_F_SHARED_OBJECT = 18,
VHOST_USER_PROTOCOL_F_DEVICE_STATE = 19,
VHOST_USER_PROTOCOL_F_MAX
};

View File

@@ -351,4 +351,82 @@ static inline int vhost_reset_device(struct vhost_dev *hdev)
}
#endif /* CONFIG_VHOST */
/**
* vhost_supports_device_state(): Checks whether the back-end supports
* transferring internal device state for the purpose of migration.
* Support for this feature is required for vhost_set_device_state_fd()
* and vhost_check_device_state().
*
* @dev: The vhost device
*
* Returns true if the device supports these commands, and false if it
* does not.
*/
bool vhost_supports_device_state(struct vhost_dev *dev);
/**
* vhost_set_device_state_fd(): Begin transfer of internal state from/to
* the back-end for the purpose of migration. Data is to be transferred
* over a pipe according to @direction and @phase. The sending end must
* only write to the pipe, and the receiving end must only read from it.
* Once the sending end is done, it closes its FD. The receiving end
* must take this as the end-of-transfer signal and close its FD, too.
*
* @fd is the back-end's end of the pipe: The write FD for SAVE, and the
* read FD for LOAD. This function transfers ownership of @fd to the
* back-end, i.e. closes it in the front-end.
*
* The back-end may optionally reply with an FD of its own, if this
* improves efficiency on its end. In this case, the returned FD is
* stored in *reply_fd. The back-end will discard the FD sent to it,
* and the front-end must use *reply_fd for transferring state to/from
* the back-end.
*
* @dev: The vhost device
* @direction: The direction in which the state is to be transferred.
* For outgoing migrations, this is SAVE, and data is read
* from the back-end and stored by the front-end in the
* migration stream.
* For incoming migrations, this is LOAD, and data is read
* by the front-end from the migration stream and sent to
* the back-end to restore the saved state.
* @phase: Which migration phase we are in. Currently, there is only
* STOPPED (device and all vrings are stopped), in the future,
* more phases such as PRE_COPY or POST_COPY may be added.
* @fd: Back-end's end of the pipe through which to transfer state; note
* that ownership is transferred to the back-end, so this function
* closes @fd in the front-end.
* @reply_fd: If the back-end wishes to use a different pipe for state
* transfer, this will contain an FD for the front-end to
* use. Otherwise, -1 is stored here.
* @errp: Potential error description
*
* Returns 0 on success, and -errno on failure.
*/
int vhost_set_device_state_fd(struct vhost_dev *dev,
VhostDeviceStateDirection direction,
VhostDeviceStatePhase phase,
int fd,
int *reply_fd,
Error **errp);
/**
* vhost_set_device_state_fd(): After transferring state from/to the
* back-end via vhost_set_device_state_fd(), i.e. once the sending end
* has closed the pipe, inquire the back-end to report any potential
* errors that have occurred on its side. This allows to sense errors
* like:
* - During outgoing migration, when the source side had already started
* to produce its state, something went wrong and it failed to finish
* - During incoming migration, when the received state is somehow
* invalid and cannot be processed by the back-end
*
* @dev: The vhost device
* @errp: Potential error description
*
* Returns 0 when the back-end reports successful state transfer and
* processing, and -errno when an error occurred somewhere.
*/
int vhost_check_device_state(struct vhost_dev *dev, Error **errp);
#endif