vhost-vdpa: classify one time request

Vhost-vdpa uses one device multiqueue queue (pairs) model. So we need
to classify the one time request (e.g SET_OWNER) and make sure those
request were only called once per device.

This is used for multiqueue support.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20211020045600.16082-3-jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Jason Wang 2021-10-20 12:55:52 +08:00 committed by Michael S. Tsirkin
parent 7327813d17
commit 4d191cfdc7
2 changed files with 48 additions and 6 deletions

View File

@ -319,6 +319,13 @@ static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v)
v->iova_range.last); v->iova_range.last);
} }
static bool vhost_vdpa_one_time_request(struct vhost_dev *dev)
{
struct vhost_vdpa *v = dev->opaque;
return v->index != 0;
}
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
{ {
struct vhost_vdpa *v; struct vhost_vdpa *v;
@ -332,6 +339,11 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
v->msg_type = VHOST_IOTLB_MSG_V2; v->msg_type = VHOST_IOTLB_MSG_V2;
vhost_vdpa_get_iova_range(v); vhost_vdpa_get_iova_range(v);
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER); VIRTIO_CONFIG_S_DRIVER);
@ -442,6 +454,10 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
struct vhost_memory *mem) struct vhost_memory *mem)
{ {
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
trace_vhost_vdpa_set_mem_table(dev, mem->nregions, mem->padding); trace_vhost_vdpa_set_mem_table(dev, mem->nregions, mem->padding);
if (trace_event_get_state_backends(TRACE_VHOST_VDPA_SET_MEM_TABLE) && if (trace_event_get_state_backends(TRACE_VHOST_VDPA_SET_MEM_TABLE) &&
trace_event_get_state_backends(TRACE_VHOST_VDPA_DUMP_REGIONS)) { trace_event_get_state_backends(TRACE_VHOST_VDPA_DUMP_REGIONS)) {
@ -465,6 +481,11 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev,
uint64_t features) uint64_t features)
{ {
int ret; int ret;
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
trace_vhost_vdpa_set_features(dev, features); trace_vhost_vdpa_set_features(dev, features);
ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features); ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
uint8_t status = 0; uint8_t status = 0;
@ -489,9 +510,12 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
} }
features &= f; features &= f;
r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features);
if (r) { if (vhost_vdpa_one_time_request(dev)) {
return -EFAULT; r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features);
if (r) {
return -EFAULT;
}
} }
dev->backend_cap = features; dev->backend_cap = features;
@ -600,11 +624,21 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
{ {
struct vhost_vdpa *v = dev->opaque; struct vhost_vdpa *v = dev->opaque;
trace_vhost_vdpa_dev_start(dev, started); trace_vhost_vdpa_dev_start(dev, started);
if (started) {
vhost_vdpa_host_notifiers_init(dev);
vhost_vdpa_set_vring_ready(dev);
} else {
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
}
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
if (started) { if (started) {
uint8_t status = 0; uint8_t status = 0;
memory_listener_register(&v->listener, &address_space_memory); memory_listener_register(&v->listener, &address_space_memory);
vhost_vdpa_host_notifiers_init(dev);
vhost_vdpa_set_vring_ready(dev);
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status); vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
@ -613,7 +647,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
vhost_vdpa_reset_device(dev); vhost_vdpa_reset_device(dev);
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER); VIRTIO_CONFIG_S_DRIVER);
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
memory_listener_unregister(&v->listener); memory_listener_unregister(&v->listener);
return 0; return 0;
@ -623,6 +656,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
struct vhost_log *log) struct vhost_log *log)
{ {
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
trace_vhost_vdpa_set_log_base(dev, base, log->size, log->refcnt, log->fd, trace_vhost_vdpa_set_log_base(dev, base, log->size, log->refcnt, log->fd,
log->log); log->log);
return vhost_vdpa_call(dev, VHOST_SET_LOG_BASE, &base); return vhost_vdpa_call(dev, VHOST_SET_LOG_BASE, &base);
@ -688,6 +725,10 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev,
static int vhost_vdpa_set_owner(struct vhost_dev *dev) static int vhost_vdpa_set_owner(struct vhost_dev *dev)
{ {
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
trace_vhost_vdpa_set_owner(dev); trace_vhost_vdpa_set_owner(dev);
return vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL); return vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL);
} }

View File

@ -22,6 +22,7 @@ typedef struct VhostVDPAHostNotifier {
typedef struct vhost_vdpa { typedef struct vhost_vdpa {
int device_fd; int device_fd;
int index;
uint32_t msg_type; uint32_t msg_type;
bool iotlb_batch_begin_sent; bool iotlb_batch_begin_sent;
MemoryListener listener; MemoryListener listener;