From patchwork Thu Mar 23 15:44:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Traynor X-Patchwork-Id: 22186 X-Patchwork-Delegate: yuanhan.liu@linux.intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 93730695C; Thu, 23 Mar 2017 16:45:25 +0100 (CET) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 4CE941B53; Thu, 23 Mar 2017 16:45:24 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 95B7181F03; Thu, 23 Mar 2017 15:45:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 95B7181F03 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ktraynor@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 95B7181F03 Received: from ktraynor.remote.csb (ovpn-117-97.ams2.redhat.com [10.36.117.97]) by smtp.corp.redhat.com (Postfix) with ESMTP id 230F077EFC; Thu, 23 Mar 2017 15:45:21 +0000 (UTC) From: Kevin Traynor To: yuanhan.liu@linux.intel.com, maxime.coquelin@redhat.com Cc: dev@dpdk.org, Kevin Traynor , stable@dpdk.org Date: Thu, 23 Mar 2017 15:44:58 +0000 Message-Id: <1490283898-23019-1-git-send-email-ktraynor@redhat.com> In-Reply-To: <1489605049-18686-1-git-send-email-ktraynor@redhat.com> References: <1489605049-18686-1-git-send-email-ktraynor@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 23 Mar 2017 15:45:23 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2] vhost: fix virtio_net false sharing X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The broadcast_rarp field in the virtio_net struct is checked in the dequeue datapath regardless of whether descriptors are available or not. As it is checked with cmpset leading to a write, false sharing on the virtio_net struct can happen between enqueue and dequeue datapaths regardless of whether a RARP is requested. In OVS, the issue can cause a uni-directional performance drop of up to 15%. Fix that by only performing the cmpset if a read of broadcast_rarp indicates that the cmpset is likely to succeed. Fixes: a66bcad32240 ("vhost: arrange struct fields for better cache sharing") Cc: stable@dpdk.org Signed-off-by: Kevin Traynor Reviewed-by: Maxime Coquelin --- V2: Change from fixing by moving broadcast_rarp location in virtio_net struct to performing a read before cmpset. lib/librte_vhost/virtio_net.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 337470d..d0a3b11 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -1057,7 +1057,19 @@ static inline bool __attribute__((always_inline)) * * Check user_send_rarp() for more information. + * + * broadcast_rarp shares a cacheline in the virtio_net structure + * with some fields that are accessed during enqueue and + * rte_atomic16_cmpset() causes a write if using cmpxchg. This could + * result in false sharing between enqueue and dequeue. + * + * Prevent unnecessary false sharing by reading broadcast_rarp first + * and only performing cmpset if the read indicates it is likely to + * be set. */ - if (unlikely(rte_atomic16_cmpset((volatile uint16_t *) - &dev->broadcast_rarp.cnt, 1, 0))) { + + if (unlikely(rte_atomic16_read(&dev->broadcast_rarp) && + rte_atomic16_cmpset((volatile uint16_t *) + &dev->broadcast_rarp.cnt, 1, 0))) { + rarp_mbuf = rte_pktmbuf_alloc(mbuf_pool); if (rarp_mbuf == NULL) {