From: "Torbjörn Andersson" <tobbe.tt@home.se>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Less interrupt overhead patch
Date: Sun, 9 Nov 2008 22:21:37 +0100 [thread overview]
Message-ID: <005301c942b1$27625490$7626fdb0$@tt@home.se> (raw)
Hi all.
I have been using QEMU for some time now and I have found that interrupts
cost more than necessary.
The TB-chaining is lost, at least partially, at the arrival of an interrupt.
These chain links are then recreated at some time in the future, with a
performance penalty.
My proposed solution is to skip unlinking TBs recursively and simply flag
that there is an interrupt request pending. Then we check interrupt flag in
goto_tb and skip jumping to the next TB. I think the code shows this change
quite well.
My experience is that this results in better overall performance. However, I
guess targets with very little interrupts will be somewhat slower.
Unfortunately, I have no structured measurements worth sending, so you will
have to do some tests on your own. If you find this patch not resulting in
improved overall performance, then please reply and explain why.
Regarding the code, I have done some small changes in all targets, but I
guess it's possible to isolate the change in tcg-op.h and exec. However, the
type name of the CPU state struct is not the same in all targets.
Signed-off-by: Torbjörn Anderson <tobbe.tt@home.se>
Index: target-arm/translate.c
===================================================================
--- target-arm/translate.c (revision 5661)
+++ target-arm/translate.c (working copy)
@@ -3376,7 +3376,14 @@
tb = s->tb;
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ uint32_t offset = offsetof(CPUARMState, interrupt_request);
+ TCGv tmp = new_tmp();
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ dead_tmp(tmp);
tcg_gen_goto_tb(n);
+ gen_set_label(label);
gen_set_pc_im(dest);
tcg_gen_exit_tb((long)tb + n);
} else {
Index: target-sh4/translate.c
===================================================================
--- target-sh4/translate.c (revision 5661)
+++ target-sh4/translate.c (working copy)
@@ -264,7 +264,14 @@
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
!ctx->singlestep_enabled) {
/* Use a direct jump if in same page and singlestep not enabled */
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
tcg_gen_goto_tb(n);
+ gen_set_label(label);
tcg_gen_movi_i32(cpu_pc, dest);
tcg_gen_exit_tb((long) tb + n);
} else {
Index: exec.c
===================================================================
--- exec.c (revision 5661)
+++ exec.c (working copy)
@@ -1495,15 +1495,6 @@
cpu_abort(env, "Raised interrupt while not in I/O function");
}
#endif
- } else {
- tb = env->current_tb;
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- if (tb && !testandset(&interrupt_lock)) {
- env->current_tb = NULL;
- tb_reset_jump_recursive(tb);
- resetlock(&interrupt_lock);
- }
}
#endif
}
Index: target-mips/translate.c
===================================================================
--- target-mips/translate.c (revision 5661)
+++ target-mips/translate.c (working copy)
@@ -2438,7 +2438,14 @@
TranslationBlock *tb;
tb = ctx->tb;
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
tcg_gen_goto_tb(n);
+ gen_set_label(label);
gen_save_pc(dest);
tcg_gen_exit_tb((long)tb + n);
} else {
Index: target-m68k/translate.c
===================================================================
--- target-m68k/translate.c (revision 5661)
+++ target-m68k/translate.c (working copy)
@@ -876,7 +876,14 @@
gen_exception(s, dest, EXCP_DEBUG);
} else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
(s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
tcg_gen_goto_tb(n);
+ gen_set_label(label);
tcg_gen_movi_i32(QREG_PC, dest);
tcg_gen_exit_tb((long)tb + n);
} else {
Index: target-i386/translate.c
===================================================================
--- target-i386/translate.c (revision 5661)
+++ target-i386/translate.c (working copy)
@@ -2212,8 +2212,15 @@
/* NOTE: we handle the case where the TB spans two pages here */
if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
(pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
+ uint32_t offset = offsetof(CPUX86State, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
+ gen_set_label(label);
gen_jmp_im(eip);
tcg_gen_exit_tb((long)tb + tb_num);
} else {
Index: target-cris/translate.c
===================================================================
--- target-cris/translate.c (revision 5663)
+++ target-cris/translate.c (working copy)
@@ -643,7 +643,14 @@
TranslationBlock *tb;
tb = dc->tb;
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
- tcg_gen_goto_tb(n);
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
+ tcg_gen_goto_tb(n);
+ gen_set_label(label);
tcg_gen_movi_tl(env_pc, dest);
tcg_gen_exit_tb((long)tb + n);
} else {
Index: target-sparc/translate.c
===================================================================
--- target-sparc/translate.c (revision 5661)
+++ target-sparc/translate.c (working copy)
@@ -226,7 +226,14 @@
if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
(npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
/* jump to same page: we can use a direct jump */
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
tcg_gen_goto_tb(tb_num);
+ gen_set_label(label);
tcg_gen_movi_tl(cpu_pc, pc);
tcg_gen_movi_tl(cpu_npc, npc);
tcg_gen_exit_tb((long)tb + tb_num);
Index: target-ppc/translate.c
===================================================================
--- target-ppc/translate.c (revision 5661)
+++ target-ppc/translate.c (working copy)
@@ -3463,7 +3463,14 @@
#endif
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
likely(!ctx->singlestep_enabled)) {
+ uint32_t offset = offsetof(CPUState, interrupt_request);
+ TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
+ int label = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, label);
+ tcg_temp_free(tmp);
tcg_gen_goto_tb(n);
+ gen_set_label(label);
tcg_gen_movi_tl(cpu_nip, dest & ~3);
tcg_gen_exit_tb((long)tb + n);
} else {
reply other threads:[~2008-11-09 22:08 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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='005301c942b1$27625490$7626fdb0$@tt@home.se' \
--to=tobbe.tt@home.se \
--cc=qemu-devel@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).