DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] net/i40e: fix counters
@ 2020-11-17  8:56 Igor Ryzhov
  2020-11-19 18:27 ` Igor Ryzhov
  2020-12-23  8:03 ` Zhang, Qi Z
  0 siblings, 2 replies; 7+ messages in thread
From: Igor Ryzhov @ 2020-11-17  8:56 UTC (permalink / raw)
  To: dev; +Cc: stable

When low and high registers are read separately, this opens the door to
a race condition:
- low register is read
- NIC updates the registers
- high register is read

Because of this, we may end up with an incorrect counter value.
Let's read the registers in one shot, as it is done in Linux kernel
since the introduction of the i40e driver.

Fixes: 4861cde46116 ("i40e: new poll mode driver")
Cc: stable@dpdk.org
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
---
 drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
 drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_osdep.h b/drivers/net/i40e/base/i40e_osdep.h
index 64b15e1b6138..ebd687240006 100644
--- a/drivers/net/i40e/base/i40e_osdep.h
+++ b/drivers/net/i40e/base/i40e_osdep.h
@@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
 	return rte_le_to_cpu_32(I40E_PCI_REG(addr));
 }
 
+#define I40E_PCI_REG64(reg)		rte_read64(reg)
+#define I40E_PCI_REG64_ADDR(a, reg) \
+	((volatile uint64_t *)((char *)(a)->hw_addr + (reg)))
+static inline uint64_t i40e_read64_addr(volatile void *addr)
+{
+	return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
+}
+
 #define I40E_PCI_REG_WRITE(reg, value)		\
 	rte_write32((rte_cpu_to_le_32(value)), reg)
 #define I40E_PCI_REG_WRITE_RELAXED(reg, value)	\
@@ -145,6 +153,8 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
 #define I40E_WRITE_REG(hw, reg, value) \
 	I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
 
