From: Alexander Graf <agraf@suse.de>
To: QEMU Developers <qemu-devel@nongnu.org>
Cc: Bharat Bhushan <bharat.bhushan@freescale.com>,
"qemu-ppc@nongnu.org list:PowerPC" <qemu-ppc@nongnu.org>,
Fabien Chouteau <chouteau@adacore.com>
Subject: [Qemu-devel] [PATCH 1/2] PPC: Make BookE FIT/WDT timers more lazy
Date: Sat, 23 Nov 2013 04:53:40 +0100 [thread overview]
Message-ID: <1385178821-1891-2-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1385178821-1891-1-git-send-email-agraf@suse.de>
Today we fire FIT and WDT timer events every time the respective bit
position in TB flips from 0 -> 1.
However, there is no need to do this if the end result would be that
we're changing a TSR bit that is set to 1 to 1 again. No guest visible
change would have occured.
So whenever we see that the TSR bit to our timer is already set, don't
even bother to update the timer that would potentially fire it off.
However, we do need to make sure that we update our timer that notifies
us of the TB flip when the respective TSR bit gets unset. In that case
we do care about the flip and need to notify the guest again. So add
a callback into our timer handlers when TSR bits get unset.
This improves performance for me when the guest is busy processing things.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppc/ppc_booke.c | 43 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c
index 8bbfc72..28cf9fd 100644
--- a/hw/ppc/ppc_booke.c
+++ b/hw/ppc/ppc_booke.c
@@ -128,7 +128,8 @@ static uint8_t booke_get_wdt_target(CPUPPCState *env, ppc_tb_t *tb_env)
static void booke_update_fixed_timer(CPUPPCState *env,
uint8_t target_bit,
uint64_t *next,
- struct QEMUTimer *timer)
+ struct QEMUTimer *timer,
+ int tsr_bit)
{
ppc_tb_t *tb_env = env->tb_env;
uint64_t delta_tick, ticks = 0;
@@ -136,6 +137,14 @@ static void booke_update_fixed_timer(CPUPPCState *env,
uint64_t period;
uint64_t now;
+ if (!env->spr[SPR_BOOKE_TSR] & tsr_bit) {
+ /*
+ * Don't arm the timer again when the guest has the current
+ * interrupt still pending. Wait for it to ack it.
+ */
+ return;
+ }
+
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
tb = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
period = 1ULL << target_bit;
@@ -167,6 +176,7 @@ static void booke_update_fixed_timer(CPUPPCState *env,
(*next)++;
}
+ /* Fire the next timer */
timer_mod(timer, *next);
}
@@ -200,7 +210,8 @@ static void booke_fit_cb(void *opaque)
booke_update_fixed_timer(env,
booke_get_fit_target(env, tb_env),
&booke_timer->fit_next,
- booke_timer->fit_timer);
+ booke_timer->fit_timer,
+ TSR_FIS);
}
static void booke_wdt_cb(void *opaque)
@@ -220,15 +231,35 @@ static void booke_wdt_cb(void *opaque)
booke_update_fixed_timer(env,
booke_get_wdt_target(env, tb_env),
&booke_timer->wdt_next,
- booke_timer->wdt_timer);
+ booke_timer->wdt_timer,
+ TSR_WIS);
}
void store_booke_tsr(CPUPPCState *env, target_ulong val)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ ppc_tb_t *tb_env = env->tb_env;
+ booke_timer_t *booke_timer = tb_env->opaque;
env->spr[SPR_BOOKE_TSR] &= ~val;
kvmppc_clear_tsr_bits(cpu, val);
+
+ if (val & TSR_FIS) {
+ booke_update_fixed_timer(env,
+ booke_get_fit_target(env, tb_env),
+ &booke_timer->fit_next,
+ booke_timer->fit_timer,
+ TSR_FIS);
+ }
+
+ if (val & TSR_WIS) {
+ booke_update_fixed_timer(env,
+ booke_get_wdt_target(env, tb_env),
+ &booke_timer->wdt_next,
+ booke_timer->wdt_timer,
+ TSR_WIS);
+ }
+
booke_update_irq(cpu);
}
@@ -247,12 +278,14 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
booke_update_fixed_timer(env,
booke_get_fit_target(env, tb_env),
&booke_timer->fit_next,
- booke_timer->fit_timer);
+ booke_timer->fit_timer,
+ TSR_FIS);
booke_update_fixed_timer(env,
booke_get_wdt_target(env, tb_env),
&booke_timer->wdt_next,
- booke_timer->wdt_timer);
+ booke_timer->wdt_timer,
+ TSR_WIS);
}
static void ppc_booke_timer_reset_handle(void *opaque)
--
1.7.12.4
next prev parent reply other threads:[~2013-11-23 3:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-23 3:53 [Qemu-devel] [PATCH 1.7 0/2] PPC: Fix BookE timer performance regression Alexander Graf
2013-11-23 3:53 ` Alexander Graf [this message]
2013-11-23 3:53 ` [Qemu-devel] [PATCH 2/2] PPC: BookE: Make FIT/WDT timers at best microsecond grained Alexander Graf
2013-11-23 4:08 ` [Qemu-devel] [PATCH 1.7 0/2] PPC: Fix BookE timer performance regression Stefan Weil
2013-11-23 4:43 ` Stefan Weil
2013-11-25 11:10 ` Alexander Graf
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=1385178821-1891-2-git-send-email-agraf@suse.de \
--to=agraf@suse.de \
--cc=bharat.bhushan@freescale.com \
--cc=chouteau@adacore.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.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;
as well as URLs for NNTP newsgroup(s).