[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before c
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache |
Date: |
Tue, 14 Nov 2017 14:38:05 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 |
On 14/11/2017 09:18, Pavel Dovgalyuk wrote:
> This patch resets icount_decr.u32.high before calling cpu_exec_nocache
> when exception is pending. Exception is caused by the first instruction
> in the block and it cannot be executed without resetting the flag.
>
> This patch also moves this check to the beginning of cpu_handle_exception
> function to process pending exceptions in one function call.
>
> Signed-off-by: Maria Klimushenkova <address@hidden>
> Signed-off-by: Pavel Dovgalyuk <address@hidden>
>
> --
>
> v2: reorganized the exception processing code (as suggested by Paolo Bonzini)
>
> ---
> accel/tcg/cpu-exec.c | 95
> ++++++++++++++++++++++++++++----------------------
> 1 file changed, 54 insertions(+), 41 deletions(-)
>
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 0473055..f3de96f 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -470,48 +470,51 @@ static inline void cpu_handle_debug_exception(CPUState
> *cpu)
>
> static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
> {
> - if (cpu->exception_index >= 0) {
> - if (cpu->exception_index >= EXCP_INTERRUPT) {
> - /* exit request from the cpu execution loop */
> - *ret = cpu->exception_index;
> - if (*ret == EXCP_DEBUG) {
> - cpu_handle_debug_exception(cpu);
> - }
> - cpu->exception_index = -1;
> - return true;
> - } else {
> + if (cpu->exception_index < 0) {
> +#ifndef CONFIG_USER_ONLY
> + if (replay_has_exception()
> + && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
> + /* try to cause an exception pending in the log */
> + cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0, curr_cflags()),
> true);
> + }
> +#endif
> + if (cpu->exception_index < 0) {
> + return false;
> + }
> + }
> +
> + if (cpu->exception_index >= EXCP_INTERRUPT) {
> + /* exit request from the cpu execution loop */
> + *ret = cpu->exception_index;
> + if (*ret == EXCP_DEBUG) {
> + cpu_handle_debug_exception(cpu);
> + }
> + cpu->exception_index = -1;
> + return true;
> + } else {
> #if defined(CONFIG_USER_ONLY)
> - /* if user mode only, we simulate a fake exception
> - which will be handled outside the cpu execution
> - loop */
> + /* if user mode only, we simulate a fake exception
> + which will be handled outside the cpu execution
> + loop */
> #if defined(TARGET_I386)
> + CPUClass *cc = CPU_GET_CLASS(cpu);
> + cc->do_interrupt(cpu);
> +#endif
> + *ret = cpu->exception_index;
> + cpu->exception_index = -1;
> + return true;
> +#else
> + if (replay_exception()) {
> CPUClass *cc = CPU_GET_CLASS(cpu);
> + qemu_mutex_lock_iothread();
> cc->do_interrupt(cpu);
> -#endif
> - *ret = cpu->exception_index;
> + qemu_mutex_unlock_iothread();
> cpu->exception_index = -1;
> + } else if (!replay_has_interrupt()) {
> + /* give a chance to iothread in replay mode */
> + *ret = EXCP_INTERRUPT;
> return true;
> -#else
> - if (replay_exception()) {
> - CPUClass *cc = CPU_GET_CLASS(cpu);
> - qemu_mutex_lock_iothread();
> - cc->do_interrupt(cpu);
> - qemu_mutex_unlock_iothread();
> - cpu->exception_index = -1;
> - } else if (!replay_has_interrupt()) {
> - /* give a chance to iothread in replay mode */
> - *ret = EXCP_INTERRUPT;
> - return true;
> - }
> -#endif
> }
> -#ifndef CONFIG_USER_ONLY
> - } else if (replay_has_exception()
> - && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
> - /* try to cause an exception pending in the log */
> - cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0, curr_cflags()), true);
> - *ret = -1;
> - return true;
> #endif
> }
>
> @@ -522,6 +525,19 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
> TranslationBlock **last_tb)
> {
> CPUClass *cc = CPU_GET_CLASS(cpu);
> + int32_t insns_left;
> +
> + /* Clear the interrupt flag now since we're processing
> + * cpu->interrupt_request and cpu->exit_request.
> + */
> + insns_left = atomic_read(&cpu->icount_decr.u32);
> + atomic_set(&cpu->icount_decr.u16.high, 0);
> + if (unlikely(insns_left < 0)) {
> + /* Ensure the zeroing of icount_decr comes before the next read
> + * of cpu->exit_request or cpu->interrupt_request.
> + */
> + smp_mb();
> + }
>
> if (unlikely(atomic_read(&cpu->interrupt_request))) {
> int interrupt_request;
> @@ -620,17 +636,14 @@ static inline void cpu_loop_exec_tb(CPUState *cpu,
> TranslationBlock *tb,
>
> *last_tb = NULL;
> insns_left = atomic_read(&cpu->icount_decr.u32);
> - atomic_set(&cpu->icount_decr.u16.high, 0);
> if (insns_left < 0) {
> /* Something asked us to stop executing chained TBs; just
> * continue round the main loop. Whatever requested the exit
> * will also have set something else (eg exit_request or
> - * interrupt_request) which we will handle next time around
> - * the loop. But we need to ensure the zeroing of icount_decr
> - * comes before the next read of cpu->exit_request
> - * or cpu->interrupt_request.
> + * interrupt_request) which will be handled by
> + * cpu_handle_interrupt. cpu_handle_interrupt will also
> + * clear cpu->icount_decr.u16.high.
> */
> - smp_mb();
> return;
> }
>
>
Thanks, queued for 2.11.
Paolo
- [Qemu-devel] [RFC PATCH v2 12/26] cpus: push BQL lock to qemu_*_wait_io_event, (continued)
- [Qemu-devel] [RFC PATCH v2 12/26] cpus: push BQL lock to qemu_*_wait_io_event, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 13/26] cpus: only take BQL for sleeping threads, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 14/26] replay/replay.c: bump REPLAY_VERSION again, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 15/26] replay/replay-internal.c: track holding of replay_lock, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 16/26] replay: make locking visible outside replay code, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 17/26] replay: push replay_mutex_lock up the call tree, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 18/26] cpu-exec: don't overwrite exception_index, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache, Pavel Dovgalyuk, 2017/11/14
- Re: [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache,
Paolo Bonzini <=
- [Qemu-devel] [RFC PATCH v2 20/26] replay: don't destroy mutex at exit, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 21/26] replay: check return values of fwrite, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 22/26] scripts/qemu-gdb: add simple tcg lock status helper, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 23/26] util/qemu-thread-*: add qemu_lock, locked and unlock trace events, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 24/26] scripts/analyse-locks-simpletrace.py: script to analyse lock times, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 25/26] scripts/replay-dump.py: replay log dumper, Pavel Dovgalyuk, 2017/11/14
- [Qemu-devel] [RFC PATCH v2 26/26] scripts/qemu-gdb/timers.py: new helper to dump timer state, Pavel Dovgalyuk, 2017/11/14
- Re: [Qemu-devel] [RFC PATCH v2 00/26] replay additions, no-reply, 2017/11/14