+#define I40E_READ_REG64(hw, reg) i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
+
 #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
 #define wr32(a, reg, value) \
 	I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 74f4ac1f9d4e..53b1e9b9e067 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,
 {
 	uint64_t new_data;
 
-	new_data = (uint64_t)I40E_READ_REG(hw, loreg);
-	new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
-			I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
+	if (hw->device_id == I40E_DEV_ID_QEMU) {
+		new_data = (uint64_t)I40E_READ_REG(hw, loreg);
+		new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
+				I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
+	} else {
+		new_data = I40E_READ_REG64(hw, loreg);
+	}
 
 	if (!offset_loaded)
 		*offset = new_data;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-17  8:56 [dpdk-dev] [PATCH] net/i40e: fix counters Igor Ryzhov
@ 2020-11-19 18:27 ` Igor Ryzhov
  2020-11-24  3:34   ` Guo, Jia
  2020-12-23  8:03 ` Zhang, Qi Z
  1 sibling, 1 reply; 7+ messages in thread
From: Igor Ryzhov @ 2020-11-19 18:27 UTC (permalink / raw)
  To: dev; +Cc: dpdk stable, Beilei Xing, Guo, Jia, Thomas Monjalon

CC maintainers and Thomas.

This fix should be 20.11. The issue is seen multiple times a day under ~20G
traffic with stats collection once per second.

Igor

On Tue, Nov 17, 2020 at 11:56 AM Igor Ryzhov <iryzhov@nfware.com> wrote:

> When low and high registers are read separately, this opens the door to
> a race condition:
> - low register is read
> - NIC updates the registers
> - high register is read
>
> Because of this, we may end up with an incorrect counter value.
> Let's read the registers in one shot, as it is done in Linux kernel
> since the introduction of the i40e driver.
>
> Fixes: 4861cde46116 ("i40e: new poll mode driver")
> Cc: stable@dpdk.org
> Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
> ---
>  drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
>  drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
>  2 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/i40e/base/i40e_osdep.h
> b/drivers/net/i40e/base/i40e_osdep.h
> index 64b15e1b6138..ebd687240006 100644
> --- a/drivers/net/i40e/base/i40e_osdep.h
> +++ b/drivers/net/i40e/base/i40e_osdep.h
> @@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile void
> *addr)
>         return rte_le_to_cpu_32(I40E_PCI_REG(addr));
>  }
>
> +#define I40E_PCI_REG64(reg)            rte_read64(reg)
> +#define I40E_PCI_REG64_ADDR(a, reg) \
> +       ((volatile uint64_t *)((char *)(a)->hw_addr + (reg)))
> +static inline uint64_t i40e_read64_addr(volatile void *addr)
> +{
> +       return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
> +}
> +
>  #define I40E_PCI_REG_WRITE(reg, value)         \
>         rte_write32((rte_cpu_to_le_32(value)), reg)
>  #define I40E_PCI_REG_WRITE_RELAXED(reg, value) \
> @@ -145,6 +153,8 @@ static inline uint32_t i40e_read_addr(volatile void
> *addr)
>  #define I40E_WRITE_REG(hw, reg, value) \
>         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
>
> +#define I40E_READ_REG64(hw, reg)
> i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
> +
>  #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
>  #define wr32(a, reg, value) \
>         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
> diff --git a/drivers/net/i40e/i40e_ethdev.c
> b/drivers/net/i40e/i40e_ethdev.c
> index 74f4ac1f9d4e..53b1e9b9e067 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,
>  {
>         uint64_t new_data;
>
> -       new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> -       new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> -                       I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> +       if (hw->device_id == I40E_DEV_ID_QEMU) {
> +               new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> +               new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> +                               I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> +       } else {
> +               new_data = I40E_READ_REG64(hw, loreg);
> +       }
>
>         if (!offset_loaded)
>                 *offset = new_data;
> --
> 2.29.2
>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-19 18:27 ` Igor Ryzhov
@ 2020-11-24  3:34   ` Guo, Jia
  2020-11-24  8:24     ` Thomas Monjalon
  0 siblings, 1 reply; 7+ messages in thread
From: Guo, Jia @ 2020-11-24  3:34 UTC (permalink / raw)
  To: Igor Ryzhov, dev; +Cc: dpdk stable, Xing, Beilei, Thomas Monjalon

hi, igor ryzhov and Thomas

Since this remain issue is report recently and we need to reproduce the issue and evaluate the patch and guaranty no side affect for other case,
so I am not sure even I don't think it still have time window to hit 20.11. But whatever we have begin to check your patch for now on. What do you think so?


From: Igor Ryzhov <iryzhov@nfware.com>
Sent: Friday, November 20, 2020 2:27 AM
To: dev <dev@dpdk.org>
Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Thomas Monjalon <thomas@monjalon.net>
Subject: Re: [PATCH] net/i40e: fix counters

CC maintainers and Thomas.

This fix should be 20.11. The issue is seen multiple times a day under ~20G traffic with stats collection once per second.

Igor

On Tue, Nov 17, 2020 at 11:56 AM Igor Ryzhov <iryzhov@nfware.com<mailto:iryzhov@nfware.com>> wrote:
When low and high registers are read separately, this opens the door to
a race condition:
- low register is read
- NIC updates the registers
- high register is read

Because of this, we may end up with an incorrect counter value.
Let's read the registers in one shot, as it is done in Linux kernel
since the introduction of the i40e driver.

Fixes: 4861cde46116 ("i40e: new poll mode driver")
Cc: stable@dpdk.org<mailto:stable@dpdk.org>
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com<mailto:iryzhov@nfware.com>>
---
 drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
 drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_osdep.h b/drivers/net/i40e/base/i40e_osdep.h
index 64b15e1b6138..ebd687240006 100644
--- a/drivers/net/i40e/base/i40e_osdep.h
+++ b/drivers/net/i40e/base/i40e_osdep.h
@@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
        return rte_le_to_cpu_32(I40E_PCI_REG(addr));
 }

+#define I40E_PCI_REG64(reg)            rte_read64(reg)
+#define I40E_PCI_REG64_ADDR(a, reg) \
+       ((volatile uint64_t *)((char *)(a)->hw_addr + (reg)))
+static inline uint64_t i40e_read64_addr(volatile void *addr)
+{
+       return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
+}
+
 #define I40E_PCI_REG_WRITE(reg, value)         \
        rte_write32((rte_cpu_to_le_32(value)), reg)
 #define I40E_PCI_REG_WRITE_RELAXED(reg, value) \
@@ -145,6 +153,8 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
 #define I40E_WRITE_REG(hw, reg, value) \
        I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))

