diff mbox

Periodic timer for VIRTUAL_CLOCK causes deadlock in icount mode

Message ID CANVkX9GbuzHzT_0gQO0Yvnt1-o0WThuBHoojBsqEVmnvU45K5g@mail.gmail.com
State New
Headers show

Commit Message

James Nutaro Nov. 1, 2015, 2:09 p.m. UTC
I have encountered the following unexpected behavior while trying to
synchronize the virtual clock in qemu to a simulation clock in another
software package. Is this something to be expected, or a bug that can
be fixed?

The issue can be reliably reproduced by making the following changes
to qemu. In the file vl.c, add two lines to introduce the function
qqq_setup. The diff against the main trunk is below.

     int i;
@@ -4641,6 +4643,7 @@ int main(int argc, char **argv, char **envp)
         }
     }

+       qqq_setup();
     main_loop();
     bdrv_close_all();
     pause_all_vcpus();


The function qqq_setup starts a periodic timer as shown below.

#include "qemu/timer.h"
#include <stdio.h>

static QEMUTimer* timer = NULL;

static void timer_callback(void* data)
{
    timer_mod(timer,qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)+100);
}

void qqq_setup(void);

void qqq_setup(void)
{
    timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,timer_callback,NULL);
    timer_mod(timer,qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)+100);
}

I recompile qemu with these additions and boot a test image as follows

qemu-system-i386 -sdl -icount 1,sleep=no linux-0.2.img

The emulator stops after triggering the timer 23  times. After that,
the emulation no longer progresses and the timer is not triggered.
When I load this into gdb, what appears to be going on is that the
emulator stops when all of the virtual cpu's become idle, at which
time it hangs on the halt_cond conditional, which is never signaled.
If I run without icount then everything works as expected.

Any ideas?

Comments

James Nutaro Nov. 1, 2015, 2:18 p.m. UTC | #1
A follow up to my previous email. I see the same behavior with the command

qemu-system-i386 -sdl -icount 1 linux-0.2.img

On Sun, Nov 1, 2015 at 9:09 AM, James Nutaro <nutaro@gmail.com> wrote:
> I have encountered the following unexpected behavior while trying to
> synchronize the virtual clock in qemu to a simulation clock in another
> software package. Is this something to be expected, or a bug that can
> be fixed?
>
> The issue can be reliably reproduced by making the following changes
> to qemu. In the file vl.c, add two lines to introduce the function
> qqq_setup. The diff against the main trunk is below.
>
> diff --git a/vl.c b/vl.c
> index f5f7c3f..0921969 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2932,6 +2932,8 @@ static void set_memory_options(uint64_t
> *ram_slots, ram_addr_t *
>      }
>  }
>
> +extern void qqq_setup(void);
> +
>  int main(int argc, char **argv, char **envp)
>  {
>      int i;
> @@ -4641,6 +4643,7 @@ int main(int argc, char **argv, char **envp)
>          }
>      }
>
> +       qqq_setup();
>      main_loop();
>      bdrv_close_all();
>      pause_all_vcpus();
>
>
> The function qqq_setup starts a periodic timer as shown below.
>
> #include "qemu/timer.h"
> #include <stdio.h>
>
> static QEMUTimer* timer = NULL;
>
> static void timer_callback(void* data)
> {
>     timer_mod(timer,qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)+100);
> }
>
> void qqq_setup(void);
>
> void qqq_setup(void)
> {
>     timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,timer_callback,NULL);
>     timer_mod(timer,qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)+100);
> }
>
> I recompile qemu with these additions and boot a test image as follows
>
> qemu-system-i386 -sdl -icount 1,sleep=no linux-0.2.img
>
> The emulator stops after triggering the timer 23  times. After that,
> the emulation no longer progresses and the timer is not triggered.
> When I load this into gdb, what appears to be going on is that the
> emulator stops when all of the virtual cpu's become idle, at which
> time it hangs on the halt_cond conditional, which is never signaled.
> If I run without icount then everything works as expected.
>
> Any ideas?
diff mbox

Patch

diff --git a/vl.c b/vl.c
index f5f7c3f..0921969 100644
--- a/vl.c
+++ b/vl.c
@@ -2932,6 +2932,8 @@  static void set_memory_options(uint64_t
*ram_slots, ram_addr_t *
     }
 }

+extern void qqq_setup(void);
+
 int main(int argc, char **argv, char **envp)
 {