There is a possibility of be_post_rx_frags() being called simultaneously from
both be_worker() (when rx_post_starved) and be_poll_rx() (when rxq->used is 0).
This can be avoided by posting rx buffers only when some completions have been
reaped.
Signed-off-by: Sathya Perla <redacted>
---
drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
@@ -298,7 +298,6 @@ struct be_adapter {u8__iomem*csr;u8__iomem*db;/* Door Bell */-u8__iomem*pcicfg;/* PCI config space */structmutexmbox_lock;/* For serializing mbox cmds to BE card */structbe_dma_memmbox_mem;
The rx_drops_no_frags HW counter for RSS rings is 16bits in HW and can
wraparound often. Maintain a 32-bit accumulator in the driver to prevent
frequent wraparound.
Signed-off-by: Sathya Perla <redacted>
---
drivers/net/ethernet/emulex/benet/be_main.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
@@ -394,9 +405,13 @@ void be_parse_stats(struct be_adapter *adapter)}/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */-for_all_rx_queues(adapter,rxo,i)-rx_stats(rxo)->rx_drops_no_frags=-erx->rx_drops_no_fragments[rxo->q.id];+for_all_rx_queues(adapter,rxo,i){+/* below erx HW counter can actually wrap around after+*65535.Driveraccumulatesa32-bitvalue+*/+accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,+(u16)erx->rx_drops_no_fragments[rxo->q.id]);+}}staticstructrtnl_link_stats64*be_get_stats64(structnet_device*netdev,
Flashing some of the PHYs can take longer thus increasing the total flash
update time to a max of 40s.
Signed-off-by: Sathya Perla <redacted>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
From: Eric Dumazet <hidden> Date: 2011-08-22 11:43:32
Le lundi 22 août 2011 à 16:43 +0530, Sathya Perla a écrit :
quoted hunk
The rx_drops_no_frags HW counter for RSS rings is 16bits in HW and can
wraparound often. Maintain a 32-bit accumulator in the driver to prevent
frequent wraparound.
Signed-off-by: Sathya Perla <redacted>
---
drivers/net/ethernet/emulex/benet/be_main.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
This adds a race for lockless SNMP readers (in be_get_stats64())
They can see the 32bit value going backward.
You have to be very careful to read the *acc once, and write it once.
From: Eric Dumazet <hidden> Date: 2011-08-22 11:47:36
Le lundi 22 août 2011 à 13:43 +0200, Eric Dumazet a écrit :
This adds a race for lockless SNMP readers (in be_get_stats64())
They can see the 32bit value going backward.
You have to be very careful to read the *acc once, and write it once.
The "write once" is the only requirement.
Something like :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
ACCESS_ONCE(*acc) = newval;
-----Original Message-----
From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
Sent: Monday, August 22, 2011 5:18 PM
Le lundi 22 août 2011 à 13:43 +0200, Eric Dumazet a écrit :
quoted
This adds a race for lockless SNMP readers (in be_get_stats64())
They can see the 32bit value going backward.
You have to be very careful to read the *acc once, and write it once.
The "write once" is the only requirement.
Something like :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
ACCESS_ONCE(*acc) = newval;
Eric,
I'm wondering why you'd need ACCESS_ONCE() here? Wouldn't using the temp variable (newval) as you suggested,
ensure that the reader doesn't see a half-baked value?
From: Eric Dumazet <hidden> Date: 2011-08-22 12:44:46
Le lundi 22 août 2011 à 05:15 -0700, Sathya.Perla@Emulex.Com a écrit :
quoted
-----Original Message-----
From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
Sent: Monday, August 22, 2011 5:18 PM
Le lundi 22 août 2011 à 13:43 +0200, Eric Dumazet a écrit :
quoted
This adds a race for lockless SNMP readers (in be_get_stats64())
They can see the 32bit value going backward.
You have to be very careful to read the *acc once, and write it once.
The "write once" is the only requirement.
Something like :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
ACCESS_ONCE(*acc) = newval;
Eric,
I'm wondering why you'd need ACCESS_ONCE() here? Wouldn't using the temp variable (newval) as you suggested,
ensure that the reader doesn't see a half-baked value?
If you write :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
*acc = newval;
C compiler (gcc) is free to eliminate the temp variable and to generate
same code than :
*acc = hi(*acc) + val;
if (wrapped)
*acc += 65536;
ACCESS_ONCE() here is the clean way (and self explanatory/documented) to
keep compiler to write to *acc twice.
OK, thanks Eric. I'll re-spin this patch series ...
-Sathya
________________________________________
From: Eric Dumazet [eric.dumazet@gmail.com]
Sent: Monday, August 22, 2011 6:14 PM
To: Perla, Sathya
Cc: netdev@vger.kernel.org
Subject: RE: [PATCH net-next 3/5] be2net: fix erx->rx_drops_no_frags wrap around
Le lundi 22 août 2011 à 05:15 -0700, Sathya.Perla@Emulex.Com a écrit :
quoted
-----Original Message-----
From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
Sent: Monday, August 22, 2011 5:18 PM
Le lundi 22 août 2011 à 13:43 +0200, Eric Dumazet a écrit :
quoted
This adds a race for lockless SNMP readers (in be_get_stats64())
They can see the 32bit value going backward.
You have to be very careful to read the *acc once, and write it once.
The "write once" is the only requirement.
Something like :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
ACCESS_ONCE(*acc) = newval;
Eric,
I'm wondering why you'd need ACCESS_ONCE() here? Wouldn't using the temp variable (newval) as you suggested,
ensure that the reader doesn't see a half-baked value?
If you write :
u32 newval = hi(*acc) + val;
if (wrapped)
newval += 65536;
*acc = newval;
C compiler (gcc) is free to eliminate the temp variable and to generate
same code than :
*acc = hi(*acc) + val;
if (wrapped)
*acc += 65536;
ACCESS_ONCE() here is the clean way (and self explanatory/documented) to
keep compiler to write to *acc twice.