+#define I40E_READ_REG64(hw, reg) i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
+
 #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
 #define wr32(a, reg, value) \
        I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 74f4ac1f9d4e..53b1e9b9e067 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,
 {
        uint64_t new_data;

-       new_data = (uint64_t)I40E_READ_REG(hw, loreg);
-       new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
-                       I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
+       if (hw->device_id == I40E_DEV_ID_QEMU) {
+               new_data = (uint64_t)I40E_READ_REG(hw, loreg);
+               new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
+                               I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
+       } else {
+               new_data = I40E_READ_REG64(hw, loreg);
+       }

        if (!offset_loaded)
                *offset = new_data;
--
2.29.2

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-24  3:34   ` Guo, Jia
@ 2020-11-24  8:24     ` Thomas Monjalon
  2020-11-24  9:42       ` Zhang, Qi Z
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Monjalon @ 2020-11-24  8:24 UTC (permalink / raw)
  To: Igor Ryzhov, dev, Guo, Jia; +Cc: dpdk stable, Xing, Beilei, ferruh.yigit

I will follow the recommendation of Ferruh and i40e maintainers.
It is risky but it can be applied just before the release.


24/11/2020 04:34, Guo, Jia:
> hi, igor ryzhov and Thomas
> 
> Since this remain issue is report recently and we need to reproduce the issue and evaluate the patch and guaranty no side affect for other case,
> so I am not sure even I don't think it still have time window to hit 20.11. But whatever we have begin to check your patch for now on. What do you think so?
> 
> 
> From: Igor Ryzhov <iryzhov@nfware.com>
> Sent: Friday, November 20, 2020 2:27 AM
> To: dev <dev@dpdk.org>
> Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Thomas Monjalon <thomas@monjalon.net>
> Subject: Re: [PATCH] net/i40e: fix counters
> 
> CC maintainers and Thomas.
> 
> This fix should be 20.11. The issue is seen multiple times a day under ~20G traffic with stats collection once per second.
> 
> Igor
> 
> On Tue, Nov 17, 2020 at 11:56 AM Igor Ryzhov <iryzhov@nfware.com<mailto:iryzhov@nfware.com>> wrote:
> When low and high registers are read separately, this opens the door to
> a race condition:
> - low register is read
> - NIC updates the registers
> - high register is read
> 
> Because of this, we may end up with an incorrect counter value.
> Let's read the registers in one shot, as it is done in Linux kernel
> since the introduction of the i40e driver.
> 
> Fixes: 4861cde46116 ("i40e: new poll mode driver")
> Cc: stable@dpdk.org<mailto:stable@dpdk.org>
> Signed-off-by: Igor Ryzhov <iryzhov@nfware.com<mailto:iryzhov@nfware.com>>
> ---
>  drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
>  drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/i40e/base/i40e_osdep.h b/drivers/net/i40e/base/i40e_osdep.h
> index 64b15e1b6138..ebd687240006 100644
> --- a/drivers/net/i40e/base/i40e_osdep.h
> +++ b/drivers/net/i40e/base/i40e_osdep.h
> @@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
>         return rte_le_to_cpu_32(I40E_PCI_REG(addr));
>  }
> 
> +#define I40E_PCI_REG64(reg)            rte_read64(reg)
> +#define I40E_PCI_REG64_ADDR(a, reg) \
> +       ((volatile uint64_t *)((char *)(a)->hw_addr + (reg)))
> +static inline uint64_t i40e_read64_addr(volatile void *addr)
> +{
> +       return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
> +}
> +
>  #define I40E_PCI_REG_WRITE(reg, value)         \
>         rte_write32((rte_cpu_to_le_32(value)), reg)
>  #define I40E_PCI_REG_WRITE_RELAXED(reg, value) \
> @@ -145,6 +153,8 @@ static inline uint32_t i40e_read_addr(volatile void *addr)
>  #define I40E_WRITE_REG(hw, reg, value) \
>         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
> 
> +#define I40E_READ_REG64(hw, reg) i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
> +
>  #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
>  #define wr32(a, reg, value) \
>         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 74f4ac1f9d4e..53b1e9b9e067 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,
>  {
>         uint64_t new_data;
> 
> -       new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> -       new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> -                       I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> +       if (hw->device_id == I40E_DEV_ID_QEMU) {
> +               new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> +               new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> +                               I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> +       } else {
> +               new_data = I40E_READ_REG64(hw, loreg);
> +       }
> 
>         if (!offset_loaded)
>                 *offset = new_data;
> --
> 2.29.2
> 






^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-24  8:24     ` Thomas Monjalon
@ 2020-11-24  9:42       ` Zhang, Qi Z
  2020-11-24 10:07         ` Igor Ryzhov
  0 siblings, 1 reply; 7+ messages in thread
From: Zhang, Qi Z @ 2020-11-24  9:42 UTC (permalink / raw)
  To: Thomas Monjalon, Igor Ryzhov, dev, Guo, Jia
  Cc: dpdk stable, Xing, Beilei, Yigit, Ferruh



> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Tuesday, November 24, 2020 4:25 PM
> To: Igor Ryzhov <iryzhov@nfware.com>; dev <dev@dpdk.org>; Guo, Jia
> <jia.guo@intel.com>
> Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei <beilei.xing@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH] net/i40e: fix counters
> 
> I will follow the recommendation of Ferruh and i40e maintainers.
> It is risky but it can be applied just before the release.

