* [Qemu-devel] Weird behavior while using the instruction counter
@ 2008-07-24 10:42 Luis Pureza
2008-07-24 12:44 ` Paul Brook
0 siblings, 1 reply; 9+ messages in thread
From: Luis Pureza @ 2008-07-24 10:42 UTC (permalink / raw)
To: qemu-devel
Hi,
I'm using the instruction counter to execute N instructions at a time.
With very small values of N (say, N < 10), I observed the following
behavior:
1. A new TB is generated and execution starts there;
2. The instruction counter timer expires and cpu_exec_nocache() is called;
3. cpu_exec_nocache() generates a new TB for the same PC and starts to
execute it;
4. Some instruction inside the TB turns out to be an I/O instruction.
Thus, cpu_io_recompile() gets called
5; cpu_io_recompile() regenerates the TB and longjmps back to the
beginning of cpu_exec()
6. on cpu_exec(), tb_find_fast() returns the first TB, instead of the
one generated by cpu_io_recompile()
7. Endless loop!
Actually, for some reason beyond my comprehension, the loop is not
really infinite: after a few seconds it actually executes the block
and moves on. However, as you can imagine, this is too slow.
I think I fixed the problem by appending CF_LAST_IO to the cflags of
the TB generated by cpu_exec_nocache(). This way, cpu_io_recompile()
won't be called for this TB. Certainly not the best solution, though.
I was wondering if my thinking makes sense or am I just completely wrong :-)
Cheers,
Luis Pureza
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] Weird behavior while using the instruction counter
2008-07-24 10:42 [Qemu-devel] Weird behavior while using the instruction counter Luis Pureza
@ 2008-07-24 12:44 ` Paul Brook
2008-07-24 13:54 ` Luis Pureza
0 siblings, 1 reply; 9+ messages in thread
From: Paul Brook @ 2008-07-24 12:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Luis Pureza
On Thursday 24 July 2008, Luis Pureza wrote:
> Hi,
>
> I'm using the instruction counter to execute N instructions at a time.
> With very small values of N (say, N < 10), I observed the following
> behavior:
>
> 1. A new TB is generated and execution starts there;
> 2. The instruction counter timer expires and cpu_exec_nocache() is called;
> 3. cpu_exec_nocache() generates a new TB for the same PC and starts to
> execute it;
> 4. Some instruction inside the TB turns out to be an I/O instruction.
> Thus, cpu_io_recompile() gets called
> 5; cpu_io_recompile() regenerates the TB and longjmps back to the
> beginning of cpu_exec()
> 6. on cpu_exec(), tb_find_fast() returns the first TB, instead of the
> one generated by cpu_io_recompile()
> 7. Endless loop!
I think I can see how this could happen, but only when the IO instruction is
the first instruction in the block. For any other TB you probably get
run+fault first.
> Actually, for some reason beyond my comprehension, the loop is not
> really infinite: after a few seconds it actually executes the block
> and moves on. However, as you can imagine, this is too slow.
You need to figure out what's actually happening. Either it's an infinite loop
or it's not.
Instruction counter expiry and the first IO trap are both fairly expensive
operation. Having the counter expire every few instructionswill make qemu go
extremely slowly. Are you sure it's not just running very slowly?
> I think I fixed the problem by appending CF_LAST_IO to the cflags of
> the TB generated by cpu_exec_nocache(). This way, cpu_io_recompile()
> won't be called for this TB.
No. You're assuming the IO trap occurs on the last instruction, which not
true. The problem is that cpu_exec_nocache introduces a second TB with the
same lookup key(pc+flags). cpu_io_recompile (and possibly other places)
assume the currently executing TB is the only tb that matches. It needs to
invalidate the original TB (if it exists) as well as the uncached one.
A related issue is that we don't invalidate the cached TB if a fault occurs
while it is being executed.
Paul
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] Weird behavior while using the instruction counter
2008-07-24 12:44 ` Paul Brook
@ 2008-07-24 13:54 ` Luis Pureza
2008-07-24 14:02 ` Paul Brook
0 siblings, 1 reply; 9+ messages in thread
From: Luis Pureza @ 2008-07-24 13:54 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
On Thu, Jul 24, 2008 at 1:44 PM, Paul Brook <paul@codesourcery.com> wrote:
> On Thursday 24 July 2008, Luis Pureza wrote:
>> Hi,
>>
>> I'm using the instruction counter to execute N instructions at a time.
>> With very small values of N (say, N < 10), I observed the following
>> behavior:
>>
>> 1. A new TB is generated and execution starts there;
>> 2. The instruction counter timer expires and cpu_exec_nocache() is called;
>> 3. cpu_exec_nocache() generates a new TB for the same PC and starts to
>> execute it;
>> 4. Some instruction inside the TB turns out to be an I/O instruction.
>> Thus, cpu_io_recompile() gets called
>> 5; cpu_io_recompile() regenerates the TB and longjmps back to the
>> beginning of cpu_exec()
>> 6. on cpu_exec(), tb_find_fast() returns the first TB, instead of the
>> one generated by cpu_io_recompile()
>> 7. Endless loop!
>
> I think I can see how this could happen, but only when the IO instruction is
> the first instruction in the block. For any other TB you probably get
> run+fault first.
>
>> Actually, for some reason beyond my comprehension, the loop is not
>> really infinite: after a few seconds it actually executes the block
>> and moves on. However, as you can imagine, this is too slow.
>
> You need to figure out what's actually happening. Either it's an infinite loop
> or it's not.
I'm not sure of this, but I think I know what was happening. Since the
first TB was never cleared, the number of TBs would grow forever...
until it filled the code generation buffer. That's when tb_find_pc()
would actually find the correct TB instead of the old one and execute
it. And it started to move again.
> Instruction counter expiry and the first IO trap are both fairly expensive
> operation. Having the counter expire every few instructionswill make qemu go
> extremely slowly. Are you sure it's not just running very slowly?
>
>> I think I fixed the problem by appending CF_LAST_IO to the cflags of
>> the TB generated by cpu_exec_nocache(). This way, cpu_io_recompile()
>> won't be called for this TB.
>
> No. You're assuming the IO trap occurs on the last instruction, which not
> true. The problem is that cpu_exec_nocache introduces a second TB with the
> same lookup key(pc+flags). cpu_io_recompile (and possibly other places)
> assume the currently executing TB is the only tb that matches. It needs to
> invalidate the original TB (if it exists) as well as the uncached one.
Obviously, you're right. I was testing with blocks of a single
instruction. What do you think of this:
if (tb != &tbs[0] && (tb - 1)->pc == tb->pc) {
tb_phys_invalidate(tb - 1, -1);
}
added to cpu_io_recompile() just after the if (!tb) check?
Seems to do the trick for me...
Thanks,
Luis Pureza
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] Weird behavior while using the instruction counter
2008-07-24 13:54 ` Luis Pureza
@ 2008-07-24 14:02 ` Paul Brook
[not found] ` <3e1533500807240742u488272b7x12c4429cbfbb9297@mail.gmail.com>
0 siblings, 1 reply; 9+ messages in thread
From: Paul Brook @ 2008-07-24 14:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Luis Pureza
> > No. You're assuming the IO trap occurs on the last instruction, which not
> > true. The problem is that cpu_exec_nocache introduces a second TB with
> > the same lookup key(pc+flags). cpu_io_recompile (and possibly other
> > places) assume the currently executing TB is the only tb that matches. It
> > needs to invalidate the original TB (if it exists) as well as the
> > uncached one.
>
> Obviously, you're right. I was testing with blocks of a single
> instruction. What do you think of this:
>
> if (tb != &tbs[0] && (tb - 1)->pc == tb->pc) {
> tb_phys_invalidate(tb - 1, -1);
> }
No. There's no guarantee that the TBs are consecutive.
Paul
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-07-24 23:59 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-24 10:42 [Qemu-devel] Weird behavior while using the instruction counter Luis Pureza
2008-07-24 12:44 ` Paul Brook
2008-07-24 13:54 ` Luis Pureza
2008-07-24 14:02 ` Paul Brook
[not found] ` <3e1533500807240742u488272b7x12c4429cbfbb9297@mail.gmail.com>
2008-07-24 14:49 ` Fwd: " Luis Pureza
[not found] ` <200807241556.48810.paul@codesourcery.com>
2008-07-24 15:17 ` Luis Pureza
2008-07-24 16:02 ` Paul Brook
2008-07-24 17:58 ` Luis Pureza
2008-07-24 23:59 ` Paul Brook
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).