On Thu, Aug 01, 2024 at 04:58:17AM +0000, Mingwei Zhang wrote: > From: Kan Liang <kan.liang@xxxxxxxxxxxxxxx> > > The current perf tracks two timestamps for the normal ctx and cgroup. > The same type of variables and similar codes are used to track the > timestamps. In the following patch, the third timestamp to track the > guest time will be introduced. > To avoid the code duplication, add a new struct perf_time_ctx and factor > out a generic function update_perf_time_ctx(). > > No functional change. > > Suggested-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> > Signed-off-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx> > Signed-off-by: Mingwei Zhang <mizhang@xxxxxxxxxx> --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -801,11 +801,22 @@ static inline u64 perf_cgroup_event_time return now; } -static inline void update_perf_time_ctx(struct perf_time_ctx *time, u64 now, bool adv); - -static inline void __update_cgrp_time(struct perf_cgroup_info *info, u64 now, bool adv) +static inline void update_perf_time_ctx(struct perf_time_ctx *time, u64 now, bool adv) { - update_perf_time_ctx(&info->time, now, adv); + if (adv) + time->time += now - time->stamp; + time->stamp = now; + + /* + * The above: time' = time + (now - timestamp), can be re-arranged + * into: time` = now + (time - timestamp), which gives a single value + * offset to compute future time without locks on. + * + * See perf_event_time_now(), which can be used from NMI context where + * it's (obviously) not possible to acquire ctx->lock in order to read + * both the above values in a consistent manner. + */ + WRITE_ONCE(time->offset, time->time - time->stamp); } static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx, bool final) @@ -821,7 +832,7 @@ static inline void update_cgrp_time_from cgrp = container_of(css, struct perf_cgroup, css); info = this_cpu_ptr(cgrp->info); - __update_cgrp_time(info, now, true); + update_perf_time_ctx(&info->time, now, true); if (final) __store_release(&info->active, 0); } @@ -844,7 +855,7 @@ static inline void update_cgrp_time_from * Do not update time when cgroup is not active */ if (info->active) - __update_cgrp_time(info, perf_clock(), true); + update_perf_time_ctx(&info->time, perf_clock(), true); } static inline void @@ -868,7 +879,7 @@ perf_cgroup_set_timestamp(struct perf_cp for (css = &cgrp->css; css; css = css->parent) { cgrp = container_of(css, struct perf_cgroup, css); info = this_cpu_ptr(cgrp->info); - __update_cgrp_time(info, ctx->time.stamp, false); + update_perf_time_ctx(&info->time, ctx->time.stamp, false); __store_release(&info->active, 1); } } @@ -1478,24 +1489,6 @@ static void perf_unpin_context(struct pe raw_spin_unlock_irqrestore(&ctx->lock, flags); } -static inline void update_perf_time_ctx(struct perf_time_ctx *time, u64 now, bool adv) -{ - if (adv) - time->time += now - time->stamp; - time->stamp = now; - - /* - * The above: time' = time + (now - timestamp), can be re-arranged - * into: time` = now + (time - timestamp), which gives a single value - * offset to compute future time without locks on. - * - * See perf_event_time_now(), which can be used from NMI context where - * it's (obviously) not possible to acquire ctx->lock in order to read - * both the above values in a consistent manner. - */ - WRITE_ONCE(time->offset, time->time - time->stamp); -} - /* * Update the record of the current time in a context. */