On Fri, 2026-09-11 at 14:34 +0200, Tobias Schaffner wrote:
> Add a small primitive that records, per automaton edge, how long the
> monitor dwelled before taking it with a count, a sum and a maximum.
> 
> The counters are per-CPU and lock-free, so a monitor's hot path can
> update them without disabling interrupts and without perturbing the latency
> being measured. Keep the state and its entry timestamp in one word so
> nested transitions cannot charge a dwell to the wrong edge.
> 
> Signed-off-by: Tobias Schaffner <[email protected]>
> ---
>  include/rv/edge_stat.h | 69 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
>  create mode 100644 include/rv/edge_stat.h
> 
> diff --git a/include/rv/edge_stat.h b/include/rv/edge_stat.h

...
> +#define RV_STATE_BITS                8
> +#define RV_STATE_MASK                GENMASK(RV_STATE_BITS - 1, 0)
> +#define RV_TS_MASK           GENMASK(BITS_PER_LONG - RV_STATE_BITS - 1, 0)
> +
> +#define da_state_of(w)               ((unsigned int)((w) & RV_STATE_MASK))
> +#define da_ts_of(w)          ((u64)(w) >> RV_STATE_BITS)
> +#define da_state_pack(s, ts) (((((da_state_t)(ts)) & RV_TS_MASK) <<
> RV_STATE_BITS) | \
> +                              ((da_state_t)(s) & RV_STATE_MASK))

These are barely readable and error prone, can you use FIELD_GET()/FIELD_PREP()?

Thanks,
Gabriele

> +
> +static __always_inline
> +void rv_edge_stat_account(struct rv_edge_stat *s, u64 dwell_ns)
> +{
> +     s64 max;
> +     int i;
> +
> +     local64_inc(&s->count);
> +     local64_add(dwell_ns, &s->sum_ns);
> +
> +     /* Keep the largest dwell; bound retries if a nested update races us.
> */
> +     max = local64_read(&s->max_ns);
> +     for (i = 0; dwell_ns > (u64)max; i++) {
> +             if (i == MAX_DA_RETRY_RACING_EVENTS) {
> +                     WARN_ONCE(1, "rv: edge-stat max update exceeded %d
> retries\n",
> +                               MAX_DA_RETRY_RACING_EVENTS);
> +                     break;
> +             }
> +             if (local64_try_cmpxchg(&s->max_ns, &max, dwell_ns))
> +                     break;
> +     }
> +}
> +
> +#endif /* CONFIG_RV_EDGE_STAT */
> +
> +#endif /* _RV_EDGE_STAT_H */


Reply via email to