I will suggest not to merge this patch in this release cycle, we need time to fully test it and it can always be captured in following LTS release if no issue be found.

Thanks
Qi
> 
> 
> 24/11/2020 04:34, Guo, Jia:
> > hi, igor ryzhov and Thomas
> >
> > Since this remain issue is report recently and we need to reproduce
> > the issue and evaluate the patch and guaranty no side affect for other case, so
> I am not sure even I don't think it still have time window to hit 20.11. But
> whatever we have begin to check your patch for now on. What do you think so?
> >
> >
> > From: Igor Ryzhov <iryzhov@nfware.com>
> > Sent: Friday, November 20, 2020 2:27 AM
> > To: dev <dev@dpdk.org>
> > Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei
> > <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Thomas Monjalon
> > <thomas@monjalon.net>
> > Subject: Re: [PATCH] net/i40e: fix counters
> >
> > CC maintainers and Thomas.
> >
> > This fix should be 20.11. The issue is seen multiple times a day under ~20G
> traffic with stats collection once per second.
> >
> > Igor
> >
> > On Tue, Nov 17, 2020 at 11:56 AM Igor Ryzhov
> <iryzhov@nfware.com<mailto:iryzhov@nfware.com>> wrote:
> > When low and high registers are read separately, this opens the door
> > to a race condition:
> > - low register is read
> > - NIC updates the registers
> > - high register is read
> >
> > Because of this, we may end up with an incorrect counter value.
> > Let's read the registers in one shot, as it is done in Linux kernel
> > since the introduction of the i40e driver.
> >
> > Fixes: 4861cde46116 ("i40e: new poll mode driver")
> > Cc: stable@dpdk.org<mailto:stable@dpdk.org>
> > Signed-off-by: Igor Ryzhov
> > <iryzhov@nfware.com<mailto:iryzhov@nfware.com>>
> > ---
> >  drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
> >  drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
> >  2 files changed, 17 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/i40e/base/i40e_osdep.h
> > b/drivers/net/i40e/base/i40e_osdep.h
> > index 64b15e1b6138..ebd687240006 100644
> > --- a/drivers/net/i40e/base/i40e_osdep.h
> > +++ b/drivers/net/i40e/base/i40e_osdep.h
> > @@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile void
> *addr)
> >         return rte_le_to_cpu_32(I40E_PCI_REG(addr));
> >  }
> >
> > +#define I40E_PCI_REG64(reg)            rte_read64(reg)
> > +#define I40E_PCI_REG64_ADDR(a, reg) \
> > +       ((volatile uint64_t *)((char *)(a)->hw_addr + (reg))) static
> > +inline uint64_t i40e_read64_addr(volatile void *addr) {
> > +       return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
> > +}
> > +
> >  #define I40E_PCI_REG_WRITE(reg, value)         \
> >         rte_write32((rte_cpu_to_le_32(value)), reg)  #define
> > I40E_PCI_REG_WRITE_RELAXED(reg, value) \ @@ -145,6 +153,8 @@ static
> > inline uint32_t i40e_read_addr(volatile void *addr)  #define
> > I40E_WRITE_REG(hw, reg, value) \
> >         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
> >
> > +#define I40E_READ_REG64(hw, reg)
> > +i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
> > +
> >  #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
> > #define wr32(a, reg, value) \
> >         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
> > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > b/drivers/net/i40e/i40e_ethdev.c index 74f4ac1f9d4e..53b1e9b9e067
> > 100644
> > --- a/drivers/net/i40e/i40e_ethdev.c
> > +++ b/drivers/net/i40e/i40e_ethdev.c
> > @@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,  {
> >         uint64_t new_data;
> >
> > -       new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> > -       new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> > -                       I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> > +       if (hw->device_id == I40E_DEV_ID_QEMU) {
> > +               new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> > +               new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> > +                               I40E_16_BIT_MASK)) <<
> I40E_32_BIT_WIDTH;
> > +       } else {
> > +               new_data = I40E_READ_REG64(hw, loreg);
> > +       }
> >
> >         if (!offset_loaded)
> >                 *offset = new_data;
> > --
> > 2.29.2
> >
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-24  9:42       ` Zhang, Qi Z
@ 2020-11-24 10:07         ` Igor Ryzhov
  0 siblings, 0 replies; 7+ messages in thread
