qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, peter.maydell@linaro.org,
	boost.lists@gmail.com, quintela@redhat.com, jasowang@redhat.com,
	mst@redhat.com, zuban32s@gmail.com,
	maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru,
	kraxel@redhat.com, pavel.dovgaluk@ispras.ru, pbonzini@redhat.com,
	alex.bennee@linaro.org
Subject: [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache
Date: Tue, 14 Nov 2017 11:18:18 +0300	[thread overview]
Message-ID: <20171114081818.27640.33165.stgit@pasha-VirtualBox> (raw)
In-Reply-To: <20171114081630.27640.53933.stgit@pasha-VirtualBox>

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 <maria.klimushenkova@ispras.ru>
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>

--

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;
     }
 

  parent reply	other threads:[~2017-11-14  8:18 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-14  8:16 [Qemu-devel] [RFC PATCH v2 00/26] replay additions Pavel Dovgalyuk
2017-11-14  8:16 ` [Qemu-devel] [RFC PATCH v2 01/26] block: implement bdrv_snapshot_goto for blkreplay Pavel Dovgalyuk
2017-11-14  8:16 ` [Qemu-devel] [RFC PATCH v2 02/26] blkreplay: create temporary overlay for underlaying devices Pavel Dovgalyuk
2017-11-14  8:16 ` [Qemu-devel] [RFC PATCH v2 03/26] replay: disable default snapshot for record/replay Pavel Dovgalyuk
2017-11-14  8:16 ` [Qemu-devel] [RFC PATCH v2 04/26] replay: fix processing async events Pavel Dovgalyuk
2017-11-14 13:34   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 05/26] replay: fixed replay_enable_events Pavel Dovgalyuk
2017-11-14 13:34   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 06/26] replay: fix save/load vm for non-empty queue Pavel Dovgalyuk
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 07/26] replay: added replay log format description Pavel Dovgalyuk
2017-11-14 13:34   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 08/26] replay: make safe vmstop at record/replay Pavel Dovgalyuk
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 09/26] replay: save prior value of the host clock Pavel Dovgalyuk
2017-11-14 13:35   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 10/26] icount: fixed saving/restoring of icount warp timers Pavel Dovgalyuk
2017-11-14 13:35   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 11/26] target/arm/arm-powertctl: drop BQL assertions Pavel Dovgalyuk
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 12/26] cpus: push BQL lock to qemu_*_wait_io_event Pavel Dovgalyuk
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 13/26] cpus: only take BQL for sleeping threads Pavel Dovgalyuk
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 14/26] replay/replay.c: bump REPLAY_VERSION again Pavel Dovgalyuk
2017-11-14 13:35   ` Paolo Bonzini
2017-11-14  8:17 ` [Qemu-devel] [RFC PATCH v2 15/26] replay/replay-internal.c: track holding of replay_lock Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 16/26] replay: make locking visible outside replay code Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 17/26] replay: push replay_mutex_lock up the call tree Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 18/26] cpu-exec: don't overwrite exception_index Pavel Dovgalyuk
2017-11-14 13:37   ` Paolo Bonzini
2017-11-14  8:18 ` Pavel Dovgalyuk [this message]
2017-11-14 13:38   ` [Qemu-devel] [RFC PATCH v2 19/26] cpu-exec: reset exit flag before calling cpu_exec_nocache Paolo Bonzini
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 20/26] replay: don't destroy mutex at exit Pavel Dovgalyuk
2017-11-14 13:36   ` Paolo Bonzini
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 21/26] replay: check return values of fwrite Pavel Dovgalyuk
2017-11-14 13:37   ` Paolo Bonzini
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 22/26] scripts/qemu-gdb: add simple tcg lock status helper Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 23/26] util/qemu-thread-*: add qemu_lock, locked and unlock trace events Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 24/26] scripts/analyse-locks-simpletrace.py: script to analyse lock times Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 25/26] scripts/replay-dump.py: replay log dumper Pavel Dovgalyuk
2017-11-14  8:18 ` [Qemu-devel] [RFC PATCH v2 26/26] scripts/qemu-gdb/timers.py: new helper to dump timer state Pavel Dovgalyuk
2017-11-14  8:58 ` [Qemu-devel] [RFC PATCH v2 00/26] replay additions no-reply
2017-11-14  9:03 ` no-reply

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=20171114081818.27640.33165.stgit@pasha-VirtualBox \
    --to=pavel.dovgaluk@ispras.ru \
    --cc=alex.bennee@linaro.org \
    --cc=boost.lists@gmail.com \
    --cc=dovgaluk@ispras.ru \
    --cc=jasowang@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=maria.klimushenkova@ispras.ru \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=zuban32s@gmail.com \
    /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).