vhost: allow per device message handler

This patch allow device to register its own message handler during
vhost_dev_init(). vDPA device will use it to implement its own DMA
mapping logic.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Link: https://lore.kernel.org/r/20200326140125.19794-3-jasowang@redhat.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Jason Wang 2020-03-26 22:01:18 +08:00 committed by Michael S. Tsirkin
parent 20c384f1ea
commit 792a4f2ed2
5 changed files with 19 additions and 6 deletions

View File

@ -1324,7 +1324,8 @@ static int vhost_net_open(struct inode *inode, struct file *f)
} }
vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX, vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX,
UIO_MAXIOV + VHOST_NET_BATCH, UIO_MAXIOV + VHOST_NET_BATCH,
VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT); VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT,
NULL);
vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, EPOLLOUT, dev); vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, EPOLLOUT, dev);
vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, EPOLLIN, dev); vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, EPOLLIN, dev);

View File

@ -1628,7 +1628,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick; vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
} }
vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV, vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV,
VHOST_SCSI_WEIGHT, 0); VHOST_SCSI_WEIGHT, 0, NULL);
vhost_scsi_init_inflight(vs, NULL); vhost_scsi_init_inflight(vs, NULL);

View File

@ -457,7 +457,9 @@ static size_t vhost_get_desc_size(struct vhost_virtqueue *vq,
void vhost_dev_init(struct vhost_dev *dev, void vhost_dev_init(struct vhost_dev *dev,
struct vhost_virtqueue **vqs, int nvqs, struct vhost_virtqueue **vqs, int nvqs,
int iov_limit, int weight, int byte_weight) int iov_limit, int weight, int byte_weight,
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg))
{ {
struct vhost_virtqueue *vq; struct vhost_virtqueue *vq;
int i; int i;
@ -473,6 +475,7 @@ void vhost_dev_init(struct vhost_dev *dev,
dev->iov_limit = iov_limit; dev->iov_limit = iov_limit;
dev->weight = weight; dev->weight = weight;
dev->byte_weight = byte_weight; dev->byte_weight = byte_weight;
dev->msg_handler = msg_handler;
init_llist_head(&dev->work_list); init_llist_head(&dev->work_list);
init_waitqueue_head(&dev->wait); init_waitqueue_head(&dev->wait);
INIT_LIST_HEAD(&dev->read_list); INIT_LIST_HEAD(&dev->read_list);
@ -1178,7 +1181,12 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
} }
if (vhost_process_iotlb_msg(dev, &msg)) {
if (dev->msg_handler)
ret = dev->msg_handler(dev, &msg);
else
ret = vhost_process_iotlb_msg(dev, &msg);
if (ret) {
ret = -EFAULT; ret = -EFAULT;
goto done; goto done;
} }

View File

@ -174,11 +174,15 @@ struct vhost_dev {
int weight; int weight;
int byte_weight; int byte_weight;
u64 kcov_handle; u64 kcov_handle;
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg);
}; };
bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len); bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len);
void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs,
int nvqs, int iov_limit, int weight, int byte_weight); int nvqs, int iov_limit, int weight, int byte_weight,
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg));
long vhost_dev_set_owner(struct vhost_dev *dev); long vhost_dev_set_owner(struct vhost_dev *dev);
bool vhost_dev_has_owner(struct vhost_dev *dev); bool vhost_dev_has_owner(struct vhost_dev *dev);
long vhost_dev_check_owner(struct vhost_dev *); long vhost_dev_check_owner(struct vhost_dev *);

View File

@ -621,7 +621,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs), vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs),
UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT, UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT,
VHOST_VSOCK_WEIGHT); VHOST_VSOCK_WEIGHT, NULL);
file->private_data = vsock; file->private_data = vsock;
spin_lock_init(&vsock->send_pkt_list_lock); spin_lock_init(&vsock->send_pkt_list_lock);