From: Igor Ryzhov @ 2020-11-24 10:07 UTC (permalink / raw)
  To: Zhang, Qi Z
  Cc: Thomas Monjalon, dev, Guo, Jia, dpdk stable, Xing, Beilei, Yigit, Ferruh

This code is just ported from the Linux kernel where it is used for around
7 years, so I suppose it is pretty safe.
But of course, take your time to test it, I am fine with getting this in
the next LTS release.

Igor

On Tue, Nov 24, 2020 at 12:43 PM Zhang, Qi Z <qi.z.zhang@intel.com> wrote:

>
>
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> > Sent: Tuesday, November 24, 2020 4:25 PM
> > To: Igor Ryzhov <iryzhov@nfware.com>; dev <dev@dpdk.org>; Guo, Jia
> > <jia.guo@intel.com>
> > Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei <beilei.xing@intel.com>;
> Yigit,
> > Ferruh <ferruh.yigit@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH] net/i40e: fix counters
> >
> > I will follow the recommendation of Ferruh and i40e maintainers.
> > It is risky but it can be applied just before the release.
>
> I will suggest not to merge this patch in this release cycle, we need time
> to fully test it and it can always be captured in following LTS release if
> no issue be found.
>
> Thanks
> Qi
> >
> >
> > 24/11/2020 04:34, Guo, Jia:
> > > hi, igor ryzhov and Thomas
> > >
> > > Since this remain issue is report recently and we need to reproduce
> > > the issue and evaluate the patch and guaranty no side affect for other
> case, so
> > I am not sure even I don't think it still have time window to hit 20.11.
> But
> > whatever we have begin to check your patch for now on. What do you think
> so?
> > >
> > >
> > > From: Igor Ryzhov <iryzhov@nfware.com>
> > > Sent: Friday, November 20, 2020 2:27 AM
> > > To: dev <dev@dpdk.org>
> > > Cc: dpdk stable <stable@dpdk.org>; Xing, Beilei
> > > <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Thomas Monjalon
> > > <thomas@monjalon.net>
> > > Subject: Re: [PATCH] net/i40e: fix counters
> > >
> > > CC maintainers and Thomas.
> > >
> > > This fix should be 20.11. The issue is seen multiple times a day under
> ~20G
> > traffic with stats collection once per second.
> > >
> > > Igor
> > >
> > > On Tue, Nov 17, 2020 at 11:56 AM Igor Ryzhov
> > <iryzhov@nfware.com<mailto:iryzhov@nfware.com>> wrote:
> > > When low and high registers are read separately, this opens the door
> > > to a race condition:
> > > - low register is read
> > > - NIC updates the registers
> > > - high register is read
> > >
> > > Because of this, we may end up with an incorrect counter value.
> > > Let's read the registers in one shot, as it is done in Linux kernel
> > > since the introduction of the i40e driver.
> > >
> > > Fixes: 4861cde46116 ("i40e: new poll mode driver")
> > > Cc: stable@dpdk.org<mailto:stable@dpdk.org>
> > > Signed-off-by: Igor Ryzhov
> > > <iryzhov@nfware.com<mailto:iryzhov@nfware.com>>
> > > ---
> > >  drivers/net/i40e/base/i40e_osdep.h | 10 ++++++++++
> > >  drivers/net/i40e/i40e_ethdev.c     | 10 +++++++---
> > >  2 files changed, 17 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/net/i40e/base/i40e_osdep.h
> > > b/drivers/net/i40e/base/i40e_osdep.h
> > > index 64b15e1b6138..ebd687240006 100644
> > > --- a/drivers/net/i40e/base/i40e_osdep.h
> > > +++ b/drivers/net/i40e/base/i40e_osdep.h
> > > @@ -133,6 +133,14 @@ static inline uint32_t i40e_read_addr(volatile
> void
> > *addr)
> > >         return rte_le_to_cpu_32(I40E_PCI_REG(addr));
> > >  }
> > >
> > > +#define I40E_PCI_REG64(reg)            rte_read64(reg)
> > > +#define I40E_PCI_REG64_ADDR(a, reg) \
> > > +       ((volatile uint64_t *)((char *)(a)->hw_addr + (reg))) static
> > > +inline uint64_t i40e_read64_addr(volatile void *addr) {
> > > +       return rte_le_to_cpu_64(I40E_PCI_REG64(addr));
> > > +}
> > > +
> > >  #define I40E_PCI_REG_WRITE(reg, value)         \
> > >         rte_write32((rte_cpu_to_le_32(value)), reg)  #define
> > > I40E_PCI_REG_WRITE_RELAXED(reg, value) \ @@ -145,6 +153,8 @@ static
> > > inline uint32_t i40e_read_addr(volatile void *addr)  #define
> > > I40E_WRITE_REG(hw, reg, value) \
> > >         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
> > >
> > > +#define I40E_READ_REG64(hw, reg)
> > > +i40e_read64_addr(I40E_PCI_REG64_ADDR((hw), (reg)))
> > > +
> > >  #define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
> > > #define wr32(a, reg, value) \
> > >         I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
> > > diff --git a/drivers/net/i40e/i40e_ethdev.c
> > > b/drivers/net/i40e/i40e_ethdev.c index 74f4ac1f9d4e..53b1e9b9e067
> > > 100644
> > > --- a/drivers/net/i40e/i40e_ethdev.c
> > > +++ b/drivers/net/i40e/i40e_ethdev.c
> > > @@ -6451,9 +6451,13 @@ i40e_stat_update_48(struct i40e_hw *hw,  {
> > >         uint64_t new_data;
> > >
> > > -       new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> > > -       new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> > > -                       I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
> > > +       if (hw->device_id == I40E_DEV_ID_QEMU) {
> > > +               new_data = (uint64_t)I40E_READ_REG(hw, loreg);
> > > +               new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
> > > +                               I40E_16_BIT_MASK)) <<
> > I40E_32_BIT_WIDTH;
> > > +       } else {
> > > +               new_data = I40E_READ_REG64(hw, loreg);
> > > +       }
> > >
> > >         if (!offset_loaded)
> > >                 *offset = new_data;
> > > --
> > > 2.29.2
> > >
> >
> >
> >
> >
>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [PATCH] net/i40e: fix counters
  2020-11-17  8:56 [dpdk-dev] [PATCH] net/i40e: fix counters Igor Ryzhov
  2020-11-19 18:27 ` Igor Ryzhov
@ 2020-12-23  8:03 ` Zhang, Qi Z
  1 sibling, 0 replies; 7+ messages in thread
