All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Benjamin Segall" <bsegall@google.com>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH] perf: skew perf_mux_hrtimer_handler firing across cpus
Date: Thu, 29 Oct 2026 23:42:33 +0000	[thread overview]
Message-ID: <sashiko-outbox-190118@kernel.org> (raw)
In-Reply-To: <xm265wykhyrv.fsf@google.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] perf: data race on cpc->hrtimer_interval in perf_mux_hrtimer_handler()
--

commit 21db2df032d9ff638545ff8ead07c480ea100710
Author: Benjamin Segall <bsegall@google.com>

perf: skew perf_mux_hrtimer_handler firing across cpus

This commit adds a per-CPU skew offset to perf_mux_hrtimer_handler() when
the mux hrtimer interval changes so that timers across CPUs do not fire at
the same time and contend on jiffies_lock in nohz_full configurations.

> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index a6c8e38a31104..80d142986eba7 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -1279,6 +1279,7 @@ static enum hrtimer_restart perf_mux_hrtimer_handler(struct hrtimer *hr)
>  {
>  	struct perf_cpu_pmu_context *cpc;
>  	bool rotations;
> +	u64 offset;
>  
>  	lockdep_assert_irqs_disabled();
>  
> @@ -1286,6 +1287,17 @@ static enum hrtimer_restart perf_mux_hrtimer_handler(struct hrtimer *hr)
>  	rotations = perf_rotate_context(cpc);
>  
>  	raw_spin_lock(&cpc->hrtimer_lock);
> +	if (cpc->hrtimer_old_interval != cpc->hrtimer_interval) {
> +		/*
> +		 * Skew the timer to avoid contention on jiffies_lock in
> +		 * nohz_full, whenever we change interval
> +		 */
> +		offset = cpc->hrtimer_interval;
> +		do_div(offset, num_possible_cpus());
> +		offset *= smp_processor_id(); /* we are PINNED_HARD */
> +		hrtimer_set_expires(hr, offset);
> +		cpc->hrtimer_old_interval = cpc->hrtimer_interval;
> +	}
>  	if (rotations)
>  		hrtimer_forward_now(hr, cpc->hrtimer_interval);

[Severity: Medium]
Can a concurrent update to cpc->hrtimer_interval from
perf_event_mux_interval_ms_store() race with perf_mux_hrtimer_handler() and
leave the timer with a mismatched skew offset?

In kernel/events/core.c, perf_event_mux_interval_ms_store() updates
cpc->hrtimer_interval across all online CPUs from the sysfs writer CPU
without holding cpc->hrtimer_lock or using WRITE_ONCE():

	for_each_online_cpu(cpu) {
		struct perf_cpu_pmu_context *cpc;
		cpc = *per_cpu_ptr(pmu->cpu_pmu_context, cpu);
		cpc->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer);

		cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpc);
	}

Meanwhile, perf_mux_hrtimer_handler() reads cpc->hrtimer_interval multiple
times without READ_ONCE() or caching it in a local variable. Between reading
cpc->hrtimer_interval into offset and storing cpc->hrtimer_interval into
cpc->hrtimer_old_interval, calls such as do_div() and smp_processor_id()
(which calls debug_smp_processor_id() out-of-line when preemption debugging
is enabled) allow the compiler to reload cpc->hrtimer_interval from memory.

If perf_event_mux_interval_ms_store() modifies cpc->hrtimer_interval in that
window, offset can be computed from the previous interval while
cpc->hrtimer_old_interval records the newly written interval, preventing
subsequent timer callbacks from recomputing the skew for the new interval
(and potentially tearing the 64-bit ktime_t load on 32-bit architectures).

Should cpc->hrtimer_interval be accessed with WRITE_ONCE() and read once
into a local variable via READ_ONCE() (or updated under cpc->hrtimer_lock)?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/xm265wykhyrv.fsf@google.com?part=1

      reply	other threads:[~2026-10-29 23:42 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 23:28 [PATCH] perf: skew perf_mux_hrtimer_handler firing across cpus Benjamin Segall
2026-10-29 23:42 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-190118@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bsegall@google.com \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.