From patchwork Mon Jul 13 12:27:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 73933 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 021A8A0540; Mon, 13 Jul 2020 14:28:03 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5C6D01D6AD; Mon, 13 Jul 2020 14:27:59 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 4D6E71D69B for ; Mon, 13 Jul 2020 14:27:58 +0200 (CEST) IronPort-SDR: JSM/z0u9e0zz+ik8nz00z/0Zt90dFwy1tZu7WIcqzmdacQMDqOXwwihzsqaKAjJz6LnsGQC6Yq il99HT4lU0MQ== X-IronPort-AV: E=McAfee;i="6000,8403,9680"; a="136070925" X-IronPort-AV: E=Sophos;i="5.75,347,1589266800"; d="scan'208";a="136070925" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jul 2020 05:27:57 -0700 IronPort-SDR: dsgJP6U2tL51aLyyLZUq+gumQvL+fY293D0y4oCWXasAi23iR2KGD3drvb0D2KMQCAGCMXvGbl r9X7QE3VpyTA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,347,1589266800"; d="scan'208";a="285370385" Received: from silpixa00383879.ir.intel.com ([10.237.222.142]) by orsmga006.jf.intel.com with ESMTP; 13 Jul 2020 05:27:55 -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, Radu Nicolau Date: Mon, 13 Jul 2020 13:27:24 +0100 Message-Id: <1594643247-11094-2-git-send-email-radu.nicolau@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1594643247-11094-1-git-send-email-radu.nicolau@intel.com> References: <1591870283-7776-1-git-send-email-radu.nicolau@intel.com> <1594643247-11094-1-git-send-email-radu.nicolau@intel.com> Subject: [dpdk-dev] [PATCH v6 1/4] 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 --- v6: add QAT and IXGBE updates lib/librte_eal/include/generic/rte_io.h | 48 ++++++++++++++++++++++++++++ lib/librte_eal/x86/include/rte_io.h | 56 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/lib/librte_eal/include/generic/rte_io.h b/lib/librte_eal/include/generic/rte_io.h index da457f7..0669baa 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 2db71b1..c95ed67 100644 --- a/lib/librte_eal/x86/include/rte_io.h +++ b/lib/librte_eal/x86/include/rte_io.h @@ -9,8 +9,64 @@ 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(uint32_t value, volatile void *addr) +{ + static int _x86_movdiri_flag = -1; + if (_x86_movdiri_flag == 1) { + rte_wmb(); + _rte_x86_movdiri(value, addr); + } else if (_x86_movdiri_flag == 0) { + rte_write32(value, addr); + } else { + _x86_movdiri_flag = + (rte_cpu_get_flag_enabled(RTE_CPUFLAG_MOVDIRI) > 0); + if (_x86_movdiri_flag == 1) { + rte_wmb(); + _rte_x86_movdiri(value, addr); + } else { + rte_write32(value, 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); + } +} + #ifdef __cplusplus } #endif