From: Zhang, Qi Z @ 2020-12-23  8:03 UTC (permalink / raw)
  To: Igor Ryzhov, dev; +Cc: stable



> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Igor Ryzhov
> Sent: Tuesday, November 17, 2020 4:57 PM
> To: dev@dpdk.org
> Cc: stable@dpdk.org
> Subject: [dpdk-dev] [PATCH] net/i40e: fix counters
> 
> When low and high registers are read separately, this opens the door to a race
> condition:
> - low register is read
> - NIC updates the registers
> - high register is read
> 
> Because of this, we may end up with an incorrect counter value.
> Let's read the registers in one shot, as it is done in Linux kernel since the
> introduction of the i40e driver.
> 
> Fixes: 4861cde46116 ("i40e: new poll mode driver")
> Cc: stable@dpdk.org
> Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

Applied to dpdk-next-net-intel.

Thanks
Qi

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-12-23  8:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17  8:56 [dpdk-dev] [PATCH] net/i40e: fix counters Igor Ryzhov
2020-11-19 18:27 ` Igor Ryzhov
2020-11-24  3:34   ` Guo, Jia
2020-11-24  8:24     ` Thomas Monjalon
2020-11-24  9:42       ` Zhang, Qi Z
2020-11-24 10:07         ` Igor Ryzhov
2020-12-23  8:03 ` Zhang, Qi Z

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).