* [PATCH] net/ice: fix statistics read error
@ 2025-11-07 7:43 Zhichao Zeng
2025-11-07 9:26 ` Bruce Richardson
2025-11-10 8:05 ` [PATCH v2] " Zhichao Zeng
0 siblings, 2 replies; 7+ messages in thread
From: Zhichao Zeng @ 2025-11-07 7:43 UTC (permalink / raw)
To: dev
Cc: stable, Zhichao Zeng, Bruce Richardson, Anatoly Burakov,
Ferruh Yigit, Wenzhuo Lu, Jeff Guo
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 <zhichaox.zeng@intel.com>
---
drivers/net/intel/ice/ice_ethdev.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 513777e372..be08be0826 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -6036,10 +6036,19 @@ ice_stat_update_40(struct ice_hw *hw,
uint64_t *stat)
{
uint64_t new_data;
+ uint32_t lo, hi, lo2;
- 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;
+ lo = ICE_READ_REG(hw, loreg);
+ hi = ICE_READ_REG(hw, hireg);
+ lo2 = ICE_READ_REG(hw, loreg);
+
+ if (lo2 < lo) {
+ lo = ICE_READ_REG(hw, loreg);
+ hi = ICE_READ_REG(hw, hireg);
+ }
+
+ new_data = (uint64_t)lo;
+ new_data |= (uint64_t)(hi & ICE_8_BIT_MASK) << ICE_32_BIT_WIDTH;
if (!offset_loaded)
*offset = new_data;
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] net/ice: fix statistics read error 2025-11-07 7:43 [PATCH] net/ice: fix statistics read error Zhichao Zeng @ 2025-11-07 9:26 ` Bruce Richardson 2025-11-10 8:05 ` [PATCH v2] " Zhichao Zeng 1 sibling, 0 replies; 7+ messages in thread From: Bruce Richardson @ 2025-11-07 9:26 UTC (permalink / raw) To: Zhichao Zeng; +Cc: dev On Fri, Nov 07, 2025 at 03:43:38PM +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 <zhichaox.zeng@intel.com> > --- See comments inline below. /Bruce > drivers/net/intel/ice/ice_ethdev.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c > index 513777e372..be08be0826 100644 > --- a/drivers/net/intel/ice/ice_ethdev.c > +++ b/drivers/net/intel/ice/ice_ethdev.c > @@ -6036,10 +6036,19 @@ ice_stat_update_40(struct ice_hw *hw, > uint64_t *stat) > { > uint64_t new_data; > + uint32_t lo, hi, lo2; > > - 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; > + lo = ICE_READ_REG(hw, loreg); > + hi = ICE_READ_REG(hw, hireg); > + lo2 = ICE_READ_REG(hw, loreg); > + > + if (lo2 < lo) { > + lo = ICE_READ_REG(hw, loreg); > + hi = ICE_READ_REG(hw, hireg); > + } > + While I can't see multiple wrap-arounds occuring, it is theoretically possible e.g. if a process gets context switched out. Therefore, I think using a "while" construction would be better. For example: uint32_t lo_old, hi, lo; do { lo_old = ... hi = ... lo = ... } while (lo_old > lo); > + new_data = (uint64_t)lo; > + new_data |= (uint64_t)(hi & ICE_8_BIT_MASK) << ICE_32_BIT_WIDTH; > Using "lo" rather than "lo2" here means we are returning data we know is old. We should be returning the second value read. Suggest using something like what I suggest above, where we make "lo" the second read rather than the first. > if (!offset_loaded) > *offset = new_data; > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] net/ice: fix statistics read error 2025-11-07 7:43 [PATCH] net/ice: fix statistics read error Zhichao Zeng 2025-11-07 9:26 ` Bruce Richardson @ 2025-11-10 8:05 ` Zhichao Zeng 2025-11-12 12:04 ` Bruce Richardson 2025-11-13 7:47 ` [PATCH v3] " Zhichao Zeng 1 sibling, 2 replies; 7+ messages in thread From: Zhichao Zeng @ 2025-11-10 8:05 UTC (permalink / raw) To: dev Cc: stable, Zhichao Zeng, Bruce Richardson, Anatoly Burakov, Jeff Guo, Ferruh Yigit, Wenzhuo Lu 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 <zhichaox.zeng@intel.com> --- 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); } /** -- 2.34.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] net/ice: fix statistics read error 2025-11-10 8:05 ` [PATCH v2] " Zhichao Zeng @ 2025-11-12 12:04 ` Bruce Richardson 2025-11-13 7:18 ` 回复: " Zeng, ZhichaoX 2025-11-13 7:47 ` [PATCH v3] " Zhichao Zeng 1 sibling, 1 reply; 7+ messages in thread From: Bruce Richardson @ 2025-11-12 12:04 UTC (permalink / raw) To: Zhichao Zeng Cc: dev, stable, Anatoly Burakov, Jeff Guo, Ferruh Yigit, Wenzhuo Lu 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 <zhichaox.zeng@intel.com> > > --- > 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 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* 回复: [PATCH v2] net/ice: fix statistics read error 2025-11-12 12:04 ` Bruce Richardson @ 2025-11-13 7:18 ` Zeng, ZhichaoX 0 siblings, 0 replies; 7+ messages in thread From: Zeng, ZhichaoX @ 2025-11-13 7:18 UTC (permalink / raw) To: Richardson, Bruce Cc: dev, stable, Burakov, Anatoly, Jeff Guo, Ferruh Yigit, Wenzhuo Lu [-- Attachment #1: Type: text/plain, Size: 3089 bytes --] 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 <bruce.richardson@intel.com> 已发送: 2025 年 11 月 12 日 星期三 20:04 收件人: Zeng, ZhichaoX <zhichaox.zeng@intel.com> 抄送: dev@dpdk.org <dev@dpdk.org>; stable@dpdk.org <stable@dpdk.org>; Burakov, Anatoly <anatoly.burakov@intel.com>; Jeff Guo <jia.guo@intel.com>; Ferruh Yigit <ferruh.yigit@amd.com>; Wenzhuo Lu <wenzhuo.lu@intel.com> 主题: 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 <zhichaox.zeng@intel.com> > > --- > 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 > [-- Attachment #2: Type: text/html, Size: 7262 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] net/ice: fix statistics read error 2025-11-10 8:05 ` [PATCH v2] " Zhichao Zeng 2025-11-12 12:04 ` Bruce Richardson @ 2025-11-13 7:47 ` Zhichao Zeng 2025-11-13 8:42 ` Bruce Richardson 1 sibling, 1 reply; 7+ messages in thread From: Zhichao Zeng @ 2025-11-13 7:47 UTC (permalink / raw) To: dev Cc: stable, Zhichao Zeng, Bruce Richardson, Anatoly Burakov, Ferruh Yigit, Wenzhuo Lu, Jeff Guo 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 <zhichaox.zeng@intel.com> --- v2: replace single retries with loops v3: fix wrong logic --- drivers/net/intel/ice/ice_ethdev.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c index 4669eba7c7..5ec57ee2b0 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; -- 2.34.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] net/ice: fix statistics read error 2025-11-13 7:47 ` [PATCH v3] " Zhichao Zeng @ 2025-11-13 8:42 ` Bruce Richardson 0 siblings, 0 replies; 7+ messages in thread From: Bruce Richardson @ 2025-11-13 8:42 UTC (permalink / raw) To: Zhichao Zeng Cc: dev, stable, Anatoly Burakov, Ferruh Yigit, Wenzhuo Lu, Jeff Guo On Thu, Nov 13, 2025 at 03:47:10PM +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 <zhichaox.zeng@intel.com> > Acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-11-13 8:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-11-07 7:43 [PATCH] net/ice: fix statistics read error Zhichao Zeng 2025-11-07 9:26 ` Bruce Richardson 2025-11-10 8:05 ` [PATCH v2] " Zhichao Zeng 2025-11-12 12:04 ` Bruce Richardson 2025-11-13 7:18 ` 回复: " Zeng, ZhichaoX 2025-11-13 7:47 ` [PATCH v3] " Zhichao Zeng 2025-11-13 8:42 ` Bruce Richardson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).