From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 57FC699FA; Tue, 1 Aug 2017 11:15:46 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2017 02:15:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,305,1498546800"; d="scan'208";a="1157638112" Received: from dpdk19.sh.intel.com ([10.67.111.74]) by orsmga001.jf.intel.com with ESMTP; 01 Aug 2017 02:15:43 -0700 From: Tiwei Bie To: dev@dpdk.org Cc: yliu@fridaylinux.org, maxime.coquelin@redhat.com, stable@dpdk.org Date: Tue, 1 Aug 2017 17:01:21 +0800 Message-Id: <1501578081-191381-1-git-send-email-tiwei.bie@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [dpdk-stable] [PATCH] vhost: make the page logging atomic X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Aug 2017 09:15:47 -0000 Each dirty page logging operation should be atomic. But it's not atomic in current implementation. So it's possible that some dirty pages can't be logged successfully when different threads try to log different pages into the same byte of the log buffer concurrently. This patch fixes this issue. Fixes: b171fad1ffa5 ("vhost: log used vring changes") Cc: stable@dpdk.org Reported-by: Xiao Wang Signed-off-by: Tiwei Bie --- lib/librte_vhost/vhost.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 0f294f3..6fe72ae 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -201,10 +201,19 @@ struct virtio_net { #define VHOST_LOG_PAGE 4096 +/* + * Atomically set a bit in memory. + */ +static __rte_always_inline void +vhost_set_bit(unsigned int nr, volatile uint8_t *addr) +{ + __sync_fetch_and_or_8(addr, (1U << nr)); +} + static __rte_always_inline void vhost_log_page(uint8_t *log_base, uint64_t page) { - log_base[page / 8] |= 1 << (page % 8); + vhost_set_bit(page % 8, &log_base[page / 8]); } static __rte_always_inline void -- 2.7.4