From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 93CAE42B47 for ; Fri, 19 May 2023 10:37:01 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 901A242D29; Fri, 19 May 2023 10:37:01 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 8E27940F16; Fri, 19 May 2023 10:36:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684485418; x=1716021418; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ACqcnx8xDgGo6vtDtcl3UGmMonmAob34dU+jelCNfP4=; b=b7J8+8KGAgMT3KvYcm1UKF9S7f6MTrSIxYMNXwJks9jZxeeIzGfCfJEa RfZQtTEesZ/WVPfyjrOrFtkGoGofvhNIiyCLkLDCq2KdvuBW2cvYZ8Nab S47kcIIv5kaMvqkt7BWedMMD0gBOQFzwU6tCm/3np/4T6WsF/YbNB/4z+ L2mpzUimaOTwi/YvGSq+YIN6t5Irg1L0nQebsb3ktxtRrQzIXOOxYBUMP tT4VlvFVdDdmA6vJQcZZt/b/4qoKVwD/38PIYEXKBtbzaSSKpYT0ohXWe mHihlOp6KpyrTAgByZ4WnzPyK2GKTw/sV6Ygb4JLO6/+5i4d/03Uo3Xce w==; X-IronPort-AV: E=McAfee;i="6600,9927,10714"; a="354670369" X-IronPort-AV: E=Sophos;i="6.00,176,1681196400"; d="scan'208";a="354670369" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 May 2023 01:36:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10714"; a="772216212" X-IronPort-AV: E=Sophos;i="6.00,176,1681196400"; d="scan'208";a="772216212" Received: from dpdk-wenjing-01.sh.intel.com ([10.67.118.161]) by fmsmga004.fm.intel.com with ESMTP; 19 May 2023 01:36:55 -0700 From: Wenjing Qiao To: jingjing.wu@intel.com, beilei.xing@intel.com, qi.z.zhang@intel.com Cc: dev@dpdk.org, mingxia.liu@intel.com, Wenjing Qiao , stable@dpdk.org Subject: [PATCH v4 1/7] common/idpf: fix 64b timestamp roll over issue Date: Fri, 19 May 2023 04:31:04 -0400 Message-Id: <20230519083110.809913-2-wenjing.qiao@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230519083110.809913-1-wenjing.qiao@intel.com> References: <20230424091707.488045-2-wenjing.qiao@intel.com> <20230519083110.809913-1-wenjing.qiao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Reading MTS register at first packet will cause timestamp roll over issue. To support calculating 64b timestamp, need an alarm to save main time from registers every 1 second. Fixes: 8c6098afa075 ("common/idpf: add Rx/Tx data path") Cc: stable@dpdk.org Signed-off-by: Wenjing Qiao --- drivers/common/idpf/idpf_common_rxtx.c | 126 ++++++++++++++----------- drivers/common/idpf/idpf_common_rxtx.h | 6 +- drivers/common/idpf/version.map | 2 + 3 files changed, 77 insertions(+), 57 deletions(-) diff --git a/drivers/common/idpf/idpf_common_rxtx.c b/drivers/common/idpf/idpf_common_rxtx.c index fc87e3e243..b487c2a8a6 100644 --- a/drivers/common/idpf/idpf_common_rxtx.c +++ b/drivers/common/idpf/idpf_common_rxtx.c @@ -4,6 +4,7 @@ #include #include +#include #include "idpf_common_rxtx.h" @@ -349,6 +350,46 @@ idpf_qc_tx_queue_release(void *txq) rte_free(q); } +#define IDPF_TIMESYNC_REG_WRAP_GUARD_BAND 10000 +static void +idpf_dev_read_time_hw(void *cb_arg) +{ +#ifdef RTE_ARCH_X86_64 + struct idpf_adapter *ad = (struct idpf_adapter *)cb_arg; + uint32_t hi, lo, lo2; + int rc = 0; + struct idpf_hw *hw = &ad->hw; + + IDPF_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); + IDPF_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, + PF_GLTSYN_CMD_SYNC_EXEC_CMD_M | PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); + lo = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + hi = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); + /* + * On typical system, the delta between lo and lo2 is ~1000ns, + * so 10000 seems a large-enough but not overly-big guard band. + */ + if (lo > (UINT32_MAX - IDPF_TIMESYNC_REG_WRAP_GUARD_BAND)) + lo2 = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + else + lo2 = lo; + + if (lo2 < lo) { + lo = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + hi = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); + } + + ad->time_hw = ((uint64_t)hi << 32) | lo; +#else /* !RTE_ARCH_X86_64 */ + ad->time_hw = 0; +#endif /* RTE_ARCH_X86_64 */ + + /* re-alarm watchdog */ + rc = rte_eal_alarm_set(1000 * 1000, &idpf_dev_read_time_hw, cb_arg); + if (rc) + DRV_LOG(ERR, "Failed to reset device watchdog alarm"); +} + int idpf_qc_ts_mbuf_register(struct idpf_rx_queue *rxq) { @@ -366,6 +407,24 @@ idpf_qc_ts_mbuf_register(struct idpf_rx_queue *rxq) return 0; } + +int +idpf_rx_timestamp_start(struct idpf_adapter *base) +{ + rte_eal_alarm_set(1000 * 1000, + &idpf_dev_read_time_hw, + (void *)base); + return 0; +} + +int +idpf_rx_timestamp_stop(struct idpf_adapter *base) +{ + rte_eal_alarm_cancel(idpf_dev_read_time_hw, + base); + return 0; +} + int idpf_qc_single_rxq_mbufs_alloc(struct idpf_rx_queue *rxq) { @@ -442,56 +501,23 @@ idpf_qc_split_rxq_mbufs_alloc(struct idpf_rx_queue *rxq) return 0; } -#define IDPF_TIMESYNC_REG_WRAP_GUARD_BAND 10000 /* Helper function to convert a 32b nanoseconds timestamp to 64b. */ static inline uint64_t -idpf_tstamp_convert_32b_64b(struct idpf_adapter *ad, uint32_t flag, - uint32_t in_timestamp) +idpf_tstamp_convert_32b_64b(uint64_t time_hw, uint32_t in_timestamp) { -#ifdef RTE_ARCH_X86_64 - struct idpf_hw *hw = &ad->hw; const uint64_t mask = 0xFFFFFFFF; - uint32_t hi, lo, lo2, delta; + const uint32_t half_overflow_duration = 0x1 << 31; + uint32_t delta; uint64_t ns; - if (flag != 0) { - IDPF_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); - IDPF_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, PF_GLTSYN_CMD_SYNC_EXEC_CMD_M | - PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); - lo = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); - hi = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); - /* - * On typical system, the delta between lo and lo2 is ~1000ns, - * so 10000 seems a large-enough but not overly-big guard band. - */ - if (lo > (UINT32_MAX - IDPF_TIMESYNC_REG_WRAP_GUARD_BAND)) - lo2 = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); - else - lo2 = lo; - - if (lo2 < lo) { - lo = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); - hi = IDPF_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); - } - - ad->time_hw = ((uint64_t)hi << 32) | lo; - } - - delta = (in_timestamp - (uint32_t)(ad->time_hw & mask)); - if (delta > (mask / 2)) { - delta = ((uint32_t)(ad->time_hw & mask) - in_timestamp); - ns = ad->time_hw - delta; + delta = (in_timestamp - (uint32_t)(time_hw & mask)); + if (delta > half_overflow_duration) { + delta = ((uint32_t)(time_hw & mask) - in_timestamp); + ns = time_hw - delta; } else { - ns = ad->time_hw + delta; + ns = time_hw + delta; } - return ns; -#else /* !RTE_ARCH_X86_64 */ - RTE_SET_USED(ad); - RTE_SET_USED(flag); - RTE_SET_USED(in_timestamp); - return 0; -#endif /* RTE_ARCH_X86_64 */ } #define IDPF_RX_FLEX_DESC_ADV_STATUS0_XSUM_S \ @@ -659,9 +685,6 @@ idpf_dp_splitq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, rx_desc_ring = rxq->rx_ring; ptype_tbl = rxq->adapter->ptype_tbl; - if ((rxq->offloads & IDPF_RX_OFFLOAD_TIMESTAMP) != 0) - rxq->hw_register_set = 1; - while (nb_rx < nb_pkts) { rx_desc = &rx_desc_ring[rx_id]; @@ -720,10 +743,8 @@ idpf_dp_splitq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, if (idpf_timestamp_dynflag > 0 && (rxq->offloads & IDPF_RX_OFFLOAD_TIMESTAMP)) { /* timestamp */ - ts_ns = idpf_tstamp_convert_32b_64b(ad, - rxq->hw_register_set, + ts_ns = idpf_tstamp_convert_32b_64b(ad->time_hw, rte_le_to_cpu_32(rx_desc->ts_high)); - rxq->hw_register_set = 0; *RTE_MBUF_DYNFIELD(rxm, idpf_timestamp_dynfield_offset, rte_mbuf_timestamp_t *) = ts_ns; @@ -1077,9 +1098,6 @@ idpf_dp_singleq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, rx_ring = rxq->rx_ring; ptype_tbl = rxq->adapter->ptype_tbl; - if ((rxq->offloads & IDPF_RX_OFFLOAD_TIMESTAMP) != 0) - rxq->hw_register_set = 1; - while (nb_rx < nb_pkts) { rxdp = &rx_ring[rx_id]; rx_status0 = rte_le_to_cpu_16(rxdp->flex_nic_wb.status_error0); @@ -1142,10 +1160,8 @@ idpf_dp_singleq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, if (idpf_timestamp_dynflag > 0 && (rxq->offloads & IDPF_RX_OFFLOAD_TIMESTAMP) != 0) { /* timestamp */ - ts_ns = idpf_tstamp_convert_32b_64b(ad, - rxq->hw_register_set, + ts_ns = idpf_tstamp_convert_32b_64b(ad->time_hw, rte_le_to_cpu_32(rxd.flex_nic_wb.flex_ts.ts_high)); - rxq->hw_register_set = 0; *RTE_MBUF_DYNFIELD(rxm, idpf_timestamp_dynfield_offset, rte_mbuf_timestamp_t *) = ts_ns; @@ -1272,10 +1288,8 @@ idpf_dp_singleq_recv_scatter_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, if (idpf_timestamp_dynflag > 0 && (rxq->offloads & IDPF_RX_OFFLOAD_TIMESTAMP) != 0) { /* timestamp */ - ts_ns = idpf_tstamp_convert_32b_64b(ad, - rxq->hw_register_set, + ts_ns = idpf_tstamp_convert_32b_64b(ad->time_hw, rte_le_to_cpu_32(rxd.flex_nic_wb.flex_ts.ts_high)); - rxq->hw_register_set = 0; *RTE_MBUF_DYNFIELD(rxm, idpf_timestamp_dynfield_offset, rte_mbuf_timestamp_t *) = ts_ns; diff --git a/drivers/common/idpf/idpf_common_rxtx.h b/drivers/common/idpf/idpf_common_rxtx.h index 6cb83fc0a6..53049b1a31 100644 --- a/drivers/common/idpf/idpf_common_rxtx.h +++ b/drivers/common/idpf/idpf_common_rxtx.h @@ -145,7 +145,6 @@ struct idpf_rx_queue { struct idpf_rx_queue *bufq2; uint64_t offloads; - uint32_t hw_register_set; }; struct idpf_tx_entry { @@ -303,4 +302,9 @@ __rte_internal uint16_t idpf_dp_singleq_recv_scatter_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +__rte_internal +int idpf_rx_timestamp_start(struct idpf_adapter *base); + +__rte_internal +int idpf_rx_timestamp_stop(struct idpf_adapter *base); #endif /* _IDPF_COMMON_RXTX_H_ */ diff --git a/drivers/common/idpf/version.map b/drivers/common/idpf/version.map index 70334a1b03..661c7f5cb9 100644 --- a/drivers/common/idpf/version.map +++ b/drivers/common/idpf/version.map @@ -34,6 +34,8 @@ INTERNAL { idpf_qc_tx_thresh_check; idpf_qc_tx_vec_avx512_setup; idpf_qc_txq_mbufs_release; + idpf_rx_timestamp_start; + idpf_rx_timestamp_stop; idpf_vc_api_version_check; idpf_vc_caps_get; -- 2.25.1