vhost: add device opr when notification to guest is sent

Message ID 25d9aeb9ba061b45d394081cc0cc7a347f7dfb2e.1567003335.git.echaudro@redhat.com (mailing list archive)
State Accepted, archived
Delegated to: Maxime Coquelin
Headers
Series vhost: add device opr when notification to guest is sent |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-dpdk_compile_ovs success Compile Testing PASS
ci/iol-dpdk_compile success Compile Testing PASS
ci/iol-dpdk_compile_spdk success Compile Testing PASS
ci/intel-Performance success Performance Testing PASS
ci/mellanox-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK

Commit Message

Eelco Chaudron Aug. 28, 2019, 2:49 p.m. UTC
  This patch adds an operation callback which gets called every time
the library is waking up the guest trough an eventfd_write() call.

This can be used by 3rd party application, like OVS, to track the
number of times interrupts where generated. This might be of
interest to find out system-call were called in the fast path.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
---
 lib/librte_vhost/rte_vhost.h | 10 +++++++++-
 lib/librte_vhost/vhost.h     | 15 ++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)
  

Comments

Maxime Coquelin Sept. 6, 2019, 4:27 p.m. UTC | #1
Hi Eelco,

On 8/28/19 4:49 PM, Eelco Chaudron wrote:
> This patch adds an operation callback which gets called every time
> the library is waking up the guest trough an eventfd_write() call.
> 
> This can be used by 3rd party application, like OVS, to track the
> number of times interrupts where generated. This might be of
> interest to find out system-call were called in the fast path.
> 
> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
> ---
>  lib/librte_vhost/rte_vhost.h | 10 +++++++++-
>  lib/librte_vhost/vhost.h     | 15 ++++++++++++---
>  2 files changed, 21 insertions(+), 4 deletions(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks!
Maxime
  
Maxime Coquelin Sept. 18, 2019, 1:11 p.m. UTC | #2
On 8/28/19 4:49 PM, Eelco Chaudron wrote:
> This patch adds an operation callback which gets called every time
> the library is waking up the guest trough an eventfd_write() call.
> 
> This can be used by 3rd party application, like OVS, to track the
> number of times interrupts where generated. This might be of
> interest to find out system-call were called in the fast path.
> 
> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
> ---
>  lib/librte_vhost/rte_vhost.h | 10 +++++++++-
>  lib/librte_vhost/vhost.h     | 15 ++++++++++++---
>  2 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index 7fb1729..878e339 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -172,7 +172,15 @@ struct vhost_device_ops {
>  	int (*new_connection)(int vid);
>  	void (*destroy_connection)(int vid);
>  
> -	void *reserved[2]; /**< Reserved for future extension */
> +	/**
> +	 * This callback gets called each time a guest gets notified
> +	 * about waiting packets. This is the interrupt handling trough
> +	 * the eventfd_write(callfd), which can be used for counting these
> +	 * "slow" syscalls.
> +	 */
> +	void (*guest_notified)(int vid);
> +
> +	void *reserved[1]; /**< Reserved for future extension */
>  };
>  
>  /**
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index 884befa..5131a97 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -543,13 +543,19 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
>  
>  		if ((vhost_need_event(vhost_used_event(vq), new, old) &&
>  					(vq->callfd >= 0)) ||
> -				unlikely(!signalled_used_valid))
> +				unlikely(!signalled_used_valid)) {
>  			eventfd_write(vq->callfd, (eventfd_t) 1);
> +			if (dev->notify_ops->guest_notified)
> +				dev->notify_ops->guest_notified(dev->vid);
> +		}
>  	} else {
>  		/* Kick the guest if necessary. */
>  		if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
> -				&& (vq->callfd >= 0))
> +				&& (vq->callfd >= 0)) {
>  			eventfd_write(vq->callfd, (eventfd_t)1);
> +			if (dev->notify_ops->guest_notified)
> +				dev->notify_ops->guest_notified(dev->vid);
> +		}
>  	}
>  }
>  
> @@ -600,8 +606,11 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
>  	if (vhost_need_event(off, new, old))
>  		kick = true;
>  kick:
> -	if (kick)
> +	if (kick) {
>  		eventfd_write(vq->callfd, (eventfd_t)1);
> +		if (dev->notify_ops->guest_notified)
> +			dev->notify_ops->guest_notified(dev->vid);
> +	}
>  }
>  
>  static __rte_always_inline void
> 

Applied to dpdk-next-virtio/master.

Thanks,
Maxime
  

Patch

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 7fb1729..878e339 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -172,7 +172,15 @@  struct vhost_device_ops {
 	int (*new_connection)(int vid);
 	void (*destroy_connection)(int vid);
 
-	void *reserved[2]; /**< Reserved for future extension */
+	/**
+	 * This callback gets called each time a guest gets notified
+	 * about waiting packets. This is the interrupt handling trough
+	 * the eventfd_write(callfd), which can be used for counting these
+	 * "slow" syscalls.
+	 */
+	void (*guest_notified)(int vid);
+
+	void *reserved[1]; /**< Reserved for future extension */
 };
 
 /**
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 884befa..5131a97 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -543,13 +543,19 @@  void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
 
 		if ((vhost_need_event(vhost_used_event(vq), new, old) &&
 					(vq->callfd >= 0)) ||
-				unlikely(!signalled_used_valid))
+				unlikely(!signalled_used_valid)) {
 			eventfd_write(vq->callfd, (eventfd_t) 1);
+			if (dev->notify_ops->guest_notified)
+				dev->notify_ops->guest_notified(dev->vid);
+		}
 	} else {
 		/* Kick the guest if necessary. */
 		if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
-				&& (vq->callfd >= 0))
+				&& (vq->callfd >= 0)) {
 			eventfd_write(vq->callfd, (eventfd_t)1);
+			if (dev->notify_ops->guest_notified)
+				dev->notify_ops->guest_notified(dev->vid);
+		}
 	}
 }
 
@@ -600,8 +606,11 @@  void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
 	if (vhost_need_event(off, new, old))
 		kick = true;
 kick:
-	if (kick)
+	if (kick) {
 		eventfd_write(vq->callfd, (eventfd_t)1);
+		if (dev->notify_ops->guest_notified)
+			dev->notify_ops->guest_notified(dev->vid);
+	}
 }
 
 static __rte_always_inline void