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 6F94DA054A for ; Tue, 25 Oct 2022 17:09:18 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 68C9E42C4B; Tue, 25 Oct 2022 17:09:18 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 9748142C38 for ; Tue, 25 Oct 2022 17:09:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666710555; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=teUlI+BuHRCGLbvuiT+M89XyExzfmnqaDPxlhUcpjVE=; b=GGxTcZFno+ItEbAuLmLt5nVUGYxjUW65AyGi3lrwgeQrSU15pvEtGN2CCdaAxoeWzxUUFe +j2UvK9va0lsIR5WQ6UMP/FUin1GLhtdHlJgZstb3uv9n4m6iLY5mN0JKIFzSQFo7y3DSM mHzwZ+s5DxOCK5K8+n7Q3JNdksQ5zDs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-332-xEiCVOZtMGOLobjjZ9lSoQ-1; Tue, 25 Oct 2022 11:09:09 -0400 X-MC-Unique: xEiCVOZtMGOLobjjZ9lSoQ-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E0CFB185A794; Tue, 25 Oct 2022 15:09:06 +0000 (UTC) Received: from rh.redhat.com (unknown [10.39.192.13]) by smtp.corp.redhat.com (Postfix) with ESMTP id AF7C64B400F; Tue, 25 Oct 2022 15:09:05 +0000 (UTC) From: Kevin Traynor To: Qi Zhang Cc: Jacob Keller , Qiming Yang , dpdk stable Subject: patch 'net/ice/base: fix division during E822 PTP init' has been queued to stable release 21.11.3 Date: Tue, 25 Oct 2022 16:06:44 +0100 Message-Id: <20221025150734.142189-49-ktraynor@redhat.com> In-Reply-To: <20221025150734.142189-1-ktraynor@redhat.com> References: <20221025150734.142189-1-ktraynor@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true 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 Hi, FYI, your patch has been queued to stable release 21.11.3 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 11/01/22. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasing (ie: not only metadata diffs), please double check that the rebase was correctly done. Queued patches are on a temporary branch at: https://github.com/kevintraynor/dpdk-stable This queued commit can be viewed at: https://github.com/kevintraynor/dpdk-stable/commit/14ed431e0817166809096e4004a29c3cbcf89b0f Thanks. Kevin --- >From 14ed431e0817166809096e4004a29c3cbcf89b0f Mon Sep 17 00:00:00 2001 From: Qi Zhang Date: Mon, 15 Aug 2022 03:31:01 -0400 Subject: [PATCH] net/ice/base: fix division during E822 PTP init [ upstream commit 4e1d404e03da1b73c69d8aedc77d810af2e5d6fb ] When initializing the device hardware for PTP, the E822 devices requirea number of values to be calculated and programmed to hardware.These values are calculated using unsigned 64-bit division. The DIV_64BIT macro currently translates into a specific Linux functionthat triggers a *signed* division. This produces incorrect results when operating on a dividend larger than an s64. The division calculation effectively overflows and results in totally unexpected behavior. In this case, the UIX value for 10Gb/40Gb link speeds are calculated incorrectly. This ultimately cascades into a failure of the Tx timestamps. Specifically, the reported Tx timestamps become wildly inaccurate and not representing nominal time. The root cause of this bug is the assumption that DIV_64BIT can correctly handle both signed and unsigned division. In fact the entire reason we need this is because the Linux kernel compilation target does not provide native 64 bit division ops, and requires explicit use of kernel functions which explicitly do either signed or unsigned division. To correctly solve this, introduce new functions, DIV_U64 and DIV_S64 which are specifically intended for signed or unsigned division. To help catch issues, use static inline functions so that we get strict type checking. Fixes: 97f4f78bbd9f ("net/ice/base: add functions for device clock control") Signed-off-by: Jacob Keller Signed-off-by: Qi Zhang Acked-by: Qiming Yang --- drivers/net/ice/base/ice_ptp_hw.c | 56 +++++++++++++++---------------- drivers/net/ice/base/ice_sched.c | 24 ++++++------- drivers/net/ice/base/ice_type.h | 30 +++++++++++++++-- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index 7e797c9511..3a47f8cebe 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -1635,5 +1635,5 @@ static enum ice_status ice_phy_cfg_uix_e822(struct ice_hw *hw, u8 port) /* Program the 10Gb/40Gb conversion ratio */ - uix = DIV_64BIT(tu_per_sec * LINE_UI_10G_40G, 390625000); + uix = DIV_U64(tu_per_sec * LINE_UI_10G_40G, 390625000); status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_10G_40G_L, @@ -1646,5 +1646,5 @@ static enum ice_status ice_phy_cfg_uix_e822(struct ice_hw *hw, u8 port) /* Program the 25Gb/100Gb conversion ratio */ - uix = DIV_64BIT(tu_per_sec * LINE_UI_25G_100G, 390625000); + uix = DIV_U64(tu_per_sec * LINE_UI_25G_100G, 390625000); status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_25G_100G_L, @@ -1728,6 +1728,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_PAR_TX_TUS */ if (e822_vernier[link_spd].tx_par_clk) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].tx_par_clk); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].tx_par_clk); else phy_tus = 0; @@ -1740,6 +1740,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_PAR_RX_TUS */ if (e822_vernier[link_spd].rx_par_clk) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].rx_par_clk); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].rx_par_clk); else phy_tus = 0; @@ -1752,6 +1752,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_PCS_TX_TUS */ if (e822_vernier[link_spd].tx_pcs_clk) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].tx_pcs_clk); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].tx_pcs_clk); else phy_tus = 0; @@ -1764,6 +1764,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_PCS_RX_TUS */ if (e822_vernier[link_spd].rx_pcs_clk) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].rx_pcs_clk); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].rx_pcs_clk); else phy_tus = 0; @@ -1776,6 +1776,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_DESK_PAR_TX_TUS */ if (e822_vernier[link_spd].tx_desk_rsgb_par) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].tx_desk_rsgb_par); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].tx_desk_rsgb_par); else phy_tus = 0; @@ -1788,6 +1788,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_DESK_PAR_RX_TUS */ if (e822_vernier[link_spd].rx_desk_rsgb_par) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].rx_desk_rsgb_par); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].rx_desk_rsgb_par); else phy_tus = 0; @@ -1800,6 +1800,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_DESK_PCS_TX_TUS */ if (e822_vernier[link_spd].tx_desk_rsgb_pcs) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].tx_desk_rsgb_pcs); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].tx_desk_rsgb_pcs); else phy_tus = 0; @@ -1812,6 +1812,6 @@ static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port) /* P_REG_DESK_PCS_RX_TUS */ if (e822_vernier[link_spd].rx_desk_rsgb_pcs) - phy_tus = DIV_64BIT(tu_per_sec, - e822_vernier[link_spd].rx_desk_rsgb_pcs); + phy_tus = DIV_U64(tu_per_sec, + e822_vernier[link_spd].rx_desk_rsgb_pcs); else phy_tus = 0; @@ -1845,7 +1845,7 @@ ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd) * divisions by 1e4 first then by 1e7. */ - fixed_offset = DIV_64BIT(tu_per_sec, 10000); + fixed_offset = DIV_U64(tu_per_sec, 10000); fixed_offset *= e822_vernier[link_spd].tx_fixed_delay; - fixed_offset = DIV_64BIT(fixed_offset, 10000000); + fixed_offset = DIV_U64(fixed_offset, 10000000); return fixed_offset; @@ -2075,7 +2075,7 @@ ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port, * speed pmd_adj_divisor value. */ - adj = DIV_64BIT(tu_per_sec, 125); + adj = DIV_U64(tu_per_sec, 125); adj *= mult; - adj = DIV_64BIT(adj, pmd_adj_divisor); + adj = DIV_U64(adj, pmd_adj_divisor); /* Finally, for 25G-RS and 50G-RS, a further adjustment for the Rx @@ -2098,7 +2098,7 @@ ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port, mult = (4 - rx_cycle) * 40; - cycle_adj = DIV_64BIT(tu_per_sec, 125); + cycle_adj = DIV_U64(tu_per_sec, 125); cycle_adj *= mult; - cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor); + cycle_adj = DIV_U64(cycle_adj, pmd_adj_divisor); adj += cycle_adj; @@ -2120,7 +2120,7 @@ ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port, mult = rx_cycle * 40; - cycle_adj = DIV_64BIT(tu_per_sec, 125); + cycle_adj = DIV_U64(tu_per_sec, 125); cycle_adj *= mult; - cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor); + cycle_adj = DIV_U64(cycle_adj, pmd_adj_divisor); adj += cycle_adj; @@ -2158,7 +2158,7 @@ ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd) * divisions by 1e4 first then by 1e7. */ - fixed_offset = DIV_64BIT(tu_per_sec, 10000); + fixed_offset = DIV_U64(tu_per_sec, 10000); fixed_offset *= e822_vernier[link_spd].rx_fixed_delay; - fixed_offset = DIV_64BIT(fixed_offset, 10000000); + fixed_offset = DIV_U64(fixed_offset, 10000000); return fixed_offset; diff --git a/drivers/net/ice/base/ice_sched.c b/drivers/net/ice/base/ice_sched.c index e697c579be..0841ec8c5b 100644 --- a/drivers/net/ice/base/ice_sched.c +++ b/drivers/net/ice/base/ice_sched.c @@ -3831,6 +3831,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) /* Get the wakeup integer value */ - bytes_per_sec = DIV_64BIT(((s64)bw * 1000), BITS_PER_BYTE); - wakeup_int = DIV_64BIT(hw->psm_clk_freq, bytes_per_sec); + bytes_per_sec = DIV_S64((s64)bw * 1000, BITS_PER_BYTE); + wakeup_int = DIV_S64(hw->psm_clk_freq, bytes_per_sec); if (wakeup_int > 63) { wakeup = (u16)((1 << 15) | wakeup_int); @@ -3840,6 +3840,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) */ wakeup_b = (s64)ICE_RL_PROF_MULTIPLIER * wakeup_int; - wakeup_a = DIV_64BIT((s64)ICE_RL_PROF_MULTIPLIER * - hw->psm_clk_freq, bytes_per_sec); + wakeup_a = DIV_S64((s64)ICE_RL_PROF_MULTIPLIER * + hw->psm_clk_freq, bytes_per_sec); /* Get Fraction value */ @@ -3847,9 +3847,9 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) /* Round up the Fractional value via Ceil(Fractional value) */ - if (wakeup_f > DIV_64BIT(ICE_RL_PROF_MULTIPLIER, 2)) + if (wakeup_f > DIV_S64(ICE_RL_PROF_MULTIPLIER, 2)) wakeup_f += 1; - wakeup_f_int = (s32)DIV_64BIT(wakeup_f * ICE_RL_PROF_FRACTION, - ICE_RL_PROF_MULTIPLIER); + wakeup_f_int = (s32)DIV_S64(wakeup_f * ICE_RL_PROF_FRACTION, + ICE_RL_PROF_MULTIPLIER); wakeup |= (u16)(wakeup_int << 9); wakeup |= (u16)(0x1ff & wakeup_f_int); @@ -3883,5 +3883,5 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, /* Bytes per second from Kbps */ - bytes_per_sec = DIV_64BIT(((s64)bw * 1000), BITS_PER_BYTE); + bytes_per_sec = DIV_S64((s64)bw * 1000, BITS_PER_BYTE); /* encode is 6 bits but really useful are 5 bits */ @@ -3889,12 +3889,12 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, u64 pow_result = BIT_ULL(i); - ts_rate = DIV_64BIT((s64)hw->psm_clk_freq, - pow_result * ICE_RL_PROF_TS_MULTIPLIER); + ts_rate = DIV_S64((s64)hw->psm_clk_freq, + pow_result * ICE_RL_PROF_TS_MULTIPLIER); if (ts_rate <= 0) continue; /* Multiplier value */ - mv_tmp = DIV_64BIT(bytes_per_sec * ICE_RL_PROF_MULTIPLIER, - ts_rate); + mv_tmp = DIV_S64(bytes_per_sec * ICE_RL_PROF_MULTIPLIER, + ts_rate); /* Round to the nearest ICE_RL_PROF_MULTIPLIER */ diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index d81984633a..ad0d72ac15 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -88,9 +88,35 @@ static inline bool ice_is_tc_ena(ice_bitmap_t bitmap, u8 tc) } -#define DIV_64BIT(n, d) ((n) / (d)) +/** + * DIV_S64 - Divide signed 64-bit value with signed 64-bit divisor + * @dividend: value to divide + * @divisor: value to divide by + * + * Use DIV_S64 for any 64-bit divide which operates on signed 64-bit dividends. + * Do not use this for unsigned 64-bit dividends as it will not produce + * correct results if the dividend is larger than S64_MAX. + */ +static inline s64 DIV_S64(s64 dividend, s64 divisor) +{ + return dividend / divisor; +} + +/** + * DIV_U64 - Divide unsigned 64-bit value by unsigned 64-bit divisor + * @dividend: value to divide + * @divisor: value to divide by + * + * Use DIV_U64 for any 64-bit divide which operates on unsigned 64-bit + * dividends. Do not use this for signed 64-bit dividends as it will not + * handle negative values correctly. + */ +static inline u64 DIV_U64(u64 dividend, u64 divisor) +{ + return dividend / divisor; +} static inline u64 round_up_64bit(u64 a, u32 b) { - return DIV_64BIT(((a) + (b) / 2), (b)); + return DIV_U64(((a) + (b) / 2), (b)); } -- 2.37.3 --- Diff of the applied patch vs upstream commit (please double-check if non-empty: --- --- - 2022-10-25 14:18:59.639925645 +0100 +++ 0049-net-ice-base-fix-division-during-E822-PTP-init.patch 2022-10-25 14:18:58.417798113 +0100 @@ -1 +1 @@ -From 4e1d404e03da1b73c69d8aedc77d810af2e5d6fb Mon Sep 17 00:00:00 2001 +From 14ed431e0817166809096e4004a29c3cbcf89b0f Mon Sep 17 00:00:00 2001 @@ -5,0 +6,2 @@ +[ upstream commit 4e1d404e03da1b73c69d8aedc77d810af2e5d6fb ] + @@ -35 +36,0 @@ -Cc: stable@dpdk.org @@ -47 +48 @@ -index 632a3f5bae..76119364e4 100644 +index 7e797c9511..3a47f8cebe 100644 @@ -187 +188 @@ -index 1b060d3567..71b5677f43 100644 +index e697c579be..0841ec8c5b 100644 @@ -190 +191 @@ -@@ -3917,6 +3917,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) +@@ -3831,6 +3831,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) @@ -199 +200 @@ -@@ -3926,6 +3926,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) +@@ -3840,6 +3840,6 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) @@ -208 +209 @@ -@@ -3933,9 +3933,9 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) +@@ -3847,9 +3847,9 @@ static u16 ice_sched_calc_wakeup(struct ice_hw *hw, s32 bw) @@ -221 +222 @@ -@@ -3969,5 +3969,5 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, +@@ -3883,5 +3883,5 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, @@ -228 +229 @@ -@@ -3975,12 +3975,12 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, +@@ -3889,12 +3889,12 @@ ice_sched_bw_to_rl_profile(struct ice_hw *hw, u32 bw, @@ -246 +247 @@ -index d4d0cab089..3da3de38af 100644 +index d81984633a..ad0d72ac15 100644