Add VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS
This change introduces a new feature to the vhost-user protocol allowing a backend device to specify the maximum number of ram slots it supports. At this point, the value returned by the backend will be capped at the maximum number of ram slots which can be supported by vhost-user, which is currently set to 8 because of underlying protocol limitations. The returned value will be stored inside the VhostUserState struct so that on device reconnect we can verify that the ram slot limitation has not decreased since the last time the device connected. Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com> Signed-off-by: Peter Turschmid <peter.turschm@nutanix.com> Message-Id: <1588533678-23450-4-git-send-email-raphael.norwitz@nutanix.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
23374a84c5
commit
6b0eff1a4e
@ -815,6 +815,7 @@ Protocol features
|
|||||||
#define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
|
#define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
|
||||||
#define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
|
#define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
|
||||||
#define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
|
#define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
|
||||||
|
#define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS 15
|
||||||
|
|
||||||
Master message types
|
Master message types
|
||||||
--------------------
|
--------------------
|
||||||
@ -1263,6 +1264,21 @@ Master message types
|
|||||||
|
|
||||||
The state.num field is currently reserved and must be set to 0.
|
The state.num field is currently reserved and must be set to 0.
|
||||||
|
|
||||||
|
``VHOST_USER_GET_MAX_MEM_SLOTS``
|
||||||
|
:id: 36
|
||||||
|
:equivalent ioctl: N/A
|
||||||
|
:slave payload: u64
|
||||||
|
|
||||||
|
When the ``VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS`` protocol
|
||||||
|
feature has been successfully negotiated, this message is submitted
|
||||||
|
by master to the slave. The slave should return the message with a
|
||||||
|
u64 payload containing the maximum number of memory slots for
|
||||||
|
QEMU to expose to the guest. At this point, the value returned
|
||||||
|
by the backend will be capped at the maximum number of ram slots
|
||||||
|
which can be supported by vhost-user. Currently that limit is set
|
||||||
|
at VHOST_USER_MAX_RAM_SLOTS = 8 because of underlying protocol
|
||||||
|
limitations.
|
||||||
|
|
||||||
Slave message types
|
Slave message types
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ enum VhostUserProtocolFeature {
|
|||||||
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
||||||
VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
|
VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12,
|
||||||
VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
|
VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
|
||||||
|
/* Feature 14 reserved for VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS. */
|
||||||
|
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
|
||||||
VHOST_USER_PROTOCOL_F_MAX
|
VHOST_USER_PROTOCOL_F_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,6 +102,8 @@ typedef enum VhostUserRequest {
|
|||||||
VHOST_USER_SET_INFLIGHT_FD = 32,
|
VHOST_USER_SET_INFLIGHT_FD = 32,
|
||||||
VHOST_USER_GPU_SET_SOCKET = 33,
|
VHOST_USER_GPU_SET_SOCKET = 33,
|
||||||
VHOST_USER_RESET_DEVICE = 34,
|
VHOST_USER_RESET_DEVICE = 34,
|
||||||
|
/* Message number 35 reserved for VHOST_USER_VRING_KICK. */
|
||||||
|
VHOST_USER_GET_MAX_MEM_SLOTS = 36,
|
||||||
VHOST_USER_MAX
|
VHOST_USER_MAX
|
||||||
} VhostUserRequest;
|
} VhostUserRequest;
|
||||||
|
|
||||||
@ -895,6 +899,23 @@ static int vhost_user_set_owner(struct vhost_dev *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vhost_user_get_max_memslots(struct vhost_dev *dev,
|
||||||
|
uint64_t *max_memslots)
|
||||||
|
{
|
||||||
|
uint64_t backend_max_memslots;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = vhost_user_get_u64(dev, VHOST_USER_GET_MAX_MEM_SLOTS,
|
||||||
|
&backend_max_memslots);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*max_memslots = backend_max_memslots;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int vhost_user_reset_device(struct vhost_dev *dev)
|
static int vhost_user_reset_device(struct vhost_dev *dev)
|
||||||
{
|
{
|
||||||
VhostUserMsg msg = {
|
VhostUserMsg msg = {
|
||||||
@ -1392,7 +1413,7 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
|
|||||||
|
|
||||||
static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
|
static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
|
||||||
{
|
{
|
||||||
uint64_t features, protocol_features;
|
uint64_t features, protocol_features, ram_slots;
|
||||||
struct vhost_user *u;
|
struct vhost_user *u;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -1454,6 +1475,27 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
|
|||||||
"slave-req protocol features.");
|
"slave-req protocol features.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get max memory regions if backend supports configurable RAM slots */
|
||||||
|
if (!virtio_has_feature(dev->protocol_features,
|
||||||
|
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS)) {
|
||||||
|
u->user->memory_slots = VHOST_MEMORY_MAX_NREGIONS;
|
||||||
|
} else {
|
||||||
|
err = vhost_user_get_max_memslots(dev, &ram_slots);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ram_slots < u->user->memory_slots) {
|
||||||
|
error_report("The backend specified a max ram slots limit "
|
||||||
|
"of %" PRIu64", when the prior validated limit was %d. "
|
||||||
|
"This limit should never decrease.", ram_slots,
|
||||||
|
u->user->memory_slots);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->user->memory_slots = MIN(ram_slots, VHOST_MEMORY_MAX_NREGIONS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->migration_blocker == NULL &&
|
if (dev->migration_blocker == NULL &&
|
||||||
@ -1519,7 +1561,9 @@ static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
|
|||||||
|
|
||||||
static int vhost_user_memslots_limit(struct vhost_dev *dev)
|
static int vhost_user_memslots_limit(struct vhost_dev *dev)
|
||||||
{
|
{
|
||||||
return VHOST_MEMORY_MAX_NREGIONS;
|
struct vhost_user *u = dev->opaque;
|
||||||
|
|
||||||
|
return u->user->memory_slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
|
static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
|
||||||
@ -1904,6 +1948,7 @@ bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
user->chr = chr;
|
user->chr = chr;
|
||||||
|
user->memory_slots = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ typedef struct VhostUserHostNotifier {
|
|||||||
typedef struct VhostUserState {
|
typedef struct VhostUserState {
|
||||||
CharBackend *chr;
|
CharBackend *chr;
|
||||||
VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX];
|
VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX];
|
||||||
|
int memory_slots;
|
||||||
} VhostUserState;
|
} VhostUserState;
|
||||||
|
|
||||||
bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp);
|
bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp);
|
||||||
|
Loading…
Reference in New Issue
Block a user