Linux Perf Users
 help / color / mirror / Atom feed
From: "Mi, Dapeng" <dapeng1.mi@linux.intel.com>
To: Zide Chen <zide.chen@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Andi Kleen <ak@linux.intel.com>,
	Eranian Stephane <eranian@google.com>
Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: Re: [PATCH V3 6/8] perf/x86/intel/uncore: Introduce PMU flags and broken state
Date: Fri, 12 Jun 2026 08:53:40 +0800	[thread overview]
Message-ID: <23c4488b-a264-49ac-99ed-4df75aa8ea84@linux.intel.com> (raw)
In-Reply-To: <20260611160033.66760-7-zide.chen@intel.com>

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>

Thanks.

On 6/12/2026 12:00 AM, Zide Chen wrote:
> Replace the boolean 'registered' field in intel_uncore_pmu with an
> unsigned long 'flags' field, and add a PMU_BROKEN flag to track box
> setup failures. The broken flag is sticky, meaning it is cleared only
> by a module reload or system reboot.
>
> Broken PMUs are skipped in the CPU hotplug and box allocation paths.
>
> When any box fails to initialize, the PMU is marked broken.  Broken
> PMUs reject new event assignments and skip future box setup attempts.
> If the PMU was already registered, it remains so to avoid disrupting
> in-flight events on other boxes.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> v3:
> - Fix typo stick->sticky and other cosmetic fixes in code comment.
> v2:
> - Make the broken flag sticky by using clear_bit() in
>   uncore_pmu_unregister() rather than zeroing out pmu->flags.
> - In uncore_change_type_ctx(), don't stop CPU migration on broken PMU
>   for in-flight events. (Sashiko).
> - Use box->cpu == -1 to identify inactive boxes that don't need
>   migration, no need to check uncore_die_has_box(), which is incomplete.
> ---
>  arch/x86/events/intel/uncore.c     | 44 ++++++++++++++++++++++--------
>  arch/x86/events/intel/uncore.h     | 13 ++++++++-
>  arch/x86/events/intel/uncore_snb.c |  2 +-
>  3 files changed, 46 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 06ef89f6ccc2..feb8c3b0076b 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -757,7 +757,7 @@ static int uncore_pmu_event_init(struct perf_event *event)
>  
>  	pmu = uncore_event_to_pmu(event);
>  	/* no device found for this pmu */
> -	if (!pmu->registered)
> +	if (!uncore_pmu_available(pmu))
>  		return -ENOENT;
>  
>  	/* Sampling not supported yet */
> @@ -953,16 +953,18 @@ static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
>  
>  	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
>  	if (!ret)
> -		pmu->registered = true;
> +		uncore_pmu_set_registered(pmu);
>  	return ret;
>  }
>  
>  static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
>  {
> -	if (!pmu->registered)
> +	if (!uncore_pmu_registered(pmu))
>  		return;
>  	perf_pmu_unregister(&pmu->pmu);
> -	pmu->registered = false;
> +
> +	/* Keep PMU_BROKEN_BIT sticky. */
> +	uncore_pmu_clear_registered(pmu);
>  }
>  
>  static void uncore_free_boxes(struct intel_uncore_pmu *pmu)
> @@ -1153,7 +1155,12 @@ static int uncore_box_setup(struct intel_uncore_pmu *pmu,
>  {
>  	int ret;
>  
> -	uncore_box_init(box);
> +	if (uncore_pmu_broken(pmu))
> +		return -ENODEV;
> +
> +	ret = uncore_box_init(box);
> +	if (ret)
> +		goto err;
>  
>  	/* First active box registers the pmu. */
>  	if (atomic_inc_return(&pmu->activeboxes) > 1)
> @@ -1167,6 +1174,16 @@ static int uncore_box_setup(struct intel_uncore_pmu *pmu,
>  
>  	return 0;
>  err:
> +	/*
> +	 * If any box fails, mark the per-package PMU as broken regardless of
> +	 * whether it was registered or not.
> +	 *
> +	 * Don't decrement refcnt to avoid other in-die CPUs from trying to set
> +	 * up the PMU box again.
> +	 *
> +	 * Don't kfree box; MSR and MMIO boxes are freed at module exit only.
> +	 */
> +	uncore_pmu_set_broken(pmu);
>  	uncore_box_exit(box);
>  	return ret;
>  }
> @@ -1190,8 +1207,10 @@ static int uncore_pci_pmu_register(struct pci_dev *pdev,
>  		return -EINVAL;
>  
>  	box = uncore_alloc_box(type, NUMA_NO_NODE);
> -	if (!box)
> +	if (!box) {
> +		uncore_pmu_set_broken(pmu);
>  		return -ENOMEM;
> +	}
>  
>  	atomic_inc(&box->refcnt);
>  	box->dieid = die;
> @@ -1507,7 +1526,8 @@ static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
>  
>  		if (old_cpu < 0) {
>  			WARN_ON_ONCE(box->cpu != -1);
> -			if (uncore_die_has_box(type, die, pmu->pmu_idx)) {
> +			if (uncore_die_has_box(type, die, pmu->pmu_idx) &&
> +			    !uncore_pmu_broken(pmu)) {
>  				box->cpu = new_cpu;
>  				cpumask_set_cpu(new_cpu, &pmu->cpu_mask);
>  			}
> @@ -1515,12 +1535,14 @@ static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
>  		}
>  
>  		WARN_ON_ONCE(box->cpu != -1 && box->cpu != old_cpu);
> -		box->cpu = -1;
>  		cpumask_clear_cpu(old_cpu, &pmu->cpu_mask);
> -		if (new_cpu < 0)
> +		if (new_cpu < 0) {
> +			box->cpu = -1;
>  			continue;
> +		}
>  
> -		if (!uncore_die_has_box(type, die, pmu->pmu_idx))
> +		/* An inactive box doesn't need migration. */
> +		if (box->cpu == -1)
>  			continue;
>  		uncore_pmu_cancel_hrtimer(box);
>  		perf_pmu_migrate_context(&pmu->pmu, old_cpu, new_cpu);
> @@ -1596,7 +1618,7 @@ static int allocate_boxes(struct intel_uncore_type **types,
>  		type = *types;
>  		pmu = type->pmus;
>  		for (i = 0; i < type->num_boxes; i++, pmu++) {
> -			if (pmu->boxes[die])
> +			if (pmu->boxes[die] || uncore_pmu_broken(pmu))
>  				continue;
>  			box = uncore_alloc_box(type, cpu_to_node(cpu));
>  			if (!box)
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index d732b87be0a9..0adb477d9708 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -146,13 +146,24 @@ struct intel_uncore_pmu {
>  	struct pmu			pmu;
>  	char				name[UNCORE_PMU_NAME_LEN];
>  	int				pmu_idx;
> -	bool				registered;
> +	unsigned long			flags;
>  	atomic_t			activeboxes;
>  	cpumask_t			cpu_mask;
>  	struct intel_uncore_type	*type;
>  	struct intel_uncore_box		**boxes;
>  };
>  
> +#define PMU_REGISTERED_BIT	0
> +#define PMU_BROKEN_BIT		1
> +
> +#define uncore_pmu_registered(pmu)	test_bit(PMU_REGISTERED_BIT, &(pmu)->flags)
> +#define uncore_pmu_broken(pmu)		test_bit(PMU_BROKEN_BIT, &(pmu)->flags)
> +#define uncore_pmu_available(pmu)	(uncore_pmu_registered(pmu) &&  \
> +					 !uncore_pmu_broken(pmu))
> +#define uncore_pmu_set_registered(pmu)	set_bit(PMU_REGISTERED_BIT, &(pmu)->flags)
> +#define uncore_pmu_set_broken(pmu)	set_bit(PMU_BROKEN_BIT, &(pmu)->flags)
> +#define uncore_pmu_clear_registered(pmu) clear_bit(PMU_REGISTERED_BIT, &(pmu)->flags)
> +
>  struct intel_uncore_extra_reg {
>  	raw_spinlock_t lock;
>  	u64 config, config1, config2;
> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
> index c5347920541c..055131c508ff 100644
> --- a/arch/x86/events/intel/uncore_snb.c
> +++ b/arch/x86/events/intel/uncore_snb.c
> @@ -940,7 +940,7 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
>  
>  	pmu = uncore_event_to_pmu(event);
>  	/* no device found for this pmu */
> -	if (!pmu->registered)
> +	if (!uncore_pmu_available(pmu))
>  		return -ENOENT;
>  
>  	/* Sampling not supported yet */

  parent reply	other threads:[~2026-06-12  0:53 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11 16:00 [PATCH v3 0/8] perf/x86/intel/uncore: PMU setup robustness fixes Zide Chen
2026-06-11 16:00 ` [PATCH V3 1/8] perf/x86/intel/uncore: Fix PCI PMU cleanup on setup failure Zide Chen
2026-06-11 16:26   ` sashiko-bot
2026-06-11 16:00 ` [PATCH V3 2/8] perf/x86/intel/uncore: Fix refcnt and other cleanups Zide Chen
2026-06-11 16:29   ` sashiko-bot
2026-06-12  0:52   ` Mi, Dapeng
2026-06-11 16:00 ` [PATCH V3 3/8] perf/x86/intel/uncore: Let init_box() callback report failures Zide Chen
2026-06-11 16:38   ` sashiko-bot
2026-06-11 16:00 ` [PATCH V3 4/8] perf/x86/intel/uncore: Keep PCI PMUs working when MMIO/MSR setup fails Zide Chen
2026-06-11 16:00 ` [PATCH V3 5/8] perf/x86/intel/uncore: Factor out box setup code Zide Chen
2026-06-11 16:00 ` [PATCH V3 6/8] perf/x86/intel/uncore: Introduce PMU flags and broken state Zide Chen
2026-06-11 16:30   ` sashiko-bot
2026-06-12  0:53   ` Mi, Dapeng [this message]
2026-06-11 16:00 ` [PATCH V3 7/8] perf/x86/intel/uncore: Fix uncore_box ref/unref ordering Zide Chen
2026-06-11 16:29   ` sashiko-bot
2026-06-12  0:55   ` Mi, Dapeng
2026-06-11 16:00 ` [PATCH V3 8/8] perf/x86/intel/uncore: Implement lazy setup for MSR/MMIO PMUs Zide Chen
2026-06-11 16:33   ` sashiko-bot

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=23c4488b-a264-49ac-99ed-4df75aa8ea84@linux.intel.com \
    --to=dapeng1.mi@linux.intel.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=eranian@google.com \
    --cc=irogers@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=zide.chen@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox