From patchwork Thu Jan 11 08:26:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124155 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp369183qgn; Thu, 11 Jan 2018 00:34:51 -0800 (PST) X-Google-Smtp-Source: ACJfBotXoV5sNjZNH98DyKVMBbXO+gsnhuvBUbFSndvWnVcNjIoWWVlVF5r3tvAYZcOeN2QoHeZn X-Received: by 10.37.69.69 with SMTP id s66mr18855894yba.116.1515659691919; Thu, 11 Jan 2018 00:34:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515659691; cv=none; d=google.com; s=arc-20160816; b=DrUNuymt2VK2Zpa8wDWa+gxeCvdnl5fouubLKmpRO76kuiQXbr2yY7dAy1xj41djkE UfER6I1sykyFOuYNEOaQbVWzXOvfVQtEAScHdOJQ6hTUx7Cs74Zh7RZNc887NfFVMJ1G gLikK30XYjjMmS+xtA8iJltYM+VO9rql5/CfcWVOLehq3Qa3l5f6yW6w9oLQIdqdoSe2 3C8w0UUkFA9NstoJnOJ0V+RetEz9W5CZfZrREIaba1UV3rYrSGcYqWFk+blvRXDEu0wJ EFKTR60obD+8NMvpIeXh9P4DlwLdqh155PYo84hx7JL7HqfJcewrarEpa46fXnuRExu4 wQDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=wTFEK1rP/PsAYVE6lDn8t3/G3KRjFANptpcyQJugdR4=; b=sBOqIjEZG6gzsd+FWe1YGgx3RUS0wnerptPiX36uBh0N6ODDWWZk80BhJlvF4xAofL 9HgZIQ+7e8t9RE+KMJep2Bnsxg7qXYFn3xxzYtSL4DNoCyrAOPYFz2+16XkPW3hw0SF2 k2GLROz2sMRd7f0ViYGzD1hpp8ZyfkCTfIx++oxyQNhAff5pOCrPdN2w4PWFx+K+Hn+7 XHECrD0T6zJWtvfdJSk7Y5mNiP4H5ZlXbl3JvDH/PYAZpl+ckN8NBfmdGrgvQeGk0grX FNQbBIzWBxOG3yct/nJS7DWOFhmZwFDHiGJRgfrNLR1CazJDxT1HGTMsn2qqrqbnUDMg i8qA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id g3si4047608ywl.95.2018.01.11.00.34.51 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:34:51 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYK3-0007fM-FF for patch@linaro.org; Thu, 11 Jan 2018 03:34:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46516) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBj-0000Ti-Oi for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYBi-0001Fj-Sx for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:15 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41748) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBi-0001Ey-L5 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:14 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C558E54006A; Thu, 11 Jan 2018 11:26:13 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:15 +0300 Message-ID: <20180111082615.27295.49886.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 14/30] target/arm/arm-powertctl: drop BQL assertions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The powerctl code is run in the context of the vCPU changing power state. It does not need the BQL to protect its changes. Signed-off-by: Alex Bennée --- target/arm/arm-powerctl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c index 25207cb..9661a59 100644 --- a/target/arm/arm-powerctl.c +++ b/target/arm/arm-powerctl.c @@ -124,7 +124,6 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state, g_free(info); /* Finally set the power status */ - assert(qemu_mutex_iothread_locked()); target_cpu->power_state = PSCI_ON; } @@ -135,8 +134,6 @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id, ARMCPU *target_cpu; struct CpuOnInfo *info; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 " (EL %d, %s) @ 0x%" PRIx64 " with R0 = 0x%" PRIx64 "\n", cpuid, target_el, target_aa64 ? "aarch64" : "aarch32", entry, context_id); @@ -227,7 +224,6 @@ static void arm_set_cpu_off_async_work(CPUState *target_cpu_state, { ARMCPU *target_cpu = ARM_CPU(target_cpu_state); - assert(qemu_mutex_iothread_locked()); target_cpu->power_state = PSCI_OFF; target_cpu_state->halted = 1; target_cpu_state->exception_index = EXCP_HLT; @@ -238,8 +234,6 @@ int arm_set_cpu_off(uint64_t cpuid) CPUState *target_cpu_state; ARMCPU *target_cpu; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 "\n", cpuid); /* change to the cpu we are powering up */ @@ -274,8 +268,6 @@ int arm_reset_cpu(uint64_t cpuid) CPUState *target_cpu_state; ARMCPU *target_cpu; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 "\n", cpuid); /* change to the cpu we are resetting */ From patchwork Thu Jan 11 08:26:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124159 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp374174qgn; Thu, 11 Jan 2018 00:40:06 -0800 (PST) X-Google-Smtp-Source: ACJfBotPtpkFtH42pd6EkhaL0I+KtwINVNeOmB9DdghnNCjXaSr1e2fa00+8Ih3ag6RORc0uie7y X-Received: by 10.37.123.133 with SMTP id w127mr19414848ybc.69.1515660006036; Thu, 11 Jan 2018 00:40:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660006; cv=none; d=google.com; s=arc-20160816; b=nApiVNksN2oBL3TGkDgr5aYRhOGO0C5Xc5llUrizEyI1e3yd0+tTKT+c4ugpgX8LXG RBgRli/P898DFCJCunzZBZ4Iqbd1b/vty6LNM3O6PlwK9+Fd6VNBiOJivXNPUPjn50mE tyN4j7Gm1WZ3+m4Mq31B7JlC93Ohd+VcDmPJiuSYjQB4uC5VdRAUkthEeRoo/6xlArpa +B8SYQ8l9m+e6NFjeXtRFqFJtFTPFgo7rGVvwQZA27qodKR0rAh0/JxZSSgE0TCXyklD MIb0oeyYlDBmB4rDNCfi61N3Z+p5CLRUSObpMEF7go7TNU9riV/uQ0CIhudpFLcRi47Z +XPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=Tqjf52OC9FSA9jwTviqdoEm46WowEekT83MjICedetk=; b=OUZ0t+Ss1n5hfOXvz8qJTknq2sHDAQBYxMcqMxAKwarmGAbRFxT84MK6vHI3nZNb72 PrDDrJ2n/4ipKpvbvUgYezlitp9noys5kk8zceRhQYTzIZtzMCIJWjuWFQx6gWUJ++QS Cjx7/4w9fCVLesiaHTPfhsqbikjSdm/Oyb8AzZAaKjRXbUXWRl/jYQ/vaoeRk2f4XEN6 E09TIldGJ/3eAGV1+VL4RXVDgp+8lmO0N3fjlMOjE0EhVkZ/suJLaVuziNaX7pkUc7Lc rzus3RIHQiMFl4qm1vyUlJ96wtDkidTjBeldzLSpWb95ciylKXp6JYy+cBbDFK0Z+nVD 2ESg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id b69si1418833ywe.676.2018.01.11.00.40.05 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:40:06 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53098 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYP7-0003fA-H4 for patch@linaro.org; Thu, 11 Jan 2018 03:40:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46646) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBs-0000aW-KU for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYBo-0001K4-JF for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:24 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41772) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBo-0001JW-72 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:20 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 58BB954006A; Thu, 11 Jan 2018 11:26:19 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:21 +0300 Message-ID: <20180111082621.27295.81834.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 15/30] cpus: push BQL lock to qemu_*_wait_io_event X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée We only really need to grab the lock for initial setup (so we don't race with the thread-spawning thread). After that we can drop the lock for the whole main loop and only grab it for waiting for IO events. There is a slight wrinkle for the round-robin TCG thread as we also expire timers which needs to be done under BQL as they are in the main-loop. This is stage one of reducing the lock impact as we can drop the requirement of implicit BQL for async work and only grab the lock when we need to sleep on the cpu->halt_cond. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- accel/kvm/kvm-all.c | 4 ---- cpus.c | 27 ++++++++++++++++++++------- target/i386/hax-all.c | 2 -- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index f290f48..8d1d2c4 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1857,9 +1857,7 @@ int kvm_cpu_exec(CPUState *cpu) return EXCP_HLT; } - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); - do { MemTxAttrs attrs; @@ -1989,8 +1987,6 @@ int kvm_cpu_exec(CPUState *cpu) } while (ret == 0); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); - if (ret < 0) { cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE); vm_stop(RUN_STATE_INTERNAL_ERROR); diff --git a/cpus.c b/cpus.c index b4146a8..82dcbf8 100644 --- a/cpus.c +++ b/cpus.c @@ -1149,6 +1149,8 @@ static bool qemu_tcg_should_sleep(CPUState *cpu) static void qemu_tcg_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); + while (qemu_tcg_should_sleep(cpu)) { stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); @@ -1157,15 +1159,21 @@ static void qemu_tcg_wait_io_event(CPUState *cpu) start_tcg_kick_timer(); qemu_wait_io_event_common(cpu); + + qemu_mutex_unlock_iothread(); } static void qemu_kvm_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); + while (cpu_thread_is_idle(cpu)) { qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } qemu_wait_io_event_common(cpu); + + qemu_mutex_unlock_iothread(); } static void qemu_hvf_wait_io_event(CPUState *cpu) @@ -1199,6 +1207,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) /* signal CPU creation */ cpu->created = true; + qemu_mutex_unlock_iothread(); + qemu_cond_signal(&qemu_cpu_cond); do { @@ -1241,10 +1251,10 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) /* signal CPU creation */ cpu->created = true; + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); while (1) { - qemu_mutex_unlock_iothread(); do { int sig; r = sigwait(&waitset, &sig); @@ -1255,6 +1265,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) } qemu_mutex_lock_iothread(); qemu_wait_io_event_common(cpu); + qemu_mutex_unlock_iothread(); } return NULL; @@ -1343,11 +1354,9 @@ static int tcg_cpu_exec(CPUState *cpu) #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); ret = cpu_exec(cpu); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); #ifdef CONFIG_PROFILER tcg_time += profile_getclock() - ti; #endif @@ -1407,6 +1416,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_wait_io_event_common(cpu); } } + qemu_mutex_unlock_iothread(); start_tcg_kick_timer(); @@ -1416,6 +1426,9 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu->exit_request = 1; while (1) { + + qemu_mutex_lock_iothread(); + /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ qemu_account_warp_timer(); @@ -1424,6 +1437,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + qemu_mutex_unlock_iothread(); + if (!cpu) { cpu = first_cpu; } @@ -1449,9 +1464,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu_handle_guest_debug(cpu); break; } else if (r == EXCP_ATOMIC) { - qemu_mutex_unlock_iothread(); cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); break; } } else if (cpu->stop) { @@ -1492,6 +1505,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg) current_cpu = cpu; hax_init_vcpu(cpu); + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); while (1) { @@ -1584,6 +1598,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) cpu->created = true; cpu->can_do_io = 1; current_cpu = cpu; + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); /* process any pending work */ @@ -1608,9 +1623,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) g_assert(cpu->halted); break; case EXCP_ATOMIC: - qemu_mutex_unlock_iothread(); cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); default: /* Ignore everything else? */ break; diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index 3ce6950..9fd60d9 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -513,11 +513,9 @@ static int hax_vcpu_hax_exec(CPUArchState *env) hax_vcpu_interrupt(env); - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); hax_ret = hax_vcpu_run(vcpu); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); /* Simply continue the vcpu_run if system call interrupted */ if (hax_ret == -EINTR || hax_ret == -EAGAIN) { From patchwork Thu Jan 11 08:26:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124162 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp375738qgn; Thu, 11 Jan 2018 00:41:27 -0800 (PST) X-Google-Smtp-Source: ACJfBouOMRf9j6jS5rQ+0uvGY3FmtjzBpjmHo3prCCfljIIUviThdR+pn84OhKxDdDo/zFBUhiEV X-Received: by 10.37.76.131 with SMTP id z125mr19651526yba.298.1515660087746; Thu, 11 Jan 2018 00:41:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660087; cv=none; d=google.com; s=arc-20160816; b=f3dk/Bwq6z8qB9qUFP7Ok8eSIOC2GfKQtMZ4XI0IXTQypDlVFPf0WnfyGgSsqCYlFE cVYodVvWd/YLQXWnLvVIFHjZKI7rTuV7doZ+If/NKjpPXb2VrAAsrM7Cu6086xul0E7m rVbhJy592aJ+bvDVUKoy55gI5QJ+t+au6laJ4fCcOEOt/7LvxqwJONx/uO53WgxV6Cua eenqLWnKI9eodRKgN5sXSLsWGZSxPzO9xR/OlPr+BZmwkik3awV3diXyIg6vn6vlJ8RR nS+vVn0yMPFcNxHEDgqJ81xi1KFmLnWn1dsKNi7wQkGVFzKhe3sadbZZondQSO4cSQnh maRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=p8PbdddRaStnDU5J19juloMNJJWAiKmFUj76hk+vNXo=; b=UAMblHeevDGQKI8Cgvhbv17aEXj/Y8v7tH+MEblqkcurGEX3oNplBMn0tbe/GdpP9Y UQc3l5r77esoSolHBMBG2jssR6U03Nebust6VbRbRnzpBnHM2+c2TtBYP1/9dyJg7ET5 biDSffMaErFK2BTaFLEwgq/s/OOw/A5L+ccSE9dUFS0hRj2KIqEUtJXtgPe112tM+3nE IZ9WhVz+Ow/OqgwcH6Ump0h5vvDuZ9J+CPSTNp7rs3jdWBHF5evmdSeuCYdRSM6OuYK3 fHpRa8rzmCG0zFJRmvrZR5QGRdH/mxhEVthPylZ+mgMbnDTL2CRjqLh2w6whlEb+803U JUrg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id z5si1162218ywd.330.2018.01.11.00.41.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:41:27 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53101 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYQR-0003yq-6h for patch@linaro.org; Thu, 11 Jan 2018 03:41:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46684) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBv-0000ck-5s for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYBu-0001Po-4G for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:27 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41792) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBt-0001Ow-Nf for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:26 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E2CE454006B; Thu, 11 Jan 2018 11:26:24 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:26 +0300 Message-ID: <20180111082626.27295.52919.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 16/30] cpus: only take BQL for sleeping threads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Now the only real need to hold the BQL is for when we sleep on the cpu->halt conditional. The lock is actually dropped while the thread sleeps so the actual window for contention is pretty small. This also means we can remove the special case hack for exclusive work and simply declare that work no longer has an implicit BQL held. This isn't a major problem async work is generally only changing things in the context of its own vCPU. If it needs to work across vCPUs it should be using the exclusive mechanism or possibly taking the lock itself. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- cpus-common.c | 13 +++++-------- cpus.c | 10 ++++------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/cpus-common.c b/cpus-common.c index 59f751e..64661c3 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -310,6 +310,11 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, queue_work_on_cpu(cpu, wi); } +/* Work items run outside of the BQL. This is essential for avoiding a + * deadlock for exclusive work but also applies to non-exclusive work. + * If the work requires cross-vCPU changes then it should use the + * exclusive mechanism. + */ void process_queued_cpu_work(CPUState *cpu) { struct qemu_work_item *wi; @@ -327,17 +332,9 @@ void process_queued_cpu_work(CPUState *cpu) } qemu_mutex_unlock(&cpu->work_mutex); if (wi->exclusive) { - /* Running work items outside the BQL avoids the following deadlock: - * 1) start_exclusive() is called with the BQL taken while another - * CPU is running; 2) cpu_exec in the other CPU tries to takes the - * BQL, so it goes to sleep; start_exclusive() is sleeping too, so - * neither CPU can proceed. - */ - qemu_mutex_unlock_iothread(); start_exclusive(); wi->func(cpu, wi->data); end_exclusive(); - qemu_mutex_lock_iothread(); } else { wi->func(cpu, wi->data); } diff --git a/cpus.c b/cpus.c index 82dcbf8..79dda49 100644 --- a/cpus.c +++ b/cpus.c @@ -1149,31 +1149,29 @@ static bool qemu_tcg_should_sleep(CPUState *cpu) static void qemu_tcg_wait_io_event(CPUState *cpu) { - qemu_mutex_lock_iothread(); while (qemu_tcg_should_sleep(cpu)) { + qemu_mutex_lock_iothread(); stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); + qemu_mutex_unlock_iothread(); } start_tcg_kick_timer(); qemu_wait_io_event_common(cpu); - - qemu_mutex_unlock_iothread(); } static void qemu_kvm_wait_io_event(CPUState *cpu) { - qemu_mutex_lock_iothread(); while (cpu_thread_is_idle(cpu)) { + qemu_mutex_lock_iothread(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); + qemu_mutex_unlock_iothread(); } qemu_wait_io_event_common(cpu); - - qemu_mutex_unlock_iothread(); } static void qemu_hvf_wait_io_event(CPUState *cpu) From patchwork Thu Jan 11 08:26:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124157 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp371697qgn; Thu, 11 Jan 2018 00:37:29 -0800 (PST) X-Google-Smtp-Source: ACJfBotP/ctbkSWPKx4n1ylFBlXNUznwNUnZavAb+NJk7bf+F9gLUEBVHAUOj9n3xEXaBQkxkswu X-Received: by 10.37.110.212 with SMTP id j203mr19322378ybc.476.1515659849247; Thu, 11 Jan 2018 00:37:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515659849; cv=none; d=google.com; s=arc-20160816; b=x3Lb46XQ2wWeBCDdcbzIu0Ll+aVMOcG9NMnHYYvC7xW+k0hObbHB7nT/BXmjz6snhj yZefABMjwmfv32t+tTK/G3ZEC7AU/UsrCWPZ4nSDAtdgyQqE451oeTzXMIBp0PCf9u+/ g/PQCQEeNSjL6TSVHbGJUDZBA7gaQt6gjYeyl/IBJg3WQleKb9KqHS3PqsboaSn73y5M hE1PYanczxd1wpuwMCKLtNHE/7YEfD3dcae2wMGqPBYQKpLQTfOPLYnhIeRB/YNiplV/ h1ke+shrtdHCaRB2wwnyUsWjuSn7nAqyuIvjNPiJgTB7zDjrmH2lVD3FOoRDvM5fRsbu r03w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=6kS1RHPs34/96la2ZIym1jAXpkol9kfn4sBc0vgnhnY=; b=By80CHcxoEYRena6Lql/APwp+KXh2bDbRzHRPjHTc5f8tf4K7DS9gIZkkIFwvgR+DM pNR1XR44vHSPFru8wNIyIn7bIR65n4vz78AR9m9b9+AQfSKfdsx0iCKawAzsYoap8w8t w+Cr35J5iLU+jvGP0EkQ+fHUWWNPShfnSile/7PONrj1gAsZJBn1zfYlgTPyuaAlAxbf 8LDlYEcNgzcBxEnGju7no/MuvoTIzRHDNBkaN8xd4TDJ54NeyN1g3cSSdbDlCE9Khi+m 3P/7l0LxYvkmfcd0lBwGzcexRnnCwLOkQhCgimQv7YQXt5sJxaagX3IrvHfRFTxbOSD0 9woQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u190si2147903ybf.20.2018.01.11.00.37.29 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:37:29 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53075 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYMa-0001Uj-Kp for patch@linaro.org; Thu, 11 Jan 2018 03:37:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46816) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYC3-0000kK-JP for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYBz-0001VG-IR for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:35 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41810) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBz-0001Ub-9u for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:31 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 68E4154006B; Thu, 11 Jan 2018 11:26:30 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:32 +0300 Message-ID: <20180111082632.27295.18985.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 17/30] replay/replay.c: bump REPLAY_VERSION again X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This time commit 802f045a5f61b781df55e4492d896b4d20503ba7 broke the replay file format. Also add a comment about this to replay-internal.h. Signed-off-by: Alex Bennée Reviewed-off-by: Pavel Dovgalyuk Acked-by: Paolo Bonzini --- replay/replay-internal.h | 2 +- replay/replay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/replay/replay-internal.h b/replay/replay-internal.h index be96d7e..8e4c701 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -12,7 +12,7 @@ * */ - +/* Any changes to order/number of events will need to bump REPLAY_VERSION */ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, diff --git a/replay/replay.c b/replay/replay.c index ff58a5a..4f24498 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02006 +#define REPLAY_VERSION 0xe02007 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) From patchwork Thu Jan 11 08:26:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124154 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp366251qgn; Thu, 11 Jan 2018 00:32:13 -0800 (PST) X-Google-Smtp-Source: ACJfBosTDQaTv2KcF8aHgVc5z5E3PbSLgUWlyQJleJXiOiOCKSHd35HQhOsCUl9izWf3icMadlvv X-Received: by 10.129.108.216 with SMTP id h207mr9406919ywc.163.1515659533942; Thu, 11 Jan 2018 00:32:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515659533; cv=none; d=google.com; s=arc-20160816; b=0PC7PNv8DJd1DRuhbGoEQJaZ9pR+YD6l4kYTtNJbfIyBApRFWRnpIp3QmBc6UXgsqW EOgR3CMmBnPVJ5LSC+OQNnYvDzB12w0L6IaQSOmmDDS3EvYCE9lDgL3XYpa/obAR0kgL wLXNbeNuD+pXmpQvJKxZDG4aqdWMwhrRa8O3VMGCQAgGfgWph1ewAVM9pjFllxaS96LM T0EtoSZwtKK4MPP8IuDeNbulBA+qmJ5f6/o8KthJZqhmZFVKC06ElN/XG9HXmZN7xlT1 Hx2Mt9CL+I8Oncps7XxMmNI0GaRcZ9HSHbl4yiOzquDNtlrPLchUbs5NDcfV1cGlXIzf 7agQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=ojZ3xwW7SZ3qXlFlE9UIGPYeYK0OwSzlNRlNQlIVsDw=; b=rN8Aroa+6YbkCTzAOPk81AReJSPW+j/3jDOGxZO2wS/taXLDy4ZRph77aJkKIlJFrq ZdvABc9XkE120UpEn/khQIKxXuzQgxSTXsqdKh7yLVIZwmmtCAgsY1z4CEm+F3Bo+p/p zPUkc4aFuM4SfAJb1yiOTWAfdrxy/KYt6jPMO7Tn5r0sad9NpmSF5KztXZ5DAqPmcd0z jk89L3ig5daaU3/px4ZyOCLCx2foVPX7JUC6C+uy9+fn/5aanNJJd2CXW7pNJz2oh/78 g2WnijITaiwfYqomF0QUSeP+196anClU2JK73TX8dQR7CvS3LBTySYN03X+TPSaQlBiA Y5uA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id f4si3838252ybn.386.2018.01.11.00.32.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:32:13 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53018 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYHV-0005Hf-Ck for patch@linaro.org; Thu, 11 Jan 2018 03:32:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46858) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYC5-0000mI-SY for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYC5-0001ZW-2Z for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:37 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41836) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYC4-0001ZB-RM for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:37 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id EEF8054006A; Thu, 11 Jan 2018 11:26:35 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:37 +0300 Message-ID: <20180111082637.27295.78763.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 18/30] replay/replay-internal.c: track holding of replay_lock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This is modelled after the iothread mutex lock. We keep a TLS flag to indicate when that thread has acquired the lock and assert we don't double-lock or release when we shouldn't have. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- replay/replay-internal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/replay/replay-internal.c b/replay/replay-internal.c index fca8514..157c863 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -179,13 +179,24 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } +static __thread bool replay_locked; + +static bool replay_mutex_locked(void) +{ + return replay_locked; +} + void replay_mutex_lock(void) { + g_assert(!replay_mutex_locked()); qemu_mutex_lock(&lock); + replay_locked = true; } void replay_mutex_unlock(void) { + g_assert(replay_mutex_locked()); + replay_locked = false; qemu_mutex_unlock(&lock); } From patchwork Thu Jan 11 08:26:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124164 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp377232qgn; Thu, 11 Jan 2018 00:43:00 -0800 (PST) X-Google-Smtp-Source: ACJfBovcOPgOrZJ0sJ7VRhgf/aYxLhsX5x+vPpN2v6qtzSg8+QdhxU6LoI04YGe6Yz67Omfk8r1/ X-Received: by 10.37.239.74 with SMTP id w10mr15861838ybm.505.1515660180930; Thu, 11 Jan 2018 00:43:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660180; cv=none; d=google.com; s=arc-20160816; b=xBkOtU4b7uBvPHRVjprxWu2lFe8h8RbmpB7skip64zT/YBzSaWrkKq0YMmzqOe/wHz nvTvKkCey5UlMM8Xj4V73N8A8tMwr9bKovhn8E0h/TohVjAt4tMhZPPTkBoL1eraLCd6 TDt6E6MTS9rRCDTKulEw9NsNpL3GgDBE2mGqRjI8ObC4DQ6wEhXdR5sT7lxbuVqV5ye0 h9QJ9SPBRl2H1qVs8c2kMyBOeWXzs7tW8q4hLgLnP5IszhD/ETTn2Ed0gEjP1o0k8yXz c9IoKXY26d36wn4TZgZMz/xLr5RVi2ESdP48S5JOuMkRPZBtLM/d7N3Qhl3YpqKVMCfv YGKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=KzpNJiMEg8uyfEWj1jsl3leIXmlNYLnok6xi9ReuC1E=; b=xeboT6nRDw4FnZBXO7yxbaYXkqGzQf23ic7F1ic3dQLULYZTMen4vBjZrLjGqiw3c3 wyeeHN+oWv7EKIsPT1tDLckWpE9T4bu8RwVRhMtflcyoAC5/GZOpdOMxk6RtYRZJW7VG TpHsOO42rdv/gJ82MWQ85CtT3P4En3DsCHT75xdPB3CKOpYE2b0RKbmKdyIe50z53+Ca iSF0N0yQuPv81GkRdwROAyPGXc3EkjtHhH3E1fd4Ar9GIIR+wJ0gQ63bsWk7p/cNcGR1 7kmPdb+WQtTkbL/8M6e9Kk9ZhER1KOiL/xC3c5soXxbVkZbDq/k18LCI1eMun3cT7qm2 MgAQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u94si1226588ybi.702.2018.01.11.00.43.00 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:43:00 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYRw-0006G6-D6 for patch@linaro.org; Thu, 11 Jan 2018 03:43:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCE-0000tV-Qh for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCA-0001gv-Os for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:46 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41854) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCA-0001fr-CF for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:42 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 85CAB54006B; Thu, 11 Jan 2018 11:26:41 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:43 +0300 Message-ID: <20180111082643.27295.68605.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 19/30] replay: make locking visible outside replay code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The replay_mutex_lock/unlock/locked functions are now going to be used for ensuring lock-step behaviour between the two threads. Make them public API functions and also provide stubs for non-QEMU builds on common paths. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 14 ++++++++++++++ replay/replay-internal.c | 9 ++++----- replay/replay-internal.h | 5 ++--- stubs/replay.c | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b86d6bb..9973849 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -47,6 +47,20 @@ extern ReplayMode replay_mode; /* Name of the initial VM snapshot */ extern char *replay_snapshot; +/* Replay locking + * + * The locks are needed to protect the shared structures and log file + * when doing record/replay. They also are the main sync-point between + * the main-loop thread and the vCPU thread. This was a role + * previously filled by the BQL which has been busy trying to reduce + * its impact across the code. This ensures blocks of events stay + * sequential and reproducible. + */ + +void replay_mutex_lock(void); +void replay_mutex_unlock(void); +bool replay_mutex_locked(void); + /* Replay process control functions */ /*! Enables recording or saving event log with specified parameters */ diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 157c863..a9a6a64 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -169,6 +169,8 @@ void replay_finish_event(void) replay_fetch_data_kind(); } +static __thread bool replay_locked; + void replay_mutex_init(void) { qemu_mutex_init(&lock); @@ -179,9 +181,7 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } -static __thread bool replay_locked; - -static bool replay_mutex_locked(void) +bool replay_mutex_locked(void) { return replay_locked; } @@ -204,7 +204,7 @@ void replay_mutex_unlock(void) void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); int diff = (int)(replay_get_current_step() - replay_state.current_step); /* Time can only go forward */ @@ -215,6 +215,5 @@ void replay_save_instructions(void) replay_put_dword(diff); replay_state.current_step += diff; } - replay_mutex_unlock(); } } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 8e4c701..f5f8e96 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -100,12 +100,11 @@ int64_t replay_get_qword(void); void replay_get_array(uint8_t *buf, size_t *size); void replay_get_array_alloc(uint8_t **buf, size_t *size); -/* Mutex functions for protecting replay log file */ +/* Mutex functions for protecting replay log file and ensuring + * synchronisation between vCPU and main-loop threads. */ void replay_mutex_init(void); void replay_mutex_destroy(void); -void replay_mutex_lock(void); -void replay_mutex_unlock(void); /*! Checks error status of the file. */ void replay_check_error(void); diff --git a/stubs/replay.c b/stubs/replay.c index 9991ee5..cb050ef 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -73,3 +73,18 @@ uint64_t blkreplay_next_id(void) { return 0; } + +void replay_mutex_lock(void) +{ + abort(); +} + +void replay_mutex_unlock(void) +{ + abort(); +} + +bool replay_mutex_locked(void) +{ + return false; +} From patchwork Thu Jan 11 08:26:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124163 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp376312qgn; Thu, 11 Jan 2018 00:42:00 -0800 (PST) X-Google-Smtp-Source: ACJfBosq0xKl1RGireavlS3U1yfb/3IOOdNspshdQz3sp67PNlp7QWbyUwdHqHkRESxiNUOXCbkA X-Received: by 10.37.177.20 with SMTP id g20mr18141947ybj.190.1515660120085; Thu, 11 Jan 2018 00:42:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660120; cv=none; d=google.com; s=arc-20160816; b=OVn9fXxDUN1DeONu6doM99/w2nMH8lzj3fiCF9aC0fjeBSyMReVDWxBtx7TOO/fSoO RWklxvgMjeNsCtHUjtqFpQjeaO3RQYemhA7aZtGjoWZqgoypv5hiFtQtRKUE3xdryK7e TNaA5phtbFRjaL7sDfMiDqDk0gdte/Jq9xtZurh116bbPlE/MIpNpzXrCCJ9PGHksVJp N3Fjrkg/IdGroyVlf6Gccv5JyBPttuBjqnnxcq7nRypIzwdYDP9RYYd8jc/TUoCPfrVq u+O1LdyFgEy9QZYcizncrcBnZQl7PrAFST9DNoDP7sj0wwiKi3J4iWsN9TbBDl5r5JYJ 6SGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=RKIVGGOS2Op0jT2o7WfKvyFVwTvKAi8oO5yZsS8nYXo=; b=w6xx6Tbg39mZNukijOqd5iIy8MGuoZbdotIUPae66kIuizoMtXneWKj2dlLPyavUhg 2uYZUnzfomgtoA5kQjrxiED93OfwwLujU9FV+5q9PD/v9pto88D2ZeEcZonR/MokZMO7 Yby7fV9eZnmuxdoaLymVk4Rs5gKM+SV+Lyxexa3D+fk6ECh0eIc4YPwusAyAmiaODDja yI/h+g2K0FQKB5sSpmOJ7SA+s+pJeHRDth+XMMA9UdbxQFlpZS7w76869rLB9tkE3djz UsKuOBoMbdI3lrnaopLUtBqawMnKzg6jcyg69bzRRF0nFVZkf2+XjDT9pChW2hf2Vh2i +GwA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d9si689820ybl.688.2018.01.11.00.41.59 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:42:00 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53125 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYQx-0005Kt-Gd for patch@linaro.org; Thu, 11 Jan 2018 03:41:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47069) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCI-0000yw-KP for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCG-0001oR-ET for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:50 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41876) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCF-0001nb-TT for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:48 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 121E454006C; Thu, 11 Jan 2018 11:26:47 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:49 +0300 Message-ID: <20180111082648.27295.79176.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 20/30] replay: push replay_mutex_lock up the call tree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Now instead of using the replay_lock to guard the output of the log we now use it to protect the whole execution section. This replaces what the BQL used to do when it was held during TCG execution. We also introduce some rules for locking order - mainly that you cannot take the replay_mutex while holding the BQL. This leads to some slight sophistry during start-up and extending the replay_mutex_destroy function to unlock the mutex without checking for the BQL condition so it can be cleanly dropped in the non-replay case. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk -- v2: updated replay_mutex_lock/unlock functions as suggested by Paolo Bonzini updated docs --- cpus.c | 17 +++++++++++++++++ docs/replay.txt | 22 ++++++++++++++++++++++ include/sysemu/replay.h | 2 ++ replay/replay-char.c | 21 ++++++++------------- replay/replay-events.c | 18 +++++------------- replay/replay-internal.c | 33 +++++++++++++++++++++++---------- replay/replay-time.c | 10 +++++----- replay/replay.c | 38 ++++++++++++++++++-------------------- util/main-loop.c | 17 +++++++++++++---- vl.c | 2 ++ 10 files changed, 115 insertions(+), 65 deletions(-) diff --git a/cpus.c b/cpus.c index 79dda49..bafedfc 100644 --- a/cpus.c +++ b/cpus.c @@ -1323,6 +1323,8 @@ static void prepare_icount_for_run(CPUState *cpu) insns_left = MIN(0xffff, cpu->icount_budget); cpu->icount_decr.u16.low = insns_left; cpu->icount_extra = cpu->icount_budget - insns_left; + + replay_mutex_lock(); } } @@ -1338,6 +1340,8 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + replay_mutex_unlock(); } } @@ -1425,6 +1429,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) while (1) { + replay_mutex_lock(); + qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ @@ -1437,6 +1443,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); + if (!cpu) { cpu = first_cpu; } @@ -1749,12 +1757,21 @@ void pause_all_vcpus(void) } } + /* We need to drop the replay_lock so any vCPU threads woken up + * can finish their replay tasks + */ + replay_mutex_unlock(); + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { qemu_cpu_kick(cpu); } } + + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); } void cpu_resume(CPUState *cpu) diff --git a/docs/replay.txt b/docs/replay.txt index c52407f..959633e 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -49,6 +49,28 @@ Modifications of qemu include: * recording/replaying user input (mouse and keyboard) * adding internal checkpoints for cpu and io synchronization +Locking and thread synchronisation +---------------------------------- + +Previously the synchronisation of the main thread and the vCPU thread +was ensured by the holding of the BQL. However the trend has been to +reduce the time the BQL was held across the system including under TCG +system emulation. As it is important that batches of events are kept +in sequence (e.g. expiring timers and checkpoints in the main thread +while instruction checkpoints are written by the vCPU thread) we need +another lock to keep things in lock-step. This role is now handled by +the replay_mutex_lock. It used to be held only for each event being +written but now it is held for a whole execution period. This results +in a deterministic ping-pong between the two main threads. + +As the BQL is now a finer grained lock than the replay_lock it is almost +certainly a bug, and a source of deadlocks, to take the +replay_mutex_lock while the BQL is held. This is enforced by an assert. +While the unlocks are usually in the reverse order, this is not +necessary; you can drop the replay_lock while holding the BQL, without +doing a more complicated unlock_iothread/replay_unlock/lock_iothread +sequence. + Non-deterministic events ------------------------ diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 9973849..d026b28 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -63,6 +63,8 @@ bool replay_mutex_locked(void); /* Replay process control functions */ +/*! Enables and take replay locks (even if we don't use it) */ +void replay_init_locks(void); /*! Enables recording or saving event log with specified parameters */ void replay_configure(struct QemuOpts *opts); /*! Initializes timers used for snapshotting and enables events recording */ diff --git a/replay/replay-char.c b/replay/replay-char.c index cbf7c04..736cc8c 100755 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -96,25 +96,24 @@ void *replay_event_char_read_load(void) void replay_char_write_event_save(int res, int offset) { + g_assert(replay_mutex_locked()); + replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_WRITE); replay_put_dword(res); replay_put_dword(offset); - replay_mutex_unlock(); } void replay_char_write_event_load(int *res, int *offset) { + g_assert(replay_mutex_locked()); + replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_CHAR_WRITE)) { *res = replay_get_dword(); *offset = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing character write event in the replay log"); exit(1); } @@ -122,23 +121,21 @@ void replay_char_write_event_load(int *res, int *offset) int replay_char_read_all_load(uint8_t *buf) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + if (replay_next_event_is(EVENT_CHAR_READ_ALL)) { size_t size; int res; replay_get_array(buf, &size); replay_finish_event(); - replay_mutex_unlock(); res = (int)size; assert(res >= 0); return res; } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) { int res = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); return res; } else { - replay_mutex_unlock(); error_report("Missing character read all event in the replay log"); exit(1); } @@ -146,19 +143,17 @@ int replay_char_read_all_load(uint8_t *buf) void replay_char_read_all_save_error(int res) { + g_assert(replay_mutex_locked()); assert(res < 0); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL_ERROR); replay_put_dword(res); - replay_mutex_unlock(); } void replay_char_read_all_save_buf(uint8_t *buf, int offset) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL); replay_put_array(buf, offset); - replay_mutex_unlock(); } diff --git a/replay/replay-events.c b/replay/replay-events.c index e858254..a941efb 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -79,16 +79,14 @@ bool replay_has_events(void) void replay_flush_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } void replay_disable_events(void) @@ -102,14 +100,14 @@ void replay_disable_events(void) void replay_clear_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } /*! Adds specified async event to the queue */ @@ -136,9 +134,8 @@ void replay_add_event(ReplayAsyncEventKind event_kind, event->opaque2 = opaque2; event->id = id; - replay_mutex_lock(); + g_assert(replay_mutex_locked()); QTAILQ_INSERT_TAIL(&events_list, event, events); - replay_mutex_unlock(); } void replay_bh_schedule_event(QEMUBH *bh) @@ -210,10 +207,7 @@ void replay_save_events(int checkpoint) while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); replay_save_event(event, checkpoint); - - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } @@ -299,9 +293,7 @@ void replay_read_events(int checkpoint) } replay_finish_event(); read_event_kind = -1; - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); g_free(event); } diff --git a/replay/replay-internal.c b/replay/replay-internal.c index a9a6a64..a1a7686 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -174,30 +174,43 @@ static __thread bool replay_locked; void replay_mutex_init(void) { qemu_mutex_init(&lock); + /* Hold the mutex while we start-up */ + qemu_mutex_lock(&lock); + replay_locked = true; } -void replay_mutex_destroy(void) +bool replay_mutex_locked(void) { - qemu_mutex_destroy(&lock); + return replay_locked; } -bool replay_mutex_locked(void) +void replay_mutex_destroy(void) { - return replay_locked; + if (replay_mutex_locked()) { + qemu_mutex_unlock(&lock); + } + qemu_mutex_destroy(&lock); } +/* Ordering constraints, replay_lock must be taken before BQL */ void replay_mutex_lock(void) { - g_assert(!replay_mutex_locked()); - qemu_mutex_lock(&lock); - replay_locked = true; + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(!qemu_mutex_iothread_locked()); + g_assert(!replay_mutex_locked()); + qemu_mutex_lock(&lock); + replay_locked = true; + } } +/* BQL can't be held when releasing the replay_lock */ void replay_mutex_unlock(void) { - g_assert(replay_mutex_locked()); - replay_locked = false; - qemu_mutex_unlock(&lock); + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(replay_mutex_locked()); + replay_locked = false; + qemu_mutex_unlock(&lock); + } } /*! Saves cached instructions. */ diff --git a/replay/replay-time.c b/replay/replay-time.c index f70382a..6a7565e 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -17,13 +17,13 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock) { - replay_save_instructions(); if (replay_file) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + + replay_save_instructions(); replay_put_event(EVENT_CLOCK + kind); replay_put_qword(clock); - replay_mutex_unlock(); } return clock; @@ -46,16 +46,16 @@ void replay_read_next_clock(ReplayClockKind kind) /*! Reads next clock event from the input. */ int64_t replay_read_clock(ReplayClockKind kind) { + g_assert(replay_file && replay_mutex_locked()); + replay_account_executed_instructions(); if (replay_file) { int64_t ret; - replay_mutex_lock(); if (replay_next_event_is(EVENT_CLOCK + kind)) { replay_read_next_clock(kind); } ret = replay_state.cached_clock[kind]; - replay_mutex_unlock(); return ret; } diff --git a/replay/replay.c b/replay/replay.c index 4f24498..a3ab3bb 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -81,7 +81,7 @@ int replay_get_instructions(void) void replay_account_executed_instructions(void) { if (replay_mode == REPLAY_MODE_PLAY) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); if (replay_state.instructions_count > 0) { int count = (int)(replay_get_current_step() - replay_state.current_step); @@ -100,24 +100,22 @@ void replay_account_executed_instructions(void) qemu_notify_event(); } } - replay_mutex_unlock(); } } bool replay_exception(void) { + if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_EXCEPTION); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_exception(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -129,10 +127,9 @@ bool replay_has_exception(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_EXCEPTION); - replay_mutex_unlock(); } return res; @@ -141,17 +138,15 @@ bool replay_has_exception(void) bool replay_interrupt(void) { if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_INTERRUPT); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_interrupt(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -163,10 +158,9 @@ bool replay_has_interrupt(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_INTERRUPT); - replay_mutex_unlock(); } return res; } @@ -174,9 +168,8 @@ bool replay_has_interrupt(void) void replay_shutdown_request(ShutdownCause cause) { if (replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); replay_put_event(EVENT_SHUTDOWN + cause); - replay_mutex_unlock(); } } @@ -190,9 +183,9 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) return true; } - replay_mutex_lock(); if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) { replay_finish_event(); } else if (replay_state.data_kind != EVENT_ASYNC) { @@ -205,15 +198,20 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) checkpoint were processed */ res = replay_state.data_kind != EVENT_ASYNC; } else if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_put_event(EVENT_CHECKPOINT + checkpoint); replay_save_events(checkpoint); res = true; } out: - replay_mutex_unlock(); return res; } +void replay_init_locks(void) +{ + replay_mutex_init(); +} + static void replay_enable(const char *fname, int mode) { const char *fmode = NULL; @@ -233,8 +231,6 @@ static void replay_enable(const char *fname, int mode) atexit(replay_finish); - replay_mutex_init(); - replay_file = fopen(fname, fmode); if (replay_file == NULL) { fprintf(stderr, "Replay: open %s: %s\n", fname, strerror(errno)); @@ -274,6 +270,8 @@ void replay_configure(QemuOpts *opts) Location loc; if (!opts) { + /* we no longer need this lock */ + replay_mutex_destroy(); return; } diff --git a/util/main-loop.c b/util/main-loop.c index 7558eb5..1e928b3 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" #include "sysemu/cpus.h" +#include "sysemu/replay.h" #include "slirp/libslirp.h" #include "qemu/main-loop.h" #include "block/aio.h" @@ -245,18 +246,21 @@ static int os_host_main_loop_wait(int64_t timeout) timeout = SCALE_MS; } + if (timeout) { spin_counter = 0; - qemu_mutex_unlock_iothread(); } else { spin_counter++; } + qemu_mutex_unlock_iothread(); + + replay_mutex_unlock(); ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); - if (timeout) { - qemu_mutex_lock_iothread(); - } + replay_mutex_lock(); + + qemu_mutex_lock_iothread(); glib_pollfds_poll(); @@ -463,8 +467,13 @@ static int os_host_main_loop_wait(int64_t timeout) poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout); qemu_mutex_unlock_iothread(); + + replay_mutex_unlock(); + g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); if (g_poll_ret > 0) { for (i = 0; i < w->num; i++) { diff --git a/vl.c b/vl.c index ba3c5a9..27f5069 100644 --- a/vl.c +++ b/vl.c @@ -3091,6 +3091,8 @@ int main(int argc, char **argv, char **envp) qemu_init_cpu_list(); qemu_init_cpu_loop(); + + replay_init_locks(); qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); From patchwork Thu Jan 11 08:27:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124160 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp374664qgn; Thu, 11 Jan 2018 00:40:28 -0800 (PST) X-Google-Smtp-Source: ACJfBosmLgc59Ts5g8IoQd47tKVLCqym2HhhneLW/dxkaTHHwTc/QSgaPiYsxAxbBTqCWxK/L97K X-Received: by 10.129.87.65 with SMTP id l62mr16576ywb.380.1515660028692; Thu, 11 Jan 2018 00:40:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660028; cv=none; d=google.com; s=arc-20160816; b=qaadcTmSO4ZuLOXCyVAQ/BCOgT06Od+eb2jfu2tUng6KBk1TUc2QLeqOHxxconJw57 S+9fsCWNbqdSnIbivUSnh1pzZ8DVMl2Y5lulxxIyFlSpnEijnXlYdwHJ4acBcLxY0SU+ YnF6a1Zdxzh1vlxSxI0WQexfgPlmLUem7PqBcyZqhh1DAuNX7oZqqaFXm/vISwYbhmxC iRYpnDi2Xo40huwimC39It0Cq+qHOSdb1AklOoUpSI/Yyj91smEEF3/Cjs+4cBfEqeXE awn+MAEJGpNXOuqUtHGKFhFFadximqyXknp09mBeET3qXxiWemufYceUmIcwo7PkyiFN XYXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=4UZpeXhyff5ylYPlggZbo3RlxXmiNKu8NizLbWA8s0Y=; b=JT9LMXob1zRc9EKMJpQJCMTJy8Ly/6IMnVQl07U5cPlhvNMS85zZ419BXEwR6CDBIi lXje3oaTHuIhhpK3s3n2rJrE52U1ZjyuaDppsLSyatv/DaEO2a4X4O7p1+sgdZCxAJop CCUkghvz2X5WmoomqnCxfuGAb7gRPrT7iFDAKlMPhCAB7vuYx6R9HIt3QJwhoTFqOcH1 Itp82vnvNJkVajmng3hOJZobKC/OsCWu6vA7C3rYQjx4zO4nyIYq6BI4SSQzcUTaFNQR M7JDnyyXZQ4JHB9+rxY4Gmfx4o6R1uXttG4PV15zMjPTm62vYdan0in0n67xmKKQ3Mfh QzFA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u63si3826334ywf.154.2018.01.11.00.40.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:40:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYPU-00040y-4Y for patch@linaro.org; Thu, 11 Jan 2018 03:40:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCd-0001H1-Hl for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCc-0002Hf-DX for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:11 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41960) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCc-0002GZ-5R for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:10 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 5212F54006B; Thu, 11 Jan 2018 11:27:09 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:27:11 +0300 Message-ID: <20180111082711.27295.21310.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 24/30] scripts/qemu-gdb: add simple tcg lock status helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Add a simple helper to dump lock state. Signed-off-by: Alex Bennée --- scripts/qemu-gdb.py | 3 ++- scripts/qemugdb/tcg.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 scripts/qemugdb/tcg.py diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index b3f8e04..d58213e 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -26,7 +26,7 @@ import os, sys sys.path.append(os.path.dirname(__file__)) -from qemugdb import aio, mtree, coroutine +from qemugdb import aio, mtree, coroutine, tcg class QemuCommand(gdb.Command): '''Prefix for QEMU debug support commands''' @@ -38,6 +38,7 @@ QemuCommand() coroutine.CoroutineCommand() mtree.MtreeCommand() aio.HandlersCommand() +tcg.TCGLockStatusCommand() coroutine.CoroutineSPFunction() coroutine.CoroutinePCFunction() diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py new file mode 100644 index 0000000..8c7f1d7 --- /dev/null +++ b/scripts/qemugdb/tcg.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# GDB debugging support, TCG status +# +# Copyright 2016 Linaro Ltd +# +# Authors: +# Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. +# +# Contributions after 2012-01-13 are licensed under the terms of the +# GNU GPL, version 2 or (at your option) any later version. + +# 'qemu tcg-lock-status' -- display the TCG lock status across threads + +import gdb + +class TCGLockStatusCommand(gdb.Command): + '''Display TCG Execution Status''' + def __init__(self): + gdb.Command.__init__(self, 'qemu tcg-lock-status', gdb.COMMAND_DATA, + gdb.COMPLETE_NONE) + + def invoke(self, arg, from_tty): + gdb.write("Thread, BQL (iothread_mutex), Replay, Blocked?\n") + for thread in gdb.inferiors()[0].threads(): + thread.switch() + + iothread = gdb.parse_and_eval("iothread_locked") + replay = gdb.parse_and_eval("replay_locked") + + frame = gdb.selected_frame() + if frame.name() == "__lll_lock_wait": + frame.older().select() + mutex = gdb.parse_and_eval("mutex") + owner = gdb.parse_and_eval("mutex->__data.__owner") + blocked = ("__lll_lock_wait waiting on %s from %d" % + (mutex, owner)) + else: + blocked = "not blocked" + + gdb.write("%d/%d, %s, %s, %s\n" % (thread.num, thread.ptid[1], + iothread, replay, blocked)) From patchwork Thu Jan 11 08:27:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124158 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp372315qgn; Thu, 11 Jan 2018 00:38:12 -0800 (PST) X-Google-Smtp-Source: ACJfBosbGA2w2JSSuUqAXUHKXP1N0s91u+hdNjVRyJ2tYvIOv9V9YjwJ86C00/T0bqdVkRFJrHNT X-Received: by 10.37.63.1 with SMTP id m1mr10064022yba.325.1515659892737; Thu, 11 Jan 2018 00:38:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515659892; cv=none; d=google.com; s=arc-20160816; b=mpV+5/rj5jiRT92ZiCZPh96zWL84bRg++PfHQAXL6fBDh51CYxrpp6C96TrXzz/fns geX/gOQNE+vhk+cJ3G+GeWsUzp+F5rckYWs7w9MQ+txsB7fyBt32oEEtZxGzhWxH//p9 MyZ9y39++/6zaL5OyycYfP0Yc4JWBUqdCeYZ4QkvVt3HbrbW1IUC4fNQtZaYimtCbb2E 4pUJsfmyfUIlRVwA1FWLW3XQU1Z3ebxzG16ASMCkBkV34pVhYPQD7kEl9MCqVqw8CYB+ fKNcvdpU/MoBwMoFppQLlEno375FRVj8N4oLdkf0tSFvmKAu6AAda3ornfl4RgwIA87Q agxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=ao0ZNhO/CXB6kBnt8qc9CE814GDDthFfdppliljD+YI=; b=t7l8dlnmpL9E5hL2HXqaYU8jwyR3NdBoS9i2dMtlUHcTn1eLrDYnqsvWXO9+t0gsGH dHScdUmwNRdds+BDL4DQXxoTyCizL043tiElx2qEhKC6f9IvSQ1k37LzYE79YyaaedVa RC1Mud+WpIPQP4HPZMB0eHACPFLBjnTTwmO0wXX7iNP0xNDO1VCfMhHDbvjtm1Ha+BOQ UkE24ZA4UIE8PLJbwO/753Xp4WPOy31yWCVf9wpRWR9WTGYYJ6dhFwHdabkjyQ1wb75l lHPjgcB6HFjpOMXEWX9mUjUm9nbIJd78h1vpcXedyCDk1oxG5QB/CLfASHYxdZXIwYhH cUTQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x83si211918ybx.715.2018.01.11.00.38.12 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:38:12 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYNI-00023m-80 for patch@linaro.org; Thu, 11 Jan 2018 03:38:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47436) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCl-0001NF-Nh for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCi-0002Ql-2y for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:19 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41996) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCh-0002Q6-LH for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:15 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id CBB4D54006C; Thu, 11 Jan 2018 11:27:14 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:27:16 +0300 Message-ID: <20180111082716.27295.11796.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 25/30] util/qemu-thread-*: add qemu_lock, locked and unlock trace events X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Signed-off-by: Alex Bennée --- v1 - fix merge conflicts with existing tracing - add trylock/cond_wait traces --- include/qemu/thread.h | 19 +++++++++++++++---- util/qemu-thread-posix.c | 21 ++++++++++++--------- util/trace-events | 7 ++++--- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 9910f49..35375f0 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -22,9 +22,16 @@ typedef struct QemuThread QemuThread; void qemu_mutex_init(QemuMutex *mutex); void qemu_mutex_destroy(QemuMutex *mutex); -void qemu_mutex_lock(QemuMutex *mutex); -int qemu_mutex_trylock(QemuMutex *mutex); -void qemu_mutex_unlock(QemuMutex *mutex); +int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line); +void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line); +void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line); + +#define qemu_mutex_lock(mutex) \ + qemu_mutex_lock_impl(mutex, __FILE__, __LINE__) +#define qemu_mutex_trylock(mutex) \ + qemu_mutex_trylock_impl(mutex, __FILE__, __LINE__) +#define qemu_mutex_unlock(mutex) \ + qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__) /* Prototypes for other functions are in thread-posix.h/thread-win32.h. */ void qemu_rec_mutex_init(QemuRecMutex *mutex); @@ -39,7 +46,11 @@ void qemu_cond_destroy(QemuCond *cond); */ void qemu_cond_signal(QemuCond *cond); void qemu_cond_broadcast(QemuCond *cond); -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); +void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, + const char *file, const int line); + +#define qemu_cond_wait(cond, mutex) \ + qemu_cond_wait_impl(cond, mutex, __FILE__, __LINE__) void qemu_sem_init(QemuSemaphore *sem, int init); void qemu_sem_post(QemuSemaphore *sem); diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 959a570..b789cf3 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -57,26 +57,28 @@ void qemu_mutex_destroy(QemuMutex *mutex) error_exit(err, __func__); } -void qemu_mutex_lock(QemuMutex *mutex) +void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); + trace_qemu_mutex_lock(mutex, file, line); + err = pthread_mutex_lock(&mutex->lock); if (err) error_exit(err, __func__); - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); } -int qemu_mutex_trylock(QemuMutex *mutex) +int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); err = pthread_mutex_trylock(&mutex->lock); if (err == 0) { - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); return 0; } if (err != EBUSY) { @@ -85,15 +87,16 @@ int qemu_mutex_trylock(QemuMutex *mutex) return -EBUSY; } -void qemu_mutex_unlock(QemuMutex *mutex) +void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); - trace_qemu_mutex_unlocked(mutex); err = pthread_mutex_unlock(&mutex->lock); if (err) error_exit(err, __func__); + + trace_qemu_mutex_unlock(mutex, file, line); } void qemu_rec_mutex_init(QemuRecMutex *mutex) @@ -152,14 +155,14 @@ void qemu_cond_broadcast(QemuCond *cond) error_exit(err, __func__); } -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) +void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line) { int err; assert(cond->initialized); - trace_qemu_mutex_unlocked(mutex); + trace_qemu_mutex_unlock(mutex, file, line); err = pthread_cond_wait(&cond->cond, &mutex->lock); - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); if (err) error_exit(err, __func__); } diff --git a/util/trace-events b/util/trace-events index 025499f..515e625 100644 --- a/util/trace-events +++ b/util/trace-events @@ -56,6 +56,7 @@ lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d" lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d" lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter" -# util/qemu-thread-posix.c -qemu_mutex_locked(void *lock) "locked mutex %p" -qemu_mutex_unlocked(void *lock) "unlocked mutex %p" +# util/qemu-thread.c +qemu_mutex_lock(void *mutex, const char *file, const int line) "waiting on mutex %p (%s:%d)" +qemu_mutex_locked(void *mutex, const char *file, const int line) "taken mutex %p (%s:%d)" +qemu_mutex_unlock(void *mutex, const char *file, const int line) "released mutex %p (%s:%d)" From patchwork Thu Jan 11 08:27:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124165 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp378712qgn; Thu, 11 Jan 2018 00:44:54 -0800 (PST) X-Google-Smtp-Source: ACJfBovw7GRkc6zxBBDYFY1qvhZ2hkkl74G76OHu+5TqyO3uk9aQaR9SPaosbaTqhR8pjm6unC9B X-Received: by 10.129.141.7 with SMTP id d7mr18765208ywg.354.1515660294682; Thu, 11 Jan 2018 00:44:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660294; cv=none; d=google.com; s=arc-20160816; b=wNalfS3QxBVrtH2HT4Q2D5mDn6EMG3i467+Is3PV+VdWnSBZatPzlbuEJmGKb1cOIm eyRjmGzr98D22OjPTDzAKI839f1L+42Km57HzsHZcUiqMuL+1VGBuW/Q2gPgVEUm+vQj awNwV0GwT4yRXRvw8UMtvnqHcf+8SHtegUGI3jw7xe0qxTZ/ngQYmkwjC7jzJXhcYaou ptoFpx/g2vqfy4LLkzUATH6LmAEsPA6yAzGZhsXtzHlfdqETx+9NFaFvPjzRrvj8Aeat TpcbjHQgEOEPG6LEzxVeo1R/rdsMy49wJ4A3PdUrnULfEugwSgSMtEN3UrmguCvQ8iKi ZoRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=6ZF4uuyx323RO0l4b78Ckk7bG2oTu55KgVjEeQHuR4I=; b=laD7bQ5HF2gdGWkXG/Uhk2Ti0K4CJLwtrO6j3crOp49m5AXQRHIZd7jMrcH6BhLMsZ 6gXm4tJIwHkmZ0aoF43TLJf6OUY58qhTEwHahXgPYWbSc2pU8H7RF9ladvjVN6Gas2Xe ayasR4Of8+PcLuoacF15limVuiwV5XQMXzRZJjgCQPw2i2AfoOTUbh6R/mVWVkjdfCle 7MRpQ0HlTRR52KyJjv8IFJDdDD3RF1u9qKRRvV6I/MdVpe/aSYznWWPi/CqMt+X76hyG unwFdB01Kq1mA6dPOjCM8mWoYfb2dCIlRko+5m1ZzMQd1XuWTj9AAGkzflqX6w/8NGvz wKxQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id o8si3920847ywa.213.2018.01.11.00.44.54 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:44:54 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53155 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYTm-000821-4I for patch@linaro.org; Thu, 11 Jan 2018 03:44:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47471) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCo-0001Po-HS for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCn-0002aE-HN for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:22 -0500 Received: from mail.ispras.ru ([83.149.199.45]:42016) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCn-0002Yo-4H for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:21 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4CADF54006A; Thu, 11 Jan 2018 11:27:20 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:27:22 +0300 Message-ID: <20180111082722.27295.91989.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 26/30] scripts/analyse-locks-simpletrace.py: script to analyse lock times X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This script allows analysis of mutex acquisition and hold times based on a trace file. Given a trace control file of: qemu_mutex_lock qemu_mutex_locked qemu_mutex_unlock And running with: $QEMU $QEMU_ARGS -trace events=./lock-trace You can analyse the results with: ./scripts/analyse-locks-simpletrace.py trace-events-all ./trace-21812 Signed-off-by: Alex Bennée --- scripts/analyse-locks-simpletrace.py | 99 ++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 scripts/analyse-locks-simpletrace.py diff --git a/scripts/analyse-locks-simpletrace.py b/scripts/analyse-locks-simpletrace.py new file mode 100755 index 0000000..b72c951 --- /dev/null +++ b/scripts/analyse-locks-simpletrace.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Analyse lock events and +# +# Author: Alex Bennée +# + +import os +import simpletrace +import argparse +import numpy as np + +class MutexAnalyser(simpletrace.Analyzer): + "A simpletrace Analyser for checking locks." + + def __init__(self): + self.locks = 0 + self.locked = 0 + self.unlocks = 0 + self.mutex_records = {} + + def _get_mutex(self, mutex): + if not mutex in self.mutex_records: + self.mutex_records[mutex] = {"locks": 0, + "lock_time": 0, + "acquire_times": [], + "locked": 0, + "locked_time": 0, + "held_times": [], + "unlocked": 0} + + return self.mutex_records[mutex] + + def qemu_mutex_lock(self, timestamp, mutex, filename, line): + self.locks += 1 + rec = self._get_mutex(mutex) + rec["locks"] += 1 + rec["lock_time"] = timestamp[0] + rec["lock_loc"] = (filename, line) + + def qemu_mutex_locked(self, timestamp, mutex, filename, line): + self.locked += 1 + rec = self._get_mutex(mutex) + rec["locked"] += 1 + rec["locked_time"] = timestamp[0] + acquire_time = rec["locked_time"] - rec["lock_time"] + rec["locked_loc"] = (filename, line) + rec["acquire_times"].append(acquire_time) + + def qemu_mutex_unlock(self, timestamp, mutex, filename, line): + self.unlocks += 1 + rec = self._get_mutex(mutex) + rec["unlocked"] += 1 + held_time = timestamp[0] - rec["locked_time"] + rec["held_times"].append(held_time) + rec["unlock_loc"] = (filename, line) + + +def get_args(): + "Grab options" + parser = argparse.ArgumentParser() + parser.add_argument("--output", "-o", type=str, help="Render plot to file") + parser.add_argument("events", type=str, help='trace file read from') + parser.add_argument("tracefile", type=str, help='trace file read from') + return parser.parse_args() + +if __name__ == '__main__': + args = get_args() + + # Gather data from the trace + analyser = MutexAnalyser() + simpletrace.process(args.events, args.tracefile, analyser) + + print ("Total locks: %d, locked: %d, unlocked: %d" % + (analyser.locks, analyser.locked, analyser.unlocks)) + + # Now dump the individual lock stats + for key, val in sorted(analyser.mutex_records.iteritems(), + key=lambda (k,v): v["locks"]): + print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" % + (key, val["locks"], val["locked"], val["unlocked"])) + + acquire_times = np.array(val["acquire_times"]) + if len(acquire_times) > 0: + print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" % + (acquire_times.min(), np.median(acquire_times), + acquire_times.mean(), acquire_times.max())) + + held_times = np.array(val["held_times"]) + if len(held_times) > 0: + print (" Held Time: min:%d median:%d avg:%.2f max:%d" % + (held_times.min(), np.median(held_times), + held_times.mean(), held_times.max())) + + # Check if any locks still held + if val["locks"] > val["locked"]: + print (" LOCK HELD (%s:%s)" % (val["locked_loc"])) + print (" BLOCKED (%s:%s)" % (val["lock_loc"])) From patchwork Thu Jan 11 08:27:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124161 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp375567qgn; Thu, 11 Jan 2018 00:41:16 -0800 (PST) X-Google-Smtp-Source: ACJfBosyBbj/xVaLEbyDEA1rlSSPzvLEIv6Lmlpv9Gel041AdgrnDwE0aljyW3Ay/9puHCdWId9o X-Received: by 10.37.103.69 with SMTP id b66mr19210337ybc.92.1515660076206; Thu, 11 Jan 2018 00:41:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660076; cv=none; d=google.com; s=arc-20160816; b=xwY+OhoHpinLOxmyJ3XigpF6DjmNMtir0CecOj5lFxUULYyUTez2j4+T3JLHagPvWu iBUgPRJM3W063xafk/Dhd8pGnRiXObFo3eXy7CuvoVrpj7lum8Zo4mUFMW96r6RfARv6 RpeE/c+oCYN6RpBNK5nUELUJnRmomAk1iNbiiJ7Kw6mVIW0FDWuWtinZG7eF1oNX2V4B GrfT2zfJ3qCWS2yv5ezmSKB3ObY5FTO/aZmRawzBYTK6ZjXicM/Bwg/e9tA8vAx8Ml4T kygAhipN7dVTulhgoC6Kab7EwcyGJrCRCQzK3DNYVnrRmQV9bMLVpCtbppw3QApNq+sA A8tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=v9IcqYv/yTMbdIsaamfWIMaz4pDbaHYdRiABxfCNKtU=; b=D73CTat9DHXDZD6STQSwREsBDOszRgxK2KhiX51p5pliCvNAZIkQ4tnfv3SlPwd/82 kOPdLANTJ7V9/pPAflI1a3Imp60l0RqqJagnvbdGxXz88jtnKn2yYKtczqKG8fXdO3dq VGFke+wg6yikXs2aLLZf+VCBlCxNsZYQccnxENLe4MyUMu4C3XAjibwF5fEupQMlwfjF incdpLSP8MD6c58Zh3JECEDG1dg+9P+ghI0g1F/WjQ+5SSNBREj9Rrzgoopv3vdstKWp w4wBYM9OY+V3wVhijFaag7bq1p2LHqqLSqeGt5EvvvSfP9nWFRKNOThx1DbHEcwsRm5d hynA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c126si3869230ywe.482.2018.01.11.00.41.16 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:41:16 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53118 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYQF-0004fL-Ia for patch@linaro.org; Thu, 11 Jan 2018 03:41:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47597) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCx-0001Xi-7C for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCt-0002jb-2V for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:31 -0500 Received: from mail.ispras.ru ([83.149.199.45]:42032) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCs-0002iZ-M1 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:26 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C2CD354006D; Thu, 11 Jan 2018 11:27:25 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:27:27 +0300 Message-ID: <20180111082727.27295.94934.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 27/30] scripts/replay-dump.py: replay log dumper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This script is a debugging tool for looking through the contents of a replay log file. It is incomplete but should fail gracefully at events it doesn't understand. It currently understands two different log formats as the audio record/replay support was merged during since MTTCG. It was written to help debug what has caused the BQL changes to break replay support. Signed-off-by: Alex Bennée --- v2 - yet another update to the log format --- scripts/replay-dump.py | 308 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100755 scripts/replay-dump.py diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py new file mode 100755 index 0000000..203bb31 --- /dev/null +++ b/scripts/replay-dump.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Dump the contents of a recorded execution stream +# +# Copyright (c) 2017 Alex Bennée +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +import argparse +import struct +from collections import namedtuple + +# This mirrors some of the global replay state which some of the +# stream loading refers to. Some decoders may read the next event so +# we need handle that case. Calling reuse_event will ensure the next +# event is read from the cache rather than advancing the file. + +class ReplayState(object): + def __init__(self): + self.event = -1 + self.event_count = 0 + self.already_read = False + self.current_checkpoint = 0 + self.checkpoint = 0 + + def set_event(self, ev): + self.event = ev + self.event_count += 1 + + def get_event(self): + self.already_read = False + return self.event + + def reuse_event(self, ev): + self.event = ev + self.already_read = True + + def set_checkpoint(self): + self.checkpoint = self.event - self.checkpoint_start + + def get_checkpoint(self): + return self.checkpoint + +replay_state = ReplayState() + +# Simple read functions that mirror replay-internal.c +# The file-stream is big-endian and manually written out a byte at a time. + +def read_byte(fin): + "Read a single byte" + return struct.unpack('>B', fin.read(1))[0] + +def read_event(fin): + "Read a single byte event, but save some state" + if replay_state.already_read: + return replay_state.get_event() + else: + replay_state.set_event(read_byte(fin)) + return replay_state.event + +def read_word(fin): + "Read a 16 bit word" + return struct.unpack('>H', fin.read(2))[0] + +def read_dword(fin): + "Read a 32 bit word" + return struct.unpack('>I', fin.read(4))[0] + +def read_qword(fin): + "Read a 64 bit word" + return struct.unpack('>Q', fin.read(8))[0] + +# Generic decoder structure +Decoder = namedtuple("Decoder", "eid name fn") + +def call_decode(table, index, dumpfile): + "Search decode table for next step" + decoder = next((d for d in table if d.eid == index), None) + if not decoder: + print "Could not decode index: %d" % (index) + print "Entry is: %s" % (decoder) + print "Decode Table is:\n%s" % (table) + return False + else: + return decoder.fn(decoder.eid, decoder.name, dumpfile) + +# Print event +def print_event(eid, name, string=None, event_count=None): + "Print event with count" + if not event_count: + event_count = replay_state.event_count + + if string: + print "%d:%s(%d) %s" % (event_count, name, eid, string) + else: + print "%d:%s(%d)" % (event_count, name, eid) + + +# Decoders for each event type + +def decode_unimp(eid, name, _unused_dumpfile): + "Unimplimented decoder, will trigger exit" + print "%s not handled - will now stop" % (name) + return False + +# Checkpoint decoder +def swallow_async_qword(eid, name, dumpfile): + "Swallow a qword of data without looking at it" + step_id = read_qword(dumpfile) + print " %s(%d) @ %d" % (name, eid, step_id) + return True + +async_decode_table = [ Decoder(0, "REPLAY_ASYNC_EVENT_BH", swallow_async_qword), + Decoder(1, "REPLAY_ASYNC_INPUT", decode_unimp), + Decoder(2, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), + Decoder(3, "REPLAY_ASYNC_CHAR_READ", decode_unimp), + Decoder(4, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), + Decoder(5, "REPLAY_ASYNC_EVENT_NET", decode_unimp), +] +# See replay_read_events/replay_read_event +def decode_async(eid, name, dumpfile): + """Decode an ASYNC event""" + + print_event(eid, name) + + async_event_kind = read_byte(dumpfile) + async_event_checkpoint = read_byte(dumpfile) + + if async_event_checkpoint != replay_state.current_checkpoint: + print " mismatch between checkpoint %d and async data %d" % ( + replay_state.current_checkpoint, async_event_checkpoint) + return True + + return call_decode(async_decode_table, async_event_kind, dumpfile) + + +def decode_instruction(eid, name, dumpfile): + ins_diff = read_dword(dumpfile) + print_event(eid, name, "0x%x" % (ins_diff)) + return True + +def decode_audio_out(eid, name, dumpfile): + audio_data = read_dword(dumpfile) + print_event(eid, name, "%d" % (audio_data)) + return True + +def decode_checkpoint(eid, name, dumpfile): + """Decode a checkpoint. + + Checkpoints contain a series of async events with their own specific data. + """ + replay_state.set_checkpoint() + # save event count as we peek ahead + event_number = replay_state.event_count + next_event = read_event(dumpfile) + + # if the next event is EVENT_ASYNC there are a bunch of + # async events to read, otherwise we are done + if next_event != 3: + print_event(eid, name, "no additional data", event_number) + else: + print_event(eid, name, "more data follows", event_number) + + replay_state.reuse_event(next_event) + return True + +def decode_checkpoint_init(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_interrupt(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_clock(eid, name, dumpfile): + clock_data = read_qword(dumpfile) + print_event(eid, name, "0x%x" % (clock_data)) + return True + + +# pre-MTTCG merge +v5_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_CLOCK_HOST", decode_clock), + Decoder(9, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(10, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(11, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(12, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(13, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(14, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(15, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(17, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(18, "EVENT_CP_RESET", decode_checkpoint), +] + +# post-MTTCG merge, AUDIO support added +v6_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(9, "EVENT_AUDIO_IN", decode_unimp), + Decoder(10, "EVENT_CLOCK_HOST", decode_clock), + Decoder(11, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(12, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(13, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(14, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(15, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(17, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(18, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(19, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(20, "EVENT_CP_RESET", decode_checkpoint), +] + +# Shutdown cause added +v7_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_SHUTDOWN_HOST_ERR", decode_unimp), + Decoder(6, "EVENT_SHUTDOWN_HOST_QMP", decode_unimp), + Decoder(7, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_unimp), + Decoder(8, "EVENT_SHUTDOWN_HOST_UI", decode_unimp), + Decoder(9, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_unimp), + Decoder(10, "EVENT_SHUTDOWN_GUEST_RESET", decode_unimp), + Decoder(11, "EVENT_SHUTDOWN_GUEST_PANIC", decode_unimp), + Decoder(12, "EVENT_SHUTDOWN___MAX", decode_unimp), + Decoder(13, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(14, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(15, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(16, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(17, "EVENT_AUDIO_IN", decode_unimp), + Decoder(18, "EVENT_CLOCK_HOST", decode_clock), + Decoder(19, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(20, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(21, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(22, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(23, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(24, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(25, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(26, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(27, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(28, "EVENT_CP_RESET", decode_checkpoint), +] + +def parse_arguments(): + "Grab arguments for script" + parser = argparse.ArgumentParser() + parser.add_argument("-f", "--file", help='record/replay dump to read from', + required=True) + return parser.parse_args() + +def decode_file(filename): + "Decode a record/replay dump" + dumpfile = open(filename, "rb") + + # read and throwaway the header + version = read_dword(dumpfile) + junk = read_qword(dumpfile) + + print "HEADER: version 0x%x" % (version) + + if version == 0xe02007: + event_decode_table = v7_event_table + replay_state.checkpoint_start = 12 + elif version == 0xe02006: + event_decode_table = v6_event_table + replay_state.checkpoint_start = 12 + else: + event_decode_table = v5_event_table + replay_state.checkpoint_start = 10 + + try: + decode_ok = True + while decode_ok: + event = read_event(dumpfile) + decode_ok = call_decode(event_decode_table, event, dumpfile) + finally: + dumpfile.close() + +if __name__ == "__main__": + args = parse_arguments() + decode_file(args.file) From patchwork Thu Jan 11 08:27:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124166 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp379472qgn; Thu, 11 Jan 2018 00:45:47 -0800 (PST) X-Google-Smtp-Source: ACJfBouk2IJ94vS4CaPtrHYlk0qBo2UlTx+9ni567gvbGlvEJ2bNDgpCTSanfNbx8PRtHCv9Wfcd X-Received: by 10.37.209.132 with SMTP id i126mr16368917ybg.29.1515660347034; Thu, 11 Jan 2018 00:45:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660347; cv=none; d=google.com; s=arc-20160816; b=ZpgrsNxkPSCxFT4cYegdfRVH8qi8CDcLQSedLVlv8Un3sqFIFd2xFRKbDHnued41c0 Cc8eLruzQiMwKY6vGUUpMICS/RZ3NKT1jprWjFlXbzeFz8xiqDg7KDIRQ56g/ugyQphW qXGfN6T5ov6PK4XrEwDSn/PRHcFz/95c0r8iNssT8F7GUVKAc0iCPVdFSWzmOMwPMUQ/ FZdEmyF3akFy6a57+W6PaH5uUyLNN74L9QRyomr4kPagolj47LSbiXzZLbTM5nM/eQ86 wLczPttjaSnBck5NNqs67tHNSgqT+T797lfsHzvMXmrhL30Z4UU8RC0qx3YaqnTjF/G/ hAFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=zAUkMS9H/iqNw6WMrhsAsWzBLobH9rhIKM7nbLWih4U=; b=FMZGbJQdec61x00I8gR4FATzZ9pnbqjx6YpvlWNmQka5WXD0FC7mrwboN99kHMH1e4 y+QdSsjIykQmkiPKTyqQy/LGZGQW0XWs4ktDl1Py6hkIYKTUAKzgARU+P+cUMcM8+uB8 n5aAPP7lqgW9DkFVXdX8yVLmCzYPFx8Dw93nhBxQP+RCEkHRmqjfafxh1uOuwZIDFTKV Ju+jgcvFF9+orv9LmwMjVvjaVY7ctdV04VqMyd1dl0iYa+RFe0figrm7HlzIdIq+ko+S LLm8D7Sxi/m+inbAd/pbfqh3M9eTSI3lKH7ecWesHubMFbgBUpGNqhsGZIvhmSJz++0j Qv/w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id o12si776395ybk.347.2018.01.11.00.45.46 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:45:47 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53147 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYUc-0007se-H8 for patch@linaro.org; Thu, 11 Jan 2018 03:45:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCz-0001ZR-JC for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYCy-0002ti-J0 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:33 -0500 Received: from mail.ispras.ru ([83.149.199.45]:42060) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYCy-0002sm-7T for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:27:32 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 58D7654006E; Thu, 11 Jan 2018 11:27:31 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:27:33 +0300 Message-ID: <20180111082733.27295.51978.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH v3 28/30] scripts/qemu-gdb/timers.py: new helper to dump timer state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This introduces the qemu-gdb command "qemu timers" which will dump the state of the main timers in the system. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé --- scripts/qemu-gdb.py | 3 ++- scripts/qemugdb/timers.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 scripts/qemugdb/timers.py diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index d58213e..690827e 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -26,7 +26,7 @@ import os, sys sys.path.append(os.path.dirname(__file__)) -from qemugdb import aio, mtree, coroutine, tcg +from qemugdb import aio, mtree, coroutine, tcg, timers class QemuCommand(gdb.Command): '''Prefix for QEMU debug support commands''' @@ -39,6 +39,7 @@ coroutine.CoroutineCommand() mtree.MtreeCommand() aio.HandlersCommand() tcg.TCGLockStatusCommand() +timers.TimersCommand() coroutine.CoroutineSPFunction() coroutine.CoroutinePCFunction() diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py new file mode 100644 index 0000000..be71a00 --- /dev/null +++ b/scripts/qemugdb/timers.py @@ -0,0 +1,54 @@ +#!/usr/bin/python +# GDB debugging support +# +# Copyright 2017 Linaro Ltd +# +# Author: Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. + +# 'qemu timers' -- display the current timerlists + +import gdb + +class TimersCommand(gdb.Command): + '''Display the current QEMU timers''' + + def __init__(self): + 'Register the class as a gdb command' + gdb.Command.__init__(self, 'qemu timers', gdb.COMMAND_DATA, + gdb.COMPLETE_NONE) + + def dump_timers(self, timer): + "Follow a timer and recursively dump each one in the list." + # timer should be of type QemuTimer + gdb.write(" timer %s/%s (cb:%s,opq:%s)\n" % ( + timer['expire_time'], + timer['scale'], + timer['cb'], + timer['opaque'])) + + if int(timer['next']) > 0: + self.dump_timers(timer['next']) + + + def process_timerlist(self, tlist, ttype): + gdb.write("Processing %s timers\n" % (ttype)) + gdb.write(" clock %s is enabled:%s, last:%s\n" % ( + tlist['clock']['type'], + tlist['clock']['enabled'], + tlist['clock']['last'])) + if int(tlist['active_timers']) > 0: + self.dump_timers(tlist['active_timers']) + + + def invoke(self, arg, from_tty): + 'Run the command' + main_timers = gdb.parse_and_eval("main_loop_tlg") + + # This will break if QEMUClockType in timer.h is redfined + self.process_timerlist(main_timers['tl'][0], "Realtime") + self.process_timerlist(main_timers['tl'][1], "Virtual") + self.process_timerlist(main_timers['tl'][2], "Host") + self.process_timerlist(main_timers['tl'][3], "Virtual RT")