Re: [PATCH] perf/x86: check ucode before disabling PEBS on SandyBridge

From: Stephane Eranian
Date: Tue Jun 12 2012 - 13:09:16 EST


On Tue, Jun 12, 2012 at 7:07 PM, Robert Richter <robert.richter@xxxxxxx> wrote:
> On 08.06.12 15:26:12, Peter Zijlstra wrote:
>> +static const u32 snb_ucode_rev = 0x28;
>> +
>> +static void intel_snb_verify_ucode(void)
>> +{
>> + Â Â u32 rev = UINT_MAX;
>> + Â Â int pebs_broken = 0;
>> + Â Â int cpu;
>> +
>> + Â Â get_online_cpus();
>> + Â Â /*
>> + Â Â Â* Because the microcode loader is bloody stupid and allows different
>> + Â Â Â* revisions per cpu and does strictly per-cpu loading, we now have to
>> + Â Â Â* check all cpus to determine the minimally installed revision.
>> + Â Â Â*
>> + Â Â Â* This makes updating the microcode O(n^2) in the number of CPUs :/
>> + Â Â Â*/
>> + Â Â for_each_online_cpu(cpu)
>> + Â Â Â Â Â Â rev = min(cpu_data(cpu).microcode, rev);
>> + Â Â put_online_cpus();
>> +
>> + Â Â pebs_broken = (rev < snb_ucode_rev);
>> +
>> + Â Â if (pebs_broken == x86_pmu.pebs_broken)
>> + Â Â Â Â Â Â return;
>> +
>> + Â Â /*
>> + Â Â Â* Serialized by the microcode lock..
>> + Â Â Â*/
>> + Â Â if (x86_pmu.pebs_broken) {
>> + Â Â Â Â Â Â pr_info("PEBS enabled due to micro-code update\n");
>> + Â Â Â Â Â Â x86_pmu.pebs_broken = 0;
>> + Â Â } else {
>> + Â Â Â Â Â Â pr_info("PEBS disabled due to CPU errata, "
>> + Â Â Â Â Â Â Â Â Â Â "please upgrade micro-code to at least %x (current: %x)\n",
>> + Â Â Â Â Â Â Â Â Â Â snb_ucode_rev, rev);
>> + Â Â Â Â Â Â x86_pmu.pebs_broken = 1;
>> + Â Â }
>> +}
>> +
>> +static int intel_snb_ucode_notifier(struct notifier_block *self,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âunsigned long action, void *_uci)
>> +{
>> + Â Â /*
>> + Â Â Â* Since ucode cannot be down-graded, and no future ucode revision
>> + Â Â Â* is known to break PEBS again, we're ok with MICROCODE_CAN_UPDATE.
>> + Â Â Â*/
>> +
>> + Â Â if (action == MICROCODE_UPDATED)
>> + Â Â Â Â Â Â intel_snb_verify_ucode();
>> +
>> + Â Â return NOTIFY_DONE;
>> +}
>> +
>> Âstatic __init void intel_sandybridge_quirk(void)
>> Â{
>> - Â Â pr_warn("PEBS disabled due to CPU errata\n");
>> - Â Â x86_pmu.pebs = 0;
>> - Â Â x86_pmu.pebs_constraints = NULL;
>> + Â Â intel_snb_verify_ucode();
>> + Â Â /*
>> + Â Â Â* we're still single threaded, so while there's a hole here,
>> + Â Â Â* you can't trigger it.
>> + Â Â Â*/
>> + Â Â microcode_notifier(intel_snb_ucode_notifier);
>> Â}
>
> Instead of registering a microcode notifier, why not checking the
> availability of pebs dynamically with each syscall in
> intel_pmu_hw_config()? It looks like intel_snb_verify_ucode() is not
> that much expensive. We can perform the check only if the event could
> be for pebs and if pebs is broken. The check could be repeated when
> setting up a new event after ucode could potentially has been updated
> (e.g. after bringing a cpu online or so).
>
That's what I had in my original version.

> -Robert
>
>
> --
> Advanced Micro Devices, Inc.
> Operating System Research Center
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/