mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
can: proc: skip stats calculation after reset in can_stat_update()
Commit80b5f90158("can: statistics: use atomic access in hot path") introduced local snapshots of the statistics counters at the beginning of can_stat_update(). When can_init_stats() resets the statistics, these stale pre-reset snapshots are still used for the following total/current /max calculations and overwrite the freshly reset values. Additionally a jiffies tick between the snapshot and the reset could trigger a second can_init_stats() call. Merge the reset conditions into a single check and skip the calculation for the current interval when the statistics have been reset. Fixes:80b5f90158("can: statistics: use atomic access in hot path") Cc: stable@vger.kernel.org Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Link: https://patch.msgid.link/20261027-can-rx-lock-v12-6-eb5afc2d8b9b@hartkopp.net Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
12297f855b
commit
01b19ed9fa
|
|
@ -149,25 +149,18 @@ void can_stat_update(struct timer_list *t)
|
|||
long tx_frames_delta = atomic_long_xchg(&pkg_stats->tx_frames_delta, 0);
|
||||
long matches_delta = atomic_long_xchg(&pkg_stats->matches_delta, 0);
|
||||
|
||||
/* restart counting in timer context on user request */
|
||||
if (user_reset)
|
||||
can_init_stats(net);
|
||||
|
||||
/* restart counting on jiffies overflow */
|
||||
if (j < pkg_stats->jiffies_init)
|
||||
can_init_stats(net);
|
||||
|
||||
/* prevent overflow in calc_rate() */
|
||||
if (rx_frames > (LONG_MAX / HZ))
|
||||
can_init_stats(net);
|
||||
|
||||
/* prevent overflow in calc_rate() */
|
||||
if (tx_frames > (LONG_MAX / HZ))
|
||||
can_init_stats(net);
|
||||
|
||||
/* matches overflow - very improbable */
|
||||
if (matches > (LONG_MAX / 100))
|
||||
/*
|
||||
* Restart counting in timer context on user request, on jiffies
|
||||
* overflow or to prevent overflows in calc_rate() and in the
|
||||
* match ratio calculation. The local snapshots are stale after
|
||||
* the reset, so skip the calculation for this interval.
|
||||
*/
|
||||
if (user_reset || j < pkg_stats->jiffies_init ||
|
||||
rx_frames > (LONG_MAX / HZ) || tx_frames > (LONG_MAX / HZ) ||
|
||||
matches > (LONG_MAX / 100)) {
|
||||
can_init_stats(net);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* calc total values */
|
||||
if (rx_frames)
|
||||
|
|
@ -196,6 +189,7 @@ void can_stat_update(struct timer_list *t)
|
|||
if (pkg_stats->max_rx_match_ratio < pkg_stats->current_rx_match_ratio)
|
||||
pkg_stats->max_rx_match_ratio = pkg_stats->current_rx_match_ratio;
|
||||
|
||||
out:
|
||||
/* restart timer (one second) */
|
||||
mod_timer(&net->can.stattimer, round_jiffies(jiffies + HZ));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user