Hi Bruce, Thank you for your comments and you're right. My apologies—since this patch was submitted some time ago, I lost track of the context when sending v2 and made an incorrect modification. I'll remove the erroneous code. Regards Zhichao ________________________________ 发件人: Richardson, Bruce 已发送: 2025 年 11 月 12 日 星期三 20:04 收件人: Zeng, ZhichaoX 抄送: dev@dpdk.org ; stable@dpdk.org ; Burakov, Anatoly ; Jeff Guo ; Ferruh Yigit ; Wenzhuo Lu 主题: Re: [PATCH v2] net/ice: fix statistics read error On Mon, Nov 10, 2025 at 04:05:14PM +0800, Zhichao Zeng wrote: > The statistics contain 40 bits. The lower 32 bits are read first, followed > by the upper 8 bits. > > In some cases, after reading the lower 32 bits, a carry occurs from > the lower bits, which causes the final statistics to be incorrect. > > This commit fixes this issue. > > Fixes: a37bde56314d ("net/ice: support statistics") > Cc: stable@dpdk.org > > Signed-off-by: Zhichao Zeng > > --- > v2: replace single retries with loops > --- > drivers/net/intel/ice/ice_ethdev.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c > index 4669eba7c7..016b25c63a 100644 > --- a/drivers/net/intel/ice/ice_ethdev.c > +++ b/drivers/net/intel/ice/ice_ethdev.c > @@ -6351,10 +6351,16 @@ ice_stat_update_40(struct ice_hw *hw, > uint64_t *stat) > { > uint64_t new_data; > + uint32_t lo_old, hi, lo; > > - new_data = (uint64_t)ICE_READ_REG(hw, loreg); > - new_data |= (uint64_t)(ICE_READ_REG(hw, hireg) & ICE_8_BIT_MASK) << > - ICE_32_BIT_WIDTH; > + do { > + lo_old = ICE_READ_REG(hw, loreg); > + hi = ICE_READ_REG(hw, hireg); > + lo = ICE_READ_REG(hw, loreg); > + } while (lo_old > lo); > + > + new_data = (uint64_t)lo; > + new_data |= (uint64_t)(hi & ICE_8_BIT_MASK) << ICE_32_BIT_WIDTH; > > if (!offset_loaded) > *offset = new_data; > @@ -6363,10 +6369,8 @@ ice_stat_update_40(struct ice_hw *hw, > *stat = new_data - *offset; > else > *stat = (uint64_t)((new_data + > - ((uint64_t)1 << ICE_40_BIT_WIDTH)) - > - *offset); > - > - *stat &= ICE_40_BIT_MASK; > + ((uint64_t)1 << ICE_32_BIT_WIDTH)) > + - *offset); This part wasn't in v1, was it? It looks wrong to me, and the original code looks correct. Given that offset and new_data should both be 40-bit quantities, any wraparound would be at 40-bits rather than 32-bits no? Can you explain why we would use a 32-bit shift here? > } > > /** > -- > 2.34.1 >