Re: [PATCH kvmtool 04/16] virtio/vhost: Factor notify_vq_gsi()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 19 Apr 2023 14:21:08 +0100
Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx> wrote:

Hi,

> All vhost devices should perform the same operations when initializing
> the IRQFD. Move it to virtio/vhost.c
> 
> This fixes vsock, which didn't go through the irq__add_irqfd() helper
> and couldn't be used on systems that require GSI translation (GICv2m).
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
> ---
>  include/kvm/virtio.h |  8 ++++++++
>  virtio/net.c         | 30 ++++--------------------------
>  virtio/scsi.c        | 15 ++-------------
>  virtio/vhost.c       | 35 +++++++++++++++++++++++++++++++++++
>  virtio/vsock.c       | 26 +++-----------------------
>  5 files changed, 52 insertions(+), 62 deletions(-)
> 
> diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h
> index 4a364a02..96c7b3ea 100644
> --- a/include/kvm/virtio.h
> +++ b/include/kvm/virtio.h
> @@ -77,6 +77,10 @@ struct virt_queue {
>  	u16		endian;
>  	bool		use_event_idx;
>  	bool		enabled;
> +
> +	/* vhost IRQ handling */
> +	int		gsi;
> +	int		irqfd;
>  };
>  
>  /*
> @@ -252,6 +256,10 @@ void virtio_vhost_set_vring(struct kvm *kvm, int vhost_fd, u32 index,
>  			    struct virt_queue *queue);
>  void virtio_vhost_set_vring_kick(struct kvm *kvm, int vhost_fd,
>  				 u32 index, int event_fd);
> +void virtio_vhost_set_vring_call(struct kvm *kvm, int vhost_fd, u32 index,
> +				 u32 gsi, struct virt_queue *queue);
> +void virtio_vhost_reset_vring(struct kvm *kvm, int vhost_fd, u32 index,
> +			      struct virt_queue *queue);
>  
>  int virtio_transport_parser(const struct option *opt, const char *arg, int unset);
>  
> diff --git a/virtio/net.c b/virtio/net.c
> index b935d24f..519dcbb7 100644
> --- a/virtio/net.c
> +++ b/virtio/net.c
> @@ -4,12 +4,12 @@
>  #include "kvm/mutex.h"
>  #include "kvm/util.h"
>  #include "kvm/kvm.h"
> -#include "kvm/irq.h"
>  #include "kvm/uip.h"
>  #include "kvm/guest_compat.h"
>  #include "kvm/iovec.h"
>  #include "kvm/strbuf.h"
>  
> +#include <linux/list.h>
>  #include <linux/vhost.h>
>  #include <linux/virtio_net.h>
>  #include <linux/if_tun.h>
> @@ -25,7 +25,6 @@
>  #include <sys/ioctl.h>
>  #include <sys/types.h>
>  #include <sys/wait.h>
> -#include <sys/eventfd.h>
>  
>  #define VIRTIO_NET_QUEUE_SIZE		256
>  #define VIRTIO_NET_NUM_QUEUES		8
> @@ -44,8 +43,6 @@ struct net_dev_queue {
>  	pthread_t			thread;
>  	struct mutex			lock;
>  	pthread_cond_t			cond;
> -	int				gsi;
> -	int				irqfd;
>  };
>  
>  struct net_dev {
> @@ -647,11 +644,7 @@ static void exit_vq(struct kvm *kvm, void *dev, u32 vq)
>  	struct net_dev *ndev = dev;
>  	struct net_dev_queue *queue = &ndev->queues[vq];
>  
> -	if (!is_ctrl_vq(ndev, vq) && queue->gsi) {

So this first condition here seems to be lost in the transformation. Is
or was that never needed?

Apart from that the changes look fine.

Cheers,
Andre

> -		irq__del_irqfd(kvm, queue->gsi, queue->irqfd);
> -		close(queue->irqfd);
> -		queue->gsi = queue->irqfd = 0;
> -	}
> +	virtio_vhost_reset_vring(kvm, ndev->vhost_fd, vq, &queue->vq);
>  
>  	/*
>  	 * TODO: vhost reset owner. It's the only way to cleanly stop vhost, but
> @@ -675,27 +668,12 @@ static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi)
>  {
>  	struct net_dev *ndev = dev;
>  	struct net_dev_queue *queue = &ndev->queues[vq];
> -	struct vhost_vring_file file;
> -	int r;
>  
>  	if (ndev->vhost_fd == 0)
>  		return;
>  
> -	file = (struct vhost_vring_file) {
> -		.index	= vq,
> -		.fd	= eventfd(0, 0),
> -	};
> -
> -	r = irq__add_irqfd(kvm, gsi, file.fd, -1);
> -	if (r < 0)
> -		die_perror("KVM_IRQFD failed");
> -
> -	queue->irqfd = file.fd;
> -	queue->gsi = gsi;
> -
> -	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_CALL, &file);
> -	if (r < 0)
> -		die_perror("VHOST_SET_VRING_CALL failed");
> +	virtio_vhost_set_vring_call(kvm, ndev->vhost_fd, vq, gsi,
> +				    &queue->vq);
>  }
>  
>  static void notify_vq_eventfd(struct kvm *kvm, void *dev, u32 vq, u32 efd)
> diff --git a/virtio/scsi.c b/virtio/scsi.c
> index 1f757404..29acf57c 100644
> --- a/virtio/scsi.c
> +++ b/virtio/scsi.c
> @@ -92,25 +92,14 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq)
>  
>  static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi)
>  {
> -	struct vhost_vring_file file;
>  	struct scsi_dev *sdev = dev;
>  	int r;
>  
>  	if (sdev->vhost_fd == 0)
>  		return;
>  
> -	file = (struct vhost_vring_file) {
> -		.index	= vq,
> -		.fd	= eventfd(0, 0),
> -	};
> -
> -	r = irq__add_irqfd(kvm, gsi, file.fd, -1);
> -	if (r < 0)
> -		die_perror("KVM_IRQFD failed");
> -
> -	r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_CALL, &file);
> -	if (r < 0)
> -		die_perror("VHOST_SET_VRING_CALL failed");
> +	virtio_vhost_set_vring_call(kvm, sdev->vhost_fd, vq, gsi,
> +				    &sdev->vqs[vq]);
>  
>  	if (vq > 0)
>  		return;
> diff --git a/virtio/vhost.c b/virtio/vhost.c
> index 3acfd30a..cd83645c 100644
> --- a/virtio/vhost.c
> +++ b/virtio/vhost.c
> @@ -1,9 +1,12 @@
> +#include "kvm/irq.h"
>  #include "kvm/virtio.h"
>  
>  #include <linux/kvm.h>
>  #include <linux/vhost.h>
>  #include <linux/list.h>
>  
> +#include <sys/eventfd.h>
> +
>  void virtio_vhost_init(struct kvm *kvm, int vhost_fd)
>  {
>  	struct kvm_mem_bank *bank;
> @@ -79,3 +82,35 @@ void virtio_vhost_set_vring_kick(struct kvm *kvm, int vhost_fd,
>  	if (r < 0)
>  		die_perror("VHOST_SET_VRING_KICK failed");
>  }
> +
> +void virtio_vhost_set_vring_call(struct kvm *kvm, int vhost_fd, u32 index,
> +				 u32 gsi, struct virt_queue *queue)
> +{
> +	int r;
> +	struct vhost_vring_file file = {
> +		.index	= index,
> +		.fd	= eventfd(0, 0),
> +	};
> +
> +	r = irq__add_irqfd(kvm, gsi, file.fd, -1);
> +	if (r < 0)
> +		die_perror("KVM_IRQFD failed");
> +
> +	r = ioctl(vhost_fd, VHOST_SET_VRING_CALL, &file);
> +	if (r < 0)
> +		die_perror("VHOST_SET_VRING_CALL failed");
> +
> +	queue->irqfd = file.fd;
> +	queue->gsi = gsi;
> +}
> +
> +void virtio_vhost_reset_vring(struct kvm *kvm, int vhost_fd, u32 index,
> +			      struct virt_queue *queue)
> +
> +{
> +	if (queue->gsi) {
> +		irq__del_irqfd(kvm, queue->gsi, queue->irqfd);
> +		close(queue->irqfd);
> +		queue->gsi = queue->irqfd = 0;
> +	}
> +}
> diff --git a/virtio/vsock.c b/virtio/vsock.c
> index 0ada9e09..559fbaba 100644
> --- a/virtio/vsock.c
> +++ b/virtio/vsock.c
> @@ -131,33 +131,13 @@ static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size)
>  
>  static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi)
>  {
> -	struct vhost_vring_file file;
>  	struct vsock_dev *vdev = dev;
> -	struct kvm_irqfd irq;
> -	int r;
> -
> -	if (vdev->vhost_fd == -1)
> -		return;
>  
> -	if (is_event_vq(vq))
> +	if (vdev->vhost_fd == -1 || is_event_vq(vq))
>  		return;
>  
> -	irq = (struct kvm_irqfd) {
> -		.gsi	= gsi,
> -		.fd	= eventfd(0, 0),
> -	};
> -	file = (struct vhost_vring_file) {
> -		.index	= vq,
> -		.fd	= irq.fd,
> -	};
> -
> -	r = ioctl(kvm->vm_fd, KVM_IRQFD, &irq);
> -	if (r < 0)
> -		die_perror("KVM_IRQFD failed");
> -
> -	r = ioctl(vdev->vhost_fd, VHOST_SET_VRING_CALL, &file);
> -	if (r < 0)
> -		die_perror("VHOST_SET_VRING_CALL failed");
> +	virtio_vhost_set_vring_call(kvm, vdev->vhost_fd, vq, gsi,
> +				    &vdev->vqs[vq]);
>  }
>  
>  static unsigned int get_vq_count(struct kvm *kvm, void *dev)




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux