vhost: allow per device message handler
authorJason Wang <jasowang@redhat.com>
Thu, 26 Mar 2020 14:01:18 +0000 (22:01 +0800)
committerMichael S. Tsirkin <mst@redhat.com>
Wed, 1 Apr 2020 16:06:26 +0000 (12:06 -0400)
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>
drivers/vhost/net.c
drivers/vhost/scsi.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/vhost/vsock.c

index 18e205e..7b1d2df 100644 (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,
                       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_RX, handle_rx_net, EPOLLIN, dev);
index 0b949a1..7653667 100644 (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;
        }
        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);
 
index f44340b..8e9e234 100644 (file)
@@ -457,7 +457,9 @@ static size_t vhost_get_desc_size(struct vhost_virtqueue *vq,
 
 void vhost_dev_init(struct vhost_dev *dev,
                    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;
        int i;
@@ -473,6 +475,7 @@ void vhost_dev_init(struct vhost_dev *dev,
        dev->iov_limit = iov_limit;
        dev->weight = weight;
        dev->byte_weight = byte_weight;
+       dev->msg_handler = msg_handler;
        init_llist_head(&dev->work_list);
        init_waitqueue_head(&dev->wait);
        INIT_LIST_HEAD(&dev->read_list);
@@ -1178,7 +1181,12 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
                ret = -EINVAL;
                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;
                goto done;
        }
index a123fd7..f9d1a03 100644 (file)
@@ -174,11 +174,15 @@ struct vhost_dev {
        int weight;
        int byte_weight;
        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);
 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);
 bool vhost_dev_has_owner(struct vhost_dev *dev);
 long vhost_dev_check_owner(struct vhost_dev *);
index c2d7d57..9766948 100644 (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),
                       UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT,
-                      VHOST_VSOCK_WEIGHT);
+                      VHOST_VSOCK_WEIGHT, NULL);
 
        file->private_data = vsock;
        spin_lock_init(&vsock->send_pkt_list_lock);