From patchwork Fri Sep 29 10:38:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 132203 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C385642672; Fri, 29 Sep 2023 12:38:17 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5A598402AA; Fri, 29 Sep 2023 12:38:17 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 5436540287 for ; Fri, 29 Sep 2023 12:38:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1695983894; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=SCrUCEi5yrJXCVO3IVyAOt7Xhfs8Nzsfv3n7FycQH7A=; b=c8GQmPv3rNt9VRADixnlgxYU0YMj5ZO76I5EHC54d75zPoJM5tv83FdR9BQbanabIm+oCr NJZq+SbVF5SGOvkUHQ5Zm9SBM+VhfuPUzMnmFa1YOGAH6cDXgYd3hGymwNeyMzBDYPHOom tUo2qkKY/y0s1OoC0xZBrsf8mTAjmYk= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-528-3ypJ8gNDP--7kS1sNGEE9Q-1; Fri, 29 Sep 2023 06:38:12 -0400 X-MC-Unique: 3ypJ8gNDP--7kS1sNGEE9Q-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4070B1C068DC; Fri, 29 Sep 2023 10:38:12 +0000 (UTC) Received: from max-p1.redhat.com (unknown [10.39.208.41]) by smtp.corp.redhat.com (Postfix) with ESMTP id 164D3C15BB8; Fri, 29 Sep 2023 10:38:10 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, david.marchand@redhat.com, echaudro@redhat.com, chenbo.xia@outlook.com Cc: Maxime Coquelin Subject: [PATCH v3] vhost: add IRQ suppression Date: Fri, 29 Sep 2023 12:38:09 +0200 Message-ID: <20230929103809.765417-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Guest notifications offloading, which has been introduced in v23.07, aims at offloading syscalls out of the datapath. This patch optimizes the offloading by not offloading the guest notification for a given virtqueue if one is already being offloaded by the application. With a single VDUSE device, we can already see few notifications being suppressed when doing throughput testing with Iperf3. We can expect to see much more being suppressed when the offloading thread is under pressure. Signed-off-by: Maxime Coquelin Acked-by: Eelco Chaudron Reviewed-by: David Marchand --- v3: s/0/false/ (David) lib/vhost/vhost.c | 4 ++++ lib/vhost/vhost.h | 27 +++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) -- 2.41.0 diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index c03bb9c6eb..7fde412ef3 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -49,6 +49,8 @@ static const struct vhost_vq_stats_name_off vhost_vq_stat_strings[] = { stats.guest_notifications_offloaded)}, {"guest_notifications_error", offsetof(struct vhost_virtqueue, stats.guest_notifications_error)}, + {"guest_notifications_suppressed", offsetof(struct vhost_virtqueue, + stats.guest_notifications_suppressed)}, {"iotlb_hits", offsetof(struct vhost_virtqueue, stats.iotlb_hits)}, {"iotlb_misses", offsetof(struct vhost_virtqueue, stats.iotlb_misses)}, {"inflight_submitted", offsetof(struct vhost_virtqueue, stats.inflight_submitted)}, @@ -1517,6 +1519,8 @@ rte_vhost_notify_guest(int vid, uint16_t queue_id) rte_rwlock_read_lock(&vq->access_lock); + __atomic_store_n(&vq->irq_pending, false, __ATOMIC_RELEASE); + if (dev->backend_ops->inject_irq(dev, vq)) { if (dev->flags & VIRTIO_DEV_STATS_ENABLED) __atomic_fetch_add(&vq->stats.guest_notifications_error, diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h index 9723429b1c..5fc9035a1f 100644 --- a/lib/vhost/vhost.h +++ b/lib/vhost/vhost.h @@ -156,6 +156,7 @@ struct virtqueue_stats { uint64_t iotlb_misses; uint64_t inflight_submitted; uint64_t inflight_completed; + uint64_t guest_notifications_suppressed; /* Counters below are atomic, and should be incremented as such. */ uint64_t guest_notifications; uint64_t guest_notifications_offloaded; @@ -346,6 +347,8 @@ struct vhost_virtqueue { struct vhost_vring_addr ring_addrs; struct virtqueue_stats stats; + + bool irq_pending; } __rte_cache_aligned; /* Virtio device status as per Virtio specification */ @@ -908,12 +911,24 @@ vhost_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old) static __rte_always_inline void vhost_vring_inject_irq(struct virtio_net *dev, struct vhost_virtqueue *vq) { - if (dev->notify_ops->guest_notify && - dev->notify_ops->guest_notify(dev->vid, vq->index)) { - if (dev->flags & VIRTIO_DEV_STATS_ENABLED) - __atomic_fetch_add(&vq->stats.guest_notifications_offloaded, - 1, __ATOMIC_RELAXED); - return; + bool expected = false; + + if (dev->notify_ops->guest_notify) { + if (__atomic_compare_exchange_n(&vq->irq_pending, &expected, true, 0, + __ATOMIC_RELEASE, __ATOMIC_RELAXED)) { + if (dev->notify_ops->guest_notify(dev->vid, vq->index)) { + if (dev->flags & VIRTIO_DEV_STATS_ENABLED) + __atomic_fetch_add(&vq->stats.guest_notifications_offloaded, + 1, __ATOMIC_RELAXED); + return; + } + + /* Offloading failed, fallback to direct IRQ injection */ + __atomic_store_n(&vq->irq_pending, false, __ATOMIC_RELEASE); + } else { + vq->stats.guest_notifications_suppressed++; + return; + } } if (dev->backend_ops->inject_irq(dev, vq)) {