]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Do not poll ioeventfd if vhost is enabled
authorAsias He <asias.hejun@gmail.com>
Wed, 11 Jul 2012 16:08:14 +0000 (00:08 +0800)
committerPekka Enberg <penberg@kernel.org>
Thu, 12 Jul 2012 07:09:34 +0000 (10:09 +0300)
If vhost is enabled for a virtio device, vhost will poll the ioeventfd
in kernel side and there is no need to poll it in userspace. Otherwise,
both vhost kernel and userspace will race to poll.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/include/kvm/ioeventfd.h
tools/kvm/include/kvm/virtio.h
tools/kvm/ioeventfd.c
tools/kvm/virtio/mmio.c
tools/kvm/virtio/net.c
tools/kvm/virtio/pci.c

index 70cce9aa4304086c014f1d323dd98e7f9a91ca30..d71fa4066eb92a63470d9a7dc246c3b5fed05ed5 100644 (file)
@@ -22,7 +22,7 @@ struct ioevent {
 
 int ioeventfd__init(struct kvm *kvm);
 int ioeventfd__exit(struct kvm *kvm);
-int ioeventfd__add_event(struct ioevent *ioevent, bool is_pio);
+int ioeventfd__add_event(struct ioevent *ioevent, bool is_pio, bool poll_in_userspace);
 int ioeventfd__del_event(u64 addr, u64 datamatch);
 
 #endif
index a957a5bd3213778f6052a09fd5ff5f3ec37cd96c..71b6bad1df79cbf8aa5fcd1473ee380af4db71d9 100644 (file)
@@ -72,6 +72,7 @@ enum virtio_trans {
 };
 
 struct virtio_device {
+       bool                    use_vhost;
        void                    *virtio;
        struct virtio_ops       *ops;
 };
index 97deb06cb2f8a9cae4712c80d4416bd669a3e8e9..226876fce2adfe132bcf96f801a354ae8fbbc862 100644 (file)
@@ -117,7 +117,7 @@ int ioeventfd__exit(struct kvm *kvm)
        return 0;
 }
 
-int ioeventfd__add_event(struct ioevent *ioevent, bool is_pio)
+int ioeventfd__add_event(struct ioevent *ioevent, bool is_pio, bool poll_in_userspace)
 {
        struct kvm_ioeventfd kvm_ioevent;
        struct epoll_event epoll_event;
@@ -151,6 +151,9 @@ int ioeventfd__add_event(struct ioevent *ioevent, bool is_pio)
                goto cleanup;
        }
 
+       if (!poll_in_userspace)
+               return 0;
+
        epoll_event = (struct epoll_event) {
                .events         = EPOLLIN,
                .data.ptr       = new_ioevent,
index 831995477941ba78910c2e15371e837f54faeba1..1cf081512971ba8da8296a4bcbf7877ec4e2dc8e 100644 (file)
@@ -48,7 +48,15 @@ static int virtio_mmio_init_ioeventfd(struct kvm *kvm,
                .fd             = eventfd(0, 0),
        };
 
-       err = ioeventfd__add_event(&ioevent, false);
+       if (vdev->use_vhost)
+               /*
+                * Vhost will poll the eventfd in host kernel side,
+                * no need to poll in userspace.
+                */
+               err = ioeventfd__add_event(&ioevent, true, false);
+       else
+               /* Need to poll in userspace. */
+               err = ioeventfd__add_event(&ioevent, true, true);
        if (err)
                return err;
 
index aa769d95e56f3e7031b3318b26a22a9c8c2003be..10420ae5aad190ee590e0c03cc16a8086274029a 100644 (file)
@@ -492,6 +492,9 @@ static void virtio_net__vhost_init(struct kvm *kvm, struct net_dev *ndev)
        r = ioctl(ndev->vhost_fd, VHOST_SET_MEM_TABLE, mem);
        if (r != 0)
                die_perror("VHOST_SET_MEM_TABLE failed");
+
+       ndev->vdev.use_vhost = true;
+
        free(mem);
 }
 
index 8558341e70f434fa475804f1ec3ae70c4cf0c229..f17cd8aff80af13365a335160d594ebc5137c224 100644 (file)
@@ -40,7 +40,15 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde
                .fd             = eventfd(0, 0),
        };
 
-       r = ioeventfd__add_event(&ioevent, true);
+       if (vdev->use_vhost)
+               /*
+                * Vhost will poll the eventfd in host kernel side,
+                * no need to poll in userspace.
+                */
+               r = ioeventfd__add_event(&ioevent, true, false);
+       else
+               /* Need to poll in userspace. */
+               r = ioeventfd__add_event(&ioevent, true, true);
        if (r)
                return r;