Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b45adcd authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf/x86/amd: Rework AMD PMU init code



Josh reported that his QEMU is a bad hardware emulator and trips a
WARN in the AMD PMU init code. He requested the WARN be turned into a
pr_err() or similar.

While there, rework the code a little.

Reported-by: default avatarJosh Boyer <jwboyer@redhat.com>
Acked-by: default avatarRobert Richter <rric@kernel.org>
Acked-by: default avatarJacob Shin <jacob.shin@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20130521110537.GG26912@twins.programming.kicks-ass.net


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 2b923c8f
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -648,48 +648,48 @@ static __initconst const struct x86_pmu amd_pmu = {
	.cpu_dead		= amd_pmu_cpu_dead,
};

static int setup_event_constraints(void)
static int __init amd_core_pmu_init(void)
{
	if (boot_cpu_data.x86 == 0x15)
		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
	if (!cpu_has_perfctr_core)
		return 0;
}

static int setup_perfctr_core(void)
{
	if (!cpu_has_perfctr_core) {
		WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h,
		     KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!");
	switch (boot_cpu_data.x86) {
	case 0x15:
		pr_cont("Fam15h ");
		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
		break;

	default:
		pr_err("core perfctr but no constraints; unknown hardware!\n");
		return -ENODEV;
	}

	WARN(x86_pmu.get_event_constraints == amd_get_event_constraints,
	     KERN_ERR "hw perf events core counters need constraints handler!");

	/*
	 * If core performance counter extensions exists, we must use
	 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
	 * x86_pmu_addr_offset().
	 * amd_pmu_addr_offset().
	 */
	x86_pmu.eventsel	= MSR_F15H_PERF_CTL;
	x86_pmu.perfctr		= MSR_F15H_PERF_CTR;
	x86_pmu.num_counters	= AMD64_NUM_COUNTERS_CORE;

	printk(KERN_INFO "perf: AMD core performance counters detected\n");

	pr_cont("core perfctr, ");
	return 0;
}

__init int amd_pmu_init(void)
{
	int ret;

	/* Performance-monitoring supported from K7 and later: */
	if (boot_cpu_data.x86 < 6)
		return -ENODEV;

	x86_pmu = amd_pmu;

	setup_event_constraints();
	setup_perfctr_core();
	ret = amd_core_pmu_init();
	if (ret)
		return ret;

	/* Events are common for all AMDs */
	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,