From: Peter Zijlstra <peterz@infradead.org>
To: CodyYao-oc <CodyYao-oc@zhaoxin.com>
Cc: mingo@redhat.com, acme@kernel.org, mark.rutland@arm.com,
alexander.shishkin@linux.intel.com, jolsa@redhat.com,
namhyung@kernel.org, tglx@linutronix.de, bp@alien8.de,
hpa@zytor.com, x86@kernel.org, linux-kernel@vger.kernel.org,
cooperyan@zhaoxin.com
Subject: Re: [PATCH] x86/perf: Add hardware performance events support for Zhaoxin CPU.
Date: Tue, 31 Mar 2020 12:18:34 +0200 [thread overview]
Message-ID: <20200331101834.GP20730@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <1585647599-6649-1-git-send-email-CodyYao-oc@zhaoxin.com>
On Tue, Mar 31, 2020 at 05:39:59PM +0800, CodyYao-oc wrote:
> Zhaoxin CPU has provided facilities for monitoring performance
> via PMU(Performance Monitor Unit), but the functionality is unused so far.
> Therefore, add support for zhaoxin pmu to make performance related
> hardware events available.
This looks like an Intel Architectural PMU v2 or so, is that correct? Do
you have a link to documentation for your CPU?
> +static void zhaoxin_pmu_disable_all(void)
> +{
> + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
> +}
> +
> +static void zhaoxin_pmu_enable_all(int added)
> +{
> + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
> +}
> +
> +static inline u64 zhaoxin_pmu_get_status(void)
> +{
> + u64 status;
> +
> + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
> +
> + return status;
> +}
> +
> +static inline void zhaoxin_pmu_ack_status(u64 ack)
> +{
> + wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
> +}
> +static int zhaoxin_pmu_handle_irq(struct pt_regs *regs)
> +{
> + struct perf_sample_data data;
> + struct cpu_hw_events *cpuc;
> + int bit;
> + u64 status;
> + bool is_zxc;
> + int handled = 0;
> +
> + cpuc = this_cpu_ptr(&cpu_hw_events);
> + apic_write(APIC_LVTPC, APIC_DM_NMI);
> + zhaoxin_pmu_disable_all();
> + status = zhaoxin_pmu_get_status();
> + if (!status)
> + goto done;
> +
> + if (boot_cpu_data.x86 == 0x06 &&
> + (boot_cpu_data.x86_model == 0x0f ||
> + boot_cpu_data.x86_model == 0x19))
> + is_zxc = true;
> +again:
> +
> + /*Clearing status works only if the global control is enable on zxc.*/
> + if (is_zxc)
> + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
> +
> + zhaoxin_pmu_ack_status(status);
> +
> + if (is_zxc)
> + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
That's an unfortunate errata; perhaps write it like so:
static inline void zxc_pmu_ack_status(u64 status)
{
/*
* ZXC needs global control enabled in order to clear status bits.
*/
zhaoxin_pmu_enable_all(0);
zhaoxin_pmu_ack_status(status);
zhaoxin_pmu_disable_all();
}
if (is_zxc)
zxc_pmu_ack_status(status);
else
zhaoxin_pmu_ack_status(status);
Alternatively; you can do a whole zxc specific handle_irq() and move the
get/ack status before disable_all(). If you do that, then factor this:
> + /*
> + * CondChgd bit 63 doesn't mean any overflow status. Ignore
> + * and clear the bit.
> + */
> + if (__test_and_clear_bit(63, (unsigned long *)&status)) {
> + if (!status)
> + goto done;
> + }
> +
> + for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
> + struct perf_event *event = cpuc->events[bit];
> +
> + handled++;
> +
> + if (!test_bit(bit, cpuc->active_mask))
> + continue;
> +
> + x86_perf_event_update(event);
> + perf_sample_data_init(&data, 0, event->hw.last_period);
> +
> + if (!x86_perf_event_set_period(event))
> + continue;
> +
> + if (perf_event_overflow(event, &data, regs))
> + x86_pmu_stop(event, 0);
> + }
bit into it's own function so you don't have to duplicate it. Then the
two handle_irq() functions only differ in the status handling.
> +
> + /*
> + * Repeat if there is more work to be done:
> + */
> + status = zhaoxin_pmu_get_status();
> + if (status)
> + goto again;
> +
> +done:
> + zhaoxin_pmu_enable_all(0);
> + return handled;
> +}
next prev parent reply other threads:[~2020-03-31 10:18 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-31 9:39 CodyYao-oc
2020-03-31 10:18 ` Peter Zijlstra [this message]
2020-04-08 7:20 ` CodyYao-oc
2020-04-13 3:14 CodyYao-oc
2020-04-15 9:36 ` Borislav Petkov
2020-04-16 6:16 ` CodyYao-oc
2020-04-15 10:23 ` Peter Zijlstra
2020-04-15 10:31 ` Peter Zijlstra
2020-04-16 7:36 ` CodyYao-oc
2020-05-06 12:55 ` CodyYao-oc
2020-04-16 6:26 ` CodyYao-oc
2020-04-19 13:10 CodyYao-oc
2020-04-26 3:04 ` CodyYao-oc
2020-04-27 12:30 CodyYao-oc
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=20200331101834.GP20730@hirez.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=CodyYao-oc@zhaoxin.com \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=bp@alien8.de \
--cc=cooperyan@zhaoxin.com \
--cc=hpa@zytor.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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
Powered by JetHome