From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 7D4134CBD for ; Mon, 5 Nov 2018 18:39:47 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Nov 2018 09:39:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,468,1534834800"; d="scan'208";a="278500836" Received: from silpixa00399126.ir.intel.com (HELO silpixa00399126.ger.corp.intel.com) ([10.237.223.223]) by fmsmga006.fm.intel.com with ESMTP; 05 Nov 2018 09:39:45 -0800 From: Bruce Richardson To: dev@dpdk.org Cc: Bruce Richardson Date: Mon, 5 Nov 2018 17:39:12 +0000 Message-Id: <20181105173913.61225-4-bruce.richardson@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181105173913.61225-1-bruce.richardson@intel.com> References: <20181105173913.61225-1-bruce.richardson@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH 3/4] eal/x86: reduce contention when retrying TSX 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: , X-List-Received-Date: Mon, 05 Nov 2018 17:39:48 -0000 When TSX transactions abort, it is generally worth retrying a number of times before falling back to the traditional locking path, as the parallelism benefits from TSX can be worth it when a transaction does succeed. For cases with multiple threads and high contention rates, it can be useful to have increasing delays between retry attempts, so as to avoid having the same threads repeatedly collide. Signed-off-by: Bruce Richardson --- lib/librte_eal/common/include/arch/x86/rte_spinlock.h | 19 ++++++++++++++++--- lib/librte_eal/linuxapp/eal/eal_alarm.c | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/common/include/arch/x86/rte_spinlock.h b/lib/librte_eal/common/include/arch/x86/rte_spinlock.h index 60321da..961a3c0 100644 --- a/lib/librte_eal/common/include/arch/x86/rte_spinlock.h +++ b/lib/librte_eal/common/include/arch/x86/rte_spinlock.h @@ -15,8 +15,9 @@ #include "rte_branch_prediction.h" #include "rte_common.h" #include "rte_pause.h" +#include "rte_cycles.h" -#define RTE_RTM_MAX_RETRIES (10) +#define RTE_RTM_MAX_RETRIES (20) #define RTE_XABORT_LOCK_BUSY (0xff) #ifndef RTE_FORCE_INTRINSICS @@ -87,7 +88,7 @@ static inline int rte_tm_supported(void) unsigned int status = rte_xbegin(); - if (likely(RTE_XBEGIN_STARTED == status)) { + if (RTE_XBEGIN_STARTED == status) { if (unlikely(*lock)) rte_xabort(RTE_XABORT_LOCK_BUSY); else @@ -97,8 +98,20 @@ static inline int rte_tm_supported(void) rte_pause(); if ((status & RTE_XABORT_EXPLICIT) && - (RTE_XABORT_CODE(status) == RTE_XABORT_LOCK_BUSY)) + (RTE_XABORT_CODE(status) == RTE_XABORT_LOCK_BUSY)) { + /* add a small delay before retrying, basing the + * delay on the number of times we've already tried, + * to give a back-off type of behaviour. We + * randomize trycount by taking bits from the tsc count + */ + int try_count = RTE_RTM_MAX_RETRIES - retries; + int pause_count = (rte_rdtsc() & 0x7) | 1; + pause_count <<= try_count; + int i; + for (i = 0; i < pause_count; i++) + rte_pause(); continue; + } if ((status & RTE_XABORT_RETRY) == 0) /* do not retry */ break; diff --git a/lib/librte_eal/linuxapp/eal/eal_alarm.c b/lib/librte_eal/linuxapp/eal/eal_alarm.c index 391d2a6..840ede7 100644 --- a/lib/librte_eal/linuxapp/eal/eal_alarm.c +++ b/lib/librte_eal/linuxapp/eal/eal_alarm.c @@ -30,7 +30,9 @@ #define NS_PER_US 1000 #define US_PER_MS 1000 #define MS_PER_S 1000 +#ifndef US_PER_S #define US_PER_S (US_PER_MS * MS_PER_S) +#endif #ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */ #define CLOCK_TYPE_ID CLOCK_MONOTONIC_RAW -- 1.8.5.6