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
};
struct virtio_device {
+ bool use_vhost;
void *virtio;
struct virtio_ops *ops;
};
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;
goto cleanup;
}
+ if (!poll_in_userspace)
+ return 0;
+
epoll_event = (struct epoll_event) {
.events = EPOLLIN,
.data.ptr = new_ioevent,
.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;
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);
}
.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;