From patchwork Wed Sep 23 14:22:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 78576 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2B61A04B1; Wed, 23 Sep 2020 16:23:51 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E8A2F1DC75; Wed, 23 Sep 2020 16:23:44 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 6905A1DAAF for ; Wed, 23 Sep 2020 16:23:42 +0200 (CEST) IronPort-SDR: 6jUGz4lPEEPPOxCawYgs6bQzwjx7Fe02gW/Y7HbaFY/ndeqhUZ9UPx75ek/GV2YdXD6AdmHSj3 aBqjB2dSNnTQ== X-IronPort-AV: E=McAfee;i="6000,8403,9752"; a="245732141" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="245732141" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 07:23:42 -0700 IronPort-SDR: +mSsVow0tl2gA0Lorsd+V6zlAp97Ym4Sf2cOvj9lQiPvb/IJ1cMeii+oBaEIiUR89fad6UXyEJ zjhcL7fau8+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="511663490" Received: from silpixa00399477.ir.intel.com ([10.237.214.232]) by fmsmga005.fm.intel.com with ESMTP; 23 Sep 2020 07:23:39 -0700 From: Radu Nicolau To: dev@dpdk.org Cc: beilei.xing@intel.com, jia.guo@intel.com, bruce.richardson@intel.com, konstantin.ananyev@intel.com, jerinjacobk@gmail.com, david.marchand@redhat.com, fiona.trahe@intel.com, wei.zhao1@intel.com, ruifeng.wang@arm.com, qiming.yang@intel.com, qi.z.zhang@intel.com, Radu Nicolau Date: Wed, 23 Sep 2020 14:22:49 +0000 Message-Id: <20200923142253.18853-2-radu.nicolau@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923142253.18853-1-radu.nicolau@intel.com> References: <1591870283-7776-1-git-send-email-radu.nicolau@intel.com> <20200923142253.18853-1-radu.nicolau@intel.com> Subject: [dpdk-dev] [PATCH v12 1/5] eal: add WC store functions 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" Add rte_write32_wc and rte_write32_wc_relaxed functions that implement 32bit stores using write combining memory protocol. Provided generic stubs and x86 implementation. Signed-off-by: Radu Nicolau Acked-by: Bruce Richardson --- doc/guides/rel_notes/release_20_11.rst | 6 ++++ lib/librte_eal/arm/include/rte_io_64.h | 12 +++++++ lib/librte_eal/include/generic/rte_io.h | 48 +++++++++++++++++++++++++ lib/librte_eal/x86/include/rte_io.h | 42 ++++++++++++++++++++++ 4 files changed, 108 insertions(+) diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst index c6642f5f9..f51577684 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -78,6 +78,12 @@ New Features ``--portmask=N`` where N represents the hexadecimal bitmask of ports used. +* **Added write combining store APIs.** + + Added ``rte_write32_wc`` and ``rte_write32_wc_relaxed`` APIs + that enable write combining stores (depending on architecture). + The functions are provided as a generic stubs and + x86 specific implementation. Removed Items ------------- diff --git a/lib/librte_eal/arm/include/rte_io_64.h b/lib/librte_eal/arm/include/rte_io_64.h index e5346240e..d07d9cb22 100644 --- a/lib/librte_eal/arm/include/rte_io_64.h +++ b/lib/librte_eal/arm/include/rte_io_64.h @@ -164,6 +164,18 @@ rte_write64(uint64_t value, volatile void *addr) rte_write64_relaxed(value, addr); } +static __rte_always_inline void +rte_write32_wc(uint32_t value, volatile void *addr) +{ + rte_write32(value, addr); +} + +static __rte_always_inline void +rte_write32_wc_relaxed(uint32_t value, volatile void *addr) +{ + rte_write32_relaxed(value, addr); +} + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/include/generic/rte_io.h b/lib/librte_eal/include/generic/rte_io.h index da457f7f7..0669baa0b 100644 --- a/lib/librte_eal/include/generic/rte_io.h +++ b/lib/librte_eal/include/generic/rte_io.h @@ -229,6 +229,40 @@ rte_write32(uint32_t value, volatile void *addr); static inline void rte_write64(uint64_t value, volatile void *addr); +/** + * Write a 32-bit value to I/O device memory address addr using write + * combining memory write protocol. Depending on the platform write combining + * may not be available and/or may be treated as a hint and the behavior may + * fallback to a regular store. + * + * @param value + * Value to write + * @param addr + * I/O memory address to write the value to + */ +__rte_experimental +static inline void +rte_write32_wc(uint32_t value, volatile void *addr); + +/** + * Write a 32-bit value to I/O device memory address addr using write + * combining memory write protocol. Depending on the platform write combining + * may not be available and/or may be treated as a hint and the behavior may + * fallback to a regular store. + * + * The relaxed version does not have additional I/O memory barrier, useful in + * accessing the device registers of integrated controllers which implicitly + * strongly ordered with respect to memory access. + * + * @param value + * Value to write + * @param addr + * I/O memory address to write the value to + */ +__rte_experimental +static inline void +rte_write32_wc_relaxed(uint32_t value, volatile void *addr); + #endif /* __DOXYGEN__ */ #ifndef RTE_OVERRIDE_IO_H @@ -345,6 +379,20 @@ rte_write64(uint64_t value, volatile void *addr) rte_write64_relaxed(value, addr); } +#ifndef RTE_NATIVE_WRITE32_WC +static __rte_always_inline void +rte_write32_wc(uint32_t value, volatile void *addr) +{ + rte_write32(value, addr); +} + +static __rte_always_inline void +rte_write32_wc_relaxed(uint32_t value, volatile void *addr) +{ + rte_write32_relaxed(value, addr); +} +#endif /* RTE_NATIVE_WRITE32_WC */ + #endif /* RTE_OVERRIDE_IO_H */ #endif /* _RTE_IO_H_ */ diff --git a/lib/librte_eal/x86/include/rte_io.h b/lib/librte_eal/x86/include/rte_io.h index 2db71b1b0..4f4ff8b87 100644 --- a/lib/librte_eal/x86/include/rte_io.h +++ b/lib/librte_eal/x86/include/rte_io.h @@ -9,8 +9,50 @@ extern "C" { #endif +#include "rte_cpuflags.h" + +#define RTE_NATIVE_WRITE32_WC #include "generic/rte_io.h" +/** + * @internal + * MOVDIRI wrapper. + */ +static __rte_always_inline void +_rte_x86_movdiri(uint32_t value, volatile void *addr) +{ + asm volatile( + /* MOVDIRI */ + ".byte 0x40, 0x0f, 0x38, 0xf9, 0x02" + : + : "a" (value), "d" (addr)); +} + +static __rte_always_inline void +rte_write32_wc_relaxed(uint32_t value, volatile void *addr) +{ + static int _x86_movdiri_flag = -1; + if (_x86_movdiri_flag == 1) { + _rte_x86_movdiri(value, addr); + } else if (_x86_movdiri_flag == 0) { + rte_write32_relaxed(value, addr); + } else { + _x86_movdiri_flag = + (rte_cpu_get_flag_enabled(RTE_CPUFLAG_MOVDIRI) > 0); + if (_x86_movdiri_flag == 1) + _rte_x86_movdiri(value, addr); + else + rte_write32_relaxed(value, addr); + } +} + +static __rte_always_inline void +rte_write32_wc(uint32_t value, volatile void *addr) +{ + rte_wmb(); + rte_write32_wc_relaxed(value, addr); +} + #ifdef __cplusplus } #endif