From: David Gibson <david@gibson.dropbear.id.au>
To: Daniel Henrique Barboza <danielhb413@gmail.com>
Cc: richard.henderson@linaro.org, qemu-ppc@nongnu.org,
qemu-devel@nongnu.org, clg@kaod.org
Subject: Re: [PATCH v8 05/10] target/ppc: enable PMU counter overflow with cycle events
Date: Mon, 29 Nov 2021 14:41:36 +1100 [thread overview]
Message-ID: <YaRL8OEPdjVyed2t@yekko> (raw)
In-Reply-To: <20211125150817.573204-6-danielhb413@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6356 bytes --]
On Thu, Nov 25, 2021 at 12:08:12PM -0300, Daniel Henrique Barboza wrote:
65;6601;1c> The PowerISA v3.1 defines that if the proper bits are set (MMCR0_PMC1CE
> for PMC1 and MMCR0_PMCjCE for the remaining PMCs), counter negative
> conditions are enabled. This means that if the counter value overflows
> (i.e. exceeds 0x80000000) a performance monitor alert will occur. This alert
> can trigger an event-based exception (to be implemented in the next patches)
> if the MMCR0_EBE bit is set.
>
> For now, overflowing the counter when the PMC is counting cycles will
> just trigger a performance monitor alert. This is done by starting the
> overflow timer to expire in the moment the overflow would be occuring. The
> timer will call fire_PMC_interrupt() (via cpu_ppc_pmu_timer_cb) which will
> trigger the PMU alert and, if the conditions are met, an EBB exception.
>
> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
A couple of minor nits noted below, though.
> ---
> target/ppc/cpu.h | 2 ++
> target/ppc/power8-pmu.c | 80 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+)
>
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 9c732953f0..9b41b022e2 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -364,6 +364,8 @@ typedef enum {
> #define MMCR0_PMCC PPC_BITMASK(44, 45) /* PMC Control */
> #define MMCR0_FC14 PPC_BIT(58) /* PMC Freeze Counters 1-4 bit */
> #define MMCR0_FC56 PPC_BIT(59) /* PMC Freeze Counters 5-6 bit */
> +#define MMCR0_PMC1CE PPC_BIT(48) /* MMCR0 PMC1 Condition Enabled */
> +#define MMCR0_PMCjCE PPC_BIT(49) /* MMCR0 PMCj Condition Enabled */
> /* MMCR0 userspace r/w mask */
> #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
> /* MMCR2 userspace r/w mask */
> diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
> index acdaee7459..01e0b9b8fc 100644
> --- a/target/ppc/power8-pmu.c
> +++ b/target/ppc/power8-pmu.c
> @@ -23,6 +23,8 @@
>
> #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
>
> +#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL
> +
> static bool pmc_is_inactive(CPUPPCState *env, int sprn)
> {
> if (env->spr[SPR_POWER_MMCR0] & MMCR0_FC) {
> @@ -36,6 +38,15 @@ static bool pmc_is_inactive(CPUPPCState *env, int sprn)
> return env->spr[SPR_POWER_MMCR0] & MMCR0_FC56;
> }
>
> +static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
> +{
> + if (sprn == SPR_POWER_PMC1) {
> + return env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE;
> + }
> +
> + return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
> +}
> +
> /*
> * For PMCs 1-4, IBM POWER chips has support for an implementation
> * dependent event, 0x1E, that enables cycle counting. The Linux kernel
> @@ -123,6 +134,70 @@ static void pmu_update_cycles(CPUPPCState *env)
> env->pmu_base_time = now;
> }
>
> +/*
> + * Helper function to retrieve the cycle overflow timer of the
> + * 'sprn' counter. Given that PMC5 doesn't have a timer, the
> + * amount of timers is less than the total counters and the PMC6
> + * timer is the last of the array.
> + */
> +static QEMUTimer *get_cyc_overflow_timer(CPUPPCState *env, int sprn)
> +{
> + if (sprn == SPR_POWER_PMC5) {
> + return NULL;
Given that the entries in the pmu_cyc_overflow_timers are just
pointers, it would probably be slightly cheaper in terms of both time
and space to just have an always-NULL entry for PMC5, rather than
having to special case it.
> + }
> +
> + if (sprn == SPR_POWER_PMC6) {
> + return env->pmu_cyc_overflow_timers[PMU_TIMERS_NUM - 1];
> + }
> +
> + return env->pmu_cyc_overflow_timers[sprn - SPR_POWER_PMC1];
> +}
> +
> +static void pmc_update_overflow_timer(CPUPPCState *env, int sprn)
> +{
> + QEMUTimer *pmc_overflow_timer;
> + int64_t timeout;
> +
> + /* PMC5 does not have an overflow timer */
> + if (sprn == SPR_POWER_PMC5) {
> + return;
Since you've already handled the PMC5 case in
get_cyc_overflow_timer(), you could replace this handling with just an
if (!pmc_overflow_timer) {return;}
> + }
> +
> + pmc_overflow_timer = get_cyc_overflow_timer(env, sprn);
> +
> + if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES ||
> + !pmc_has_overflow_enabled(env, sprn)) {
> + /* Overflow timer is not needed for this counter */
> + timer_del(pmc_overflow_timer);
> + return;
> + }
> +
> + if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL) {
> + timeout = 0;
> + } else {
> + timeout = PMC_COUNTER_NEGATIVE_VAL - env->spr[sprn];
> + }
> +
> + /*
> + * Use timer_mod_anticipate() because an overflow timer might
> + * be already running for this PMC.
> + */
> + timer_mod_anticipate(pmc_overflow_timer, env->pmu_base_time + timeout);
> +}
> +
> +static void pmu_update_overflow_timers(CPUPPCState *env)
> +{
> + int sprn;
> +
> + /*
> + * Scroll through all PMCs and start counter overflow timers for
> + * PM_CYC events, if needed.
> + */
> + for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
> + pmc_update_overflow_timer(env, sprn);
> + }
> +}
> +
> void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
> {
> target_ulong curr_value = env->spr[SPR_POWER_MMCR0];
> @@ -143,6 +218,9 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
> (curr_FC != new_FC)) {
> hreg_compute_hflags(env);
> }
> +
> + /* Update cycle overflow timers with the current MMCR0 state */
> + pmu_update_overflow_timers(env);
> }
>
> void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
> @@ -164,6 +242,8 @@ void helper_store_pmc(CPUPPCState *env, uint32_t sprn, uint64_t value)
> pmu_update_cycles(env);
>
> env->spr[sprn] = value;
> +
> + pmc_update_overflow_timer(env, sprn);
> }
>
> static void fire_PMC_interrupt(PowerPCCPU *cpu)
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2021-11-29 4:28 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-25 15:08 [PATCH v8 00/10] PMU-EBB support for PPC64 TCG Daniel Henrique Barboza
2021-11-25 15:08 ` [PATCH v8 01/10] target/ppc: introduce PMUEventType and PMU overflow timers Daniel Henrique Barboza
2021-11-25 15:08 ` [PATCH v8 02/10] target/ppc: PMU basic cycle count for pseries TCG Daniel Henrique Barboza
2021-11-26 2:17 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 03/10] target/ppc: PMU: update counters on PMCs r/w Daniel Henrique Barboza
2021-11-26 2:24 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 04/10] target/ppc: PMU: update counters on MMCR1 write Daniel Henrique Barboza
2021-11-26 2:24 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 05/10] target/ppc: enable PMU counter overflow with cycle events Daniel Henrique Barboza
2021-11-29 3:41 ` David Gibson [this message]
2021-11-25 15:08 ` [PATCH v8 06/10] target/ppc: enable PMU instruction count Daniel Henrique Barboza
2021-11-29 4:36 ` David Gibson
2021-11-30 22:24 ` Daniel Henrique Barboza
2021-11-30 23:52 ` David Gibson
2021-12-01 13:12 ` Daniel Henrique Barboza
2021-12-02 1:23 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 07/10] target/ppc/power8-pmu.c: add PM_RUN_INST_CMPL (0xFA) event Daniel Henrique Barboza
2021-11-30 0:33 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 08/10] PPC64/TCG: Implement 'rfebb' instruction Daniel Henrique Barboza
2021-11-30 4:11 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 09/10] target/ppc: PMU Event-Based exception support Daniel Henrique Barboza
2021-11-30 4:15 ` David Gibson
2021-11-25 15:08 ` [PATCH v8 10/10] target/ppc/excp_helper.c: EBB handling adjustments Daniel Henrique Barboza
2021-11-30 4:17 ` David Gibson
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=YaRL8OEPdjVyed2t@yekko \
--to=david@gibson.dropbear.id.au \
--cc=clg@kaod.org \
--cc=danielhb413@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=richard.henderson@linaro.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 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.