mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
bonding: refine bond_fold_stats() wrap detection
[ Upstream commit142c6594ac] Some device drivers reset their stats at down/up events, possibly fooling bonding stats, since they operate with relative deltas. It is nearly not possible to fix drivers, since some of them compute the tx/rx counters based on per rx/tx queue stats, and the queues can be reconfigured (ethtool -L) between the down/up sequence. Lets avoid accumulating 'negative' values that render bonding stats useless. It is better to lose small deltas, assuming the bonding stats are fetched at a reasonable frequency. Fixes:5f0c5f73e5("bonding: make global bonding stats more reliable") Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5081260051
commit
8c989a6803
@@ -3331,12 +3331,17 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res,
|
||||
for (i = 0; i < sizeof(*_res) / sizeof(u64); i++) {
|
||||
u64 nv = new[i];
|
||||
u64 ov = old[i];
|
||||
s64 delta = nv - ov;
|
||||
|
||||
/* detects if this particular field is 32bit only */
|
||||
if (((nv | ov) >> 32) == 0)
|
||||
res[i] += (u32)nv - (u32)ov;
|
||||
else
|
||||
res[i] += nv - ov;
|
||||
delta = (s64)(s32)((u32)nv - (u32)ov);
|
||||
|
||||
/* filter anomalies, some drivers reset their stats
|
||||
* at down/up events.
|
||||
*/
|
||||
if (delta > 0)
|
||||
res[i] += delta;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user