From patchwork Tue Oct 31 11:25:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117591 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3789845qgn; Tue, 31 Oct 2017 04:38:33 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RniEqIdPkF4N21Hi7MGg48C20/Kkcm8JItF3vYHGbppFnHS42NtjygSgp2tJA3UJTJcUYo X-Received: by 10.37.210.19 with SMTP id j19mr915938ybg.476.1509449913457; Tue, 31 Oct 2017 04:38:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449913; cv=none; d=google.com; s=arc-20160816; b=Zmed5hB8+/oS2dDtn4NxUU2LNooMiHsT/vDDQqt9MVHghfqQJk08fLa+W1nzePMixS 9lH5LIBY9e2h+EaNoQYpqXfu/YNBLqUYnFBmmDnv72UWs1sPcUEt9xD8raOI2F/aWuzw JjLs/8URz7d0o8HX+kMdXGmoO0mTBB8jcz8iKgdMcTFXi03jdiiYXFBOhXKjOL8Duxb6 9XVVAbkFz8AmFdFv956QfKkeCNDFeAiJY//pejMuL3YeJUWLRSeI80sk92hVDLnf29HP R9lLqz0bY1+NTYphyr6P8fqtuhaVqFKfqLY0ZFRk9D2MhUs7DgUsMev/p3+U3YNe32Qe Cf8w== 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=rs1qWJWv8UDbdM1egYNaxIk0TpwVSiUjobYQ5TjYI7s=; b=g5rctRRt0VLZk0e9aPuSfG3hX3IawKqhN1b/MdjYrHS6DoSDknJI/P5YnkTpi8gQZ+ 54Gg9IXJ8l0plx8G9yVetvpbaVZEo5ZZGN5rmsb14Zq0L04iLkIM1DyTDzDTeZOk0qsO ZYX9eJheXOVCxTHzJYWrWVlnAr/EDrBcls9tLtQkfAKuDfN64Pk3+zg9fEnVxhnTEeu/ 9X9l3q/QwMjArh8UvpMvf1h+pXOJFAGKbeHDkfaj9Vc+m7YvaRteahQrSZcU+Hv7OdDB 2m3RZ9R78m9Ys7Lv0TkZRmsL0K6kT8ZppK1r1SFbkatx8gK9w5q/jQ15Ns59rapibj6w JmUg== 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 k3si337612ywd.185.2017.10.31.04.38.33 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:38:33 -0700 (PDT) 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]:44925 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UsK-0004tw-Ud for patch@linaro.org; Tue, 31 Oct 2017 07:38:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgC-0003L2-MN for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UgB-0007zt-O0 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:00 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45114) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgB-0007yh-Gn for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:25:59 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 9E20854006A; Tue, 31 Oct 2017 14:25:58 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:25:59 +0300 Message-ID: <20171031112559.10516.57546.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 11/26] 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 Tue Oct 31 11:26:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117585 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3780274qgn; Tue, 31 Oct 2017 04:29:32 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QZZRJRAXF5AruhNGzWoJMJkJwFBynGFk7QEe99NLwJUz2BFZSp6nUaAMMXpC6LfR0qoF/I X-Received: by 10.37.104.133 with SMTP id d127mr915492ybc.472.1509449372936; Tue, 31 Oct 2017 04:29:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449372; cv=none; d=google.com; s=arc-20160816; b=MtAuExGosMZyg0pikEJpqooiRP8st0Q0wx+FFPeqGjiDFKrLUVY6XnrhsVkdF6B8AE Z7Z3rX7JFyEjWQ6uJ5MndYW+xzIR577fQieZ6R8QH0Muxbye9OH7HbPqRsDPhkXydEj6 GmWChvOVr7FkPKnx8dtuxjyZ13JjPeEqvAwoFf9acQ9W3tzb4YEbPpzyEwSKbi2kTbxH /qzUYFaMzBDrOpFfMCLz68dDeT5qfXp1FSSzsTRHCRWRiAzfXavyKvc0/zTui25cBqMQ mFCpFieozbENZDDV/ZVunvbG1Zgkj09VJ0Tlg6F3ajZ5dWej8JGMrNrTvWv8wg66gmuA /X1Q== 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=R2WQnEalgsI8X96AelZsnrDU9uj/n2yJ+Otv0lXWcH8=; b=dIk05R3CRQdb9QjbUHEfrrc/b18eHXCcsPMtwlH5CCqzhXpTv9H0Nle9dDqbE93VYx x7em3GHWVemfBG8mv4Rjv+Xu+PcAWX+V4iKoSdFdw7oedhjLqUxC9ooG2GRvJtByXzC+ PzenJaY+N+HI4AKrwAT3xND0lZchdfLmz5oFkhJUHvxXQlhehgvHasKSAaq5H6e0YcWc rGToOxniXCNqoikedxMQwrBEYawdHKz4QshQwBcmKJREdTpGYvtkkt6iRrD/NplZNzXa lGbRUfO2QOO+7svp2kXPGWRd4+jHpEnM63r8aNY3D4JuwxEn0cSgrLlEJaDPQ8wj8uPf 7P4g== 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 b36si335564ybj.441.2017.10.31.04.29.32 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:29:32 -0700 (PDT) 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]:44883 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ujc-0005rH-Az for patch@linaro.org; Tue, 31 Oct 2017 07:29:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50638) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgK-0003SO-KT for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UgH-00089P-Ec for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:08 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45146) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgH-00088B-2v for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:05 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3ACD654006A; Tue, 31 Oct 2017 14:26:04 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:05 +0300 Message-ID: <20171031112605.10516.73988.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 12/26] 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 | 3 +-- 3 files changed, 21 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 2eec54f..efde5c1 100644 --- a/cpus.c +++ b/cpus.c @@ -1127,6 +1127,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); @@ -1135,15 +1137,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_kvm_cpu_thread_fn(void *arg) @@ -1169,6 +1177,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 { @@ -1211,10 +1221,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); @@ -1225,6 +1235,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; @@ -1313,11 +1324,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 @@ -1377,6 +1386,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(); @@ -1386,6 +1396,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(); @@ -1394,6 +1407,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + qemu_mutex_unlock_iothread(); + if (!cpu) { cpu = first_cpu; } @@ -1419,9 +1434,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) { @@ -1462,6 +1475,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) { @@ -1512,6 +1526,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 */ @@ -1536,9 +1551,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..99af6bb 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -513,11 +513,10 @@ 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); + current_cpu = cpu; 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 Tue Oct 31 11:26:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117597 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3850255edm; Tue, 31 Oct 2017 04:47:07 -0700 (PDT) X-Google-Smtp-Source: ABhQp+R7xqYVE7QVbDrEfikRhzjn0CiQFyfh4ML97EcR4OngUzYvn+EVYcnbbBRH/i73OBrypxGc X-Received: by 10.129.148.68 with SMTP id l65mr934409ywg.457.1509450427575; Tue, 31 Oct 2017 04:47:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450427; cv=none; d=google.com; s=arc-20160816; b=JU75jOEVbXb40kAbKShJbi/OUGGtHWTKPriKWZbOJJnLmQLj8SiHF7YKmVzaFSJ1if t5lUQegSBBS3W5/LjYac5MrwM2Fyb5jv30bTdZjBdP7wXMZsYBOUZhUctz0pdWxtdbMY zrZ9r00IB60W6K555NefSfquT9y4QYjl8oKG+he5pEL1P1rDLdumrqRPWUJOFW5Tukke 7pQftjZZAMQTDf1qKzsV4wYuNV73mRofUXI16GU/4sc3Ue7GZmvtqtzAn/A/B5Yz+K/J PL3ZQhlldTi76n+iIn2Dqufu/KxaTMvqoxKiuqyERjxJej4Q+PWJhSOv8UQM6UepVk6F /U6g== 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=y5Y8wRaGEaQFk+6f2M/5y78fSKFSpjuvUCaIuyse3e4=; b=as5XAIHEABXr0mAFt/4PemtPFMjx/7AxLx49NDEE/vTqyYiLHBLS7sA4py1xdQq9Up uZuiyscP8oC/FhXdYSnPd3wz/md0BgDxj+/1Vpj9VFDx84LGIKJmVdFR0g+JvFv2DkaQ +TgEyKxPYFEx0wDQbZ0onDfMueDZ5QKberxTnO4K7yA6YZm0BeUo68sPIkSVyys1OztH xYzMPEAgRtCb7s9JY974+G24LS5fkCH9WG0raRcF+dPiDUXk/3YRBVRqhv1DgUHnj/J0 t0R4OwvbjVlkMF3OUpDZxmq0qEO4QeztTPNmoi0YVCQHPwYirv3ryikgbfn3/k0JCk3P Q00w== 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 127si329393ybr.14.2017.10.31.04.47.07 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:47:07 -0700 (PDT) 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]:44976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9V0d-0004Gd-1i for patch@linaro.org; Tue, 31 Oct 2017 07:47:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgO-0003VI-4E for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UgM-0008Iz-W4 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:12 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45180) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgM-0008Hf-KD for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:10 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C09D954006A; Tue, 31 Oct 2017 14:26:09 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:10 +0300 Message-ID: <20171031112610.10516.78685.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 13/26] 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 efde5c1..de6dfce 100644 --- a/cpus.c +++ b/cpus.c @@ -1127,31 +1127,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_kvm_cpu_thread_fn(void *arg) From patchwork Tue Oct 31 11:26:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117587 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3781353qgn; Tue, 31 Oct 2017 04:30:30 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RnoJYcaOUEsYn3A7cr+Ye5yeFDIGghnc6tCuXTh1xom79gvbkrIhRWcA2MwU8pGnJSZ0j+ X-Received: by 10.37.11.10 with SMTP id 10mr1038373ybl.138.1509449430855; Tue, 31 Oct 2017 04:30:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449430; cv=none; d=google.com; s=arc-20160816; b=gzUN9cdEy6zs0khNvoQX4+hRvbbu4QDNmH0JOsJNWP8AsEUbsbSOTfEdfohtCDi9by 9gMS4iLooVflQn1584ZmEwzAqaW3c8irFPQ9aK+NaJAB5bg5SUraxmkJrY4JfxFuxxzM fDlJKtJ7DNFy8Sd23mItrW7aWRZhY2Ovu+TB02jlgihg8Mev4++wdMiP0qLzB/KfjQUy MYcJG5jD/dI5i4OX33Ue6MAuv4/TVskuxO7lf5theDwDoXGIVTJLivqPEr7oV32tjLPV ORso+PfTISaHLa0eEW05p4XGgtuAND1kl/rNcu+vaCAeuMyGOwc+bsUO7oqA5hrendf3 3JEw== 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=wB0Ogw6PcNL9/dEgXbcFgFmGjbFBmF92fbxgyIPdfqw=; b=a2ka2KUE5AGEVLIaMN7BhoHRQ49xvhnkoZ7YdgdBYyRCf9qSnrdnBCIueuFap1Mrnn hdwukR4UzvU/d+plspMgvItzd/loTQ0EkB/Vg+xKO3/nHgkjFTBH7Ut13qWIgAM8w5EJ oqrNaaTmLV+dC9HUcPc3qb0WS3xwaNJU3zeV5xUbTLSBWrcVjcyuGOyQsrhMoTGdOxPF S66oi8YG+8Gfh+Ei0OAlM9NxskG4bCVYcL2kG1668YxtmU2WpViAFfOhVAiXXBWyFuAX nlrKIw62i2ypGkavmdMMV5k+hVvtNkEAynEK7AIZbbHW3GbuOvfp7IIvkmSQq4XgyNuC PNjA== 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 d1si343545ywh.385.2017.10.31.04.30.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:30:30 -0700 (PDT) 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]:44889 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UkY-0006zx-8c for patch@linaro.org; Tue, 31 Oct 2017 07:30:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50734) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgV-0003d4-Ht for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UgS-0008RZ-EC for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:19 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45206) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgS-0008Qg-6Y for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:16 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 52DF954006A; Tue, 31 Oct 2017 14:26:15 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:16 +0300 Message-ID: <20171031112616.10516.6980.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 14/26] 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 --- 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 Tue Oct 31 11:26:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117590 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3784644qgn; Tue, 31 Oct 2017 04:33:23 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QIvboxUXvxHRIwF+QeFBh0ONEWIdFovdXVGg5EPskmJRPHFta92mh57XwFa9q3SzHAgjt2 X-Received: by 10.13.195.3 with SMTP id f3mr945319ywd.52.1509449603524; Tue, 31 Oct 2017 04:33:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449603; cv=none; d=google.com; s=arc-20160816; b=F2nr+WM6gHcQYkNiGoB5jJnWt5CWeh9LtFrMz6RdWuDfX6oBDGIwacoxvTXMo4YBfA XOEXuta4819yZi4wX2dkvfrzX/e97fom/xLbcyBnqGar09RMCvIrhSSUUcHWCQBIYRkN Q7JzOHRRfz+bc8AJBagfedz5bf2dz4rqKhHVHZDyirk6ScYupq7jnDbY+Tflp2cg0LX9 UgeHmA6XyuJfglcex0QBIAHVPjiokDQS+YYsq0gZXYJ21tbJbevV1dE2kKkl4BTlomhl AtWqFCB01A4JKVx+2tCL8uH2asd3EG7iGNXRneHML9U4qEqmzRhJ/1cNbqsHOy3cpd2O Yiig== 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=eaWXh7eJ96bPE1dM/ljeqUReo1DLKNLjyU5VNVCDfdE=; b=r6xfSiAS1rd1nA3+1VYr0aUNxZbWdMsbq/GtZbiJJak9Vdgtw/s7/ZkIlRdBf4qfP/ LuYRXdQaKS2+ADb2aQXE3tZzTD4JgK7TrI/yXus/RKK0POKieG9dVmCJzU1GAqfhPdjX vS54hjJhdfMEF8n+KvENuJqXmbPIY0We9NzWhkvgKgSiTKfKbjYAWFfeL5Tc8gfs5y88 ApIO5Itq7jNmddTEj4jZZ78pW588WEx8kEs8ksMmT+1L85r+ROKHYx1MGsULUShE1lFY Ht05sm8PPUcnpAYZooYmR31Z3ieVin9cU6NHIzim3BVtVoDEcrjY8t99URj3b3mvstJs IwQQ== 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 z6si340925ywf.445.2017.10.31.04.33.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:33:23 -0700 (PDT) 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]:44901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UnL-0000w3-15 for patch@linaro.org; Tue, 31 Oct 2017 07:33:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Uga-0003hC-9V for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UgY-00009B-1P for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:24 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45236) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UgX-00007U-Pd for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:21 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id DCF2954006A; Tue, 31 Oct 2017 14:26:20 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:21 +0300 Message-ID: <20171031112621.10516.38393.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 15/26] 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 Tue Oct 31 11:26:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117588 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3782537qgn; Tue, 31 Oct 2017 04:31:27 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QXXuy1mzx1mrNfPmHHF5mH6hD5geI1T0ApYrKKLpop0OFz3TV5UsU2qOU3zPUyB+2Kilyc X-Received: by 10.37.98.135 with SMTP id w129mr877224ybb.177.1509449487907; Tue, 31 Oct 2017 04:31:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449487; cv=none; d=google.com; s=arc-20160816; b=mPX0lUfHqVUp0C2ifnCijIZ1ycQG9cyB59e8spVO1oZljlamOpVaYIgFDG2DdN4wWe Z1Fu36tdJdpMZaiIyM3k+HGP4m9M8qp1Q6rD6VCZ5AvRm3VBLTcg501w8pGi6IK8eFMA W2knU2rI8+EtkD2JJjyuii/M5Z5RMPrdXJSqyJvVVBafx5Lmyzulg8UC8onKgSrs/RqM QzzkEhkMTXS20Ro7vzMycw/CgeNPV+/qBBMZEBUtrC4X4Z4XGAkKA+QRKexmrzvzr9cB AQ8NrYzcKJpiQ8jXGColqhLPkoxxjS4msNoI59g6O8eKxl88Zkaw9rjNoGvDxPvRxZsG Na4g== 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=dpH72NVjSEz8gPuLBqVVUM62om0pxxM3CuVXIosSo0M=; b=h4qJwMqzaiwcLA8Pk+QFLzchGdbNNcBQzVgu9JhyHW2M7Sx6megeRiygZoF1krR7fz ERGuRdauSTwJzq2TvK6W23BGoF78L5sev3z0BuNmRhw5A4r9pJkVSiuU95wlsQjB7EjP tbcdu16GIFEX3fBBxPU77151006PaYbeBBOB+596oaL8HAv16I4oVJO73F2dI575k59S dGgHZEYi6OHf4/KGg98aKlGOBIsKVmi7d3mJyOG+Y8HyanNSyhTHlL4WECUYbJQ0vMU+ FGsL8Dg9d+65IHAOirQZ6Kmxcw/cU42LSZ9ZnHJmn4Htn0PEvGoZD+Am4o61P1CPii3H x6BA== 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 c7si328176ybk.63.2017.10.31.04.31.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:31:27 -0700 (PDT) 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]:44895 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UlT-0007qd-7k for patch@linaro.org; Tue, 31 Oct 2017 07:31:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50842) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ugh-0003mr-0I for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9Ugd-0000Hj-RC for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:31 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45270) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ugd-0000HK-FR for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:27 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 7D28254006A; Tue, 31 Oct 2017 14:26:26 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:27 +0300 Message-ID: <20171031112627.10516.92024.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 16/26] 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 | 5 ++--- replay/replay-internal.h | 5 ++--- stubs/replay.c | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 6 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..e6b2fdb 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -181,7 +181,7 @@ void replay_mutex_destroy(void) 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 Tue Oct 31 11:26:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117592 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3790885qgn; Tue, 31 Oct 2017 04:39:38 -0700 (PDT) X-Google-Smtp-Source: ABhQp+SNSuilefPNBpqUqI46UjgJFWf8l3L0FH2Gx0xwKzXSY3CWm1GOxA3OmEevIhhfJRCXwLfP X-Received: by 10.13.248.130 with SMTP id i124mr960009ywf.206.1509449978199; Tue, 31 Oct 2017 04:39:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449978; cv=none; d=google.com; s=arc-20160816; b=xLKGHOWDyvPZK1wGfvAYMMGnyZj8oKB0lUnuuiww2Lv4mkC1QLhHssy/R0LeYpp7Kj ebwZlBV9gaLNAsarRcgV4Ar/IrIlczeMIZTcVTCu8l73eCazbktrvh8C+8nGmYxG+vCd UDWBgmW9ufGNtdXiJdxHBu/Cfm7cWQ8ziFO5vmFSihImZMBrgQnLlTGQ3RCCQONkhbWv YtnzeiadS672lVDj7sXfPMrgVp6BvsrPlHoo9hqUL2yVQoP8McNkBRtueOvvLEh8bghh 25ixcscMqhudtFsVCspeoUCHuD9R/Tr5eIeWsrXh7Vp2iY5FDnr58IUCTJw3RGg/MgSH IDGQ== 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=gRTubsCdpFjQPIYtK07e6zw10tWLFD2LiCCoM+QSvJ0=; b=TC7NTlupQBOIXPm1Hy7BG3UNoi/nEsl9MR6EN7F4Kz/dkFLZxskmyWZEsVV1tm8jFO KVSMc2GGEPghBo1wsTVcL1M23r2FKxSt5h+e/RkSGosshM+Sp+6l3ynHHSQ50xLg/1NM Jjo2blIaKIG2CeDIvbNwqpQJ8SnUEYNv/6XNohe3zaoI5FRWNdKzPfC2C0dnKud9sJ+6 fZQLNVcVcqk6w5O8axJXRBcq/pPAigCL0NiocJa8BFdM9QUMbIH1+4nWyKxoaWHocfzn c0dTuBo8/eV6cjBH9iddyp4PDncK5/CVOFrf85Id4yp97fGGb9HyTUErTVvxQLuNNcEi ObYQ== 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 x206si344866ybg.686.2017.10.31.04.39.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:39:38 -0700 (PDT) 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]:44930 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UtN-00068U-FA for patch@linaro.org; Tue, 31 Oct 2017 07:39:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50897) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ugl-0003rI-Lj for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9Ugj-0000N5-JN for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:35 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45292) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ugj-0000MM-23 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:26:33 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 34F1A54006B; Tue, 31 Oct 2017 14:26:32 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:26:33 +0300 Message-ID: <20171031112633.10516.44062.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 17/26] 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 --- cpus.c | 32 ++++++++++++++++++++++++++++++++ docs/replay.txt | 19 +++++++++++++++++++ include/sysemu/replay.h | 2 ++ replay/replay-char.c | 21 ++++++++------------- replay/replay-events.c | 18 +++++------------- replay/replay-internal.c | 18 +++++++++++++----- replay/replay-time.c | 10 +++++----- replay/replay.c | 40 ++++++++++++++++++++-------------------- util/main-loop.c | 23 ++++++++++++++++++++--- vl.c | 2 ++ 10 files changed, 126 insertions(+), 59 deletions(-) diff --git a/cpus.c b/cpus.c index de6dfce..110ce0a 100644 --- a/cpus.c +++ b/cpus.c @@ -1293,6 +1293,10 @@ 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; + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); + } } } @@ -1308,6 +1312,10 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } } } @@ -1395,6 +1403,10 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) while (1) { + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); + } + qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ @@ -1407,6 +1419,10 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_unlock_iothread(); + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } + if (!cpu) { cpu = first_cpu; } @@ -1677,12 +1693,28 @@ void pause_all_vcpus(void) cpu_stop_current(); } + /* We need to drop the replay_lock so any vCPU threads woken up + * can finish their replay tasks + */ + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(replay_mutex_locked()); + qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); + qemu_mutex_lock_iothread(); + } + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { qemu_cpu_kick(cpu); } } + + if (replay_mode != REPLAY_MODE_NONE) { + 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..994153e 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -49,6 +49,25 @@ 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 deadlocks are easy to introduce a new rule is introduced that the +replay_mutex_lock is taken before any BQL locks. Conversely you cannot +release the replay_lock while the BQL is still held. + + 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 e6b2fdb..d036a02 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -174,11 +174,6 @@ void replay_mutex_init(void) qemu_mutex_init(&lock); } -void replay_mutex_destroy(void) -{ - qemu_mutex_destroy(&lock); -} - static __thread bool replay_locked; bool replay_mutex_locked(void) @@ -186,15 +181,28 @@ bool replay_mutex_locked(void) return replay_locked; } +void replay_mutex_destroy(void) +{ + 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(!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(!qemu_mutex_iothread_locked()); g_assert(replay_mutex_locked()); replay_locked = false; qemu_mutex_unlock(&lock); 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..7fc50ea 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -80,8 +80,9 @@ int replay_get_instructions(void) void replay_account_executed_instructions(void) { + g_assert(replay_mutex_locked()); + if (replay_mode == REPLAY_MODE_PLAY) { - replay_mutex_lock(); if (replay_state.instructions_count > 0) { int count = (int)(replay_get_current_step() - replay_state.current_step); @@ -100,24 +101,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 +128,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 +139,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 +159,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 +169,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 +184,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 +199,21 @@ 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(); + replay_mutex_lock(); /* Hold while we start-up */ +} + static void replay_enable(const char *fname, int mode) { const char *fmode = NULL; @@ -233,8 +233,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 +272,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..7c5b163 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,19 +246,26 @@ 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(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); - if (timeout) { - qemu_mutex_lock_iothread(); + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); } + qemu_mutex_lock_iothread(); + glib_pollfds_poll(); g_main_context_release(context); @@ -463,8 +471,17 @@ static int os_host_main_loop_wait(int64_t timeout) poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout); qemu_mutex_unlock_iothread(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } + g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); + if (replay_mode != REPLAY_MODE_NONE) { + 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 a8e0d03..77fc1ef 100644 --- a/vl.c +++ b/vl.c @@ -3137,6 +3137,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 Tue Oct 31 11:27:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117594 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3791387qgn; Tue, 31 Oct 2017 04:40:09 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RmyWAOMQBvXqaj9GE52wQZrjfRIAOmpXX7f4kliYBdTOMVz9ksfAZJxiuAbxmxiKKoperF X-Received: by 10.37.187.69 with SMTP id b5mr935921ybk.191.1509450009123; Tue, 31 Oct 2017 04:40:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450009; cv=none; d=google.com; s=arc-20160816; b=rhAhvhJr09sHirp5UrkRB3bwUhCdVcoTZ3Ih4h8OLhkdpRFtRtE06s8K7yK9/3RZs/ ai95mzokYqnALGU2ciDfZS0haKGUBgtpSwVG+gzTSMJM9FBF/M7xUIZfSq6NNxKWTbri TSOyDty1JDKs++qBr8lZZ/CjRUuGhH81soWAPmRztdA9mcNM5dxdC9U649EpSG3sDgyU xRfAyjiaSpLbdiRbvXv/x/Q+PbTL47Np90u4ufbSBfBSaWGTKbnS5c2uzHGWYp1X7/x8 whnQ5oUOeKfGSMqTLkJJ6HjguV+PqI8fafTei06wvL4prddeEc6fnZwxalYX0AqYamVJ tCxQ== 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=8/Vw8eOcmoeZm82a8jz9Lqv6EaUsIFnni1lghWpg+Ng=; b=ilTIRs8LBHlOSNzRHriLWZQRr2exhMMoUbJIj+EQrDPGIAih86A8Kv1F/tVHoMb/Jo 0W/kMvg+32eTKN/lFQmF97BgSAB5AvVSQhwUt8o2rU42uDBOvfIax9vLFU2FQGzqJPLF sb4r0zWsa4VwO7w4nDOFW4JJSy3QUimwh2ghfZ0l40siylUUJwnZPXRYrzz7cN8edXf+ l7d5VQyTFaP95wxF/F4IAGGKfbhU7n2cjCF5p6Jxgm1bwKsXVIsUH3fYaqz+M1V3PZJF YFheK+FsDwwYgzG4Zp6Ey0ijFuLx7l/W7XuZYi+28jwKw5BoVbBYVi6iz7xo2ye66vA0 pYgA== 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 h204si345969ywh.800.2017.10.31.04.40.09 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:40:09 -0700 (PDT) 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]:44933 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Uts-0006bv-JY for patch@linaro.org; Tue, 31 Oct 2017 07:40:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51213) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhC-0004GT-CZ for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UhB-0000pN-12 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:02 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45432) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhA-0000oc-Pj for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:00 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id EBE8754006A; Tue, 31 Oct 2017 14:26:59 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:27:00 +0300 Message-ID: <20171031112700.10516.76192.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 22/26] 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 Tue Oct 31 11:27:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117595 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3846042edm; Tue, 31 Oct 2017 04:42:55 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QmeAexmuYKq2MbTQhhcebDNiOZerCF3wrOLoxudibzThLKmqeI3JNfrMLefZlHkP6sfObF X-Received: by 10.37.204.70 with SMTP id l67mr962912ybf.241.1509450175030; Tue, 31 Oct 2017 04:42:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450175; cv=none; d=google.com; s=arc-20160816; b=aM8EOvhtSHxTq9hTRieNVJ4iUhQ3Au/1sqnfFRVRJ/9hzRVvDFVdT3r4iWececXh5y JobeArcKs6kDBnvHzaPgSZH8YspHrX+QLKULOZK4wFbZ4PO4JvGa785a6fW7VHKwA/dd Tw/TryAvUXPPs6C+14rYa3njjAAqw+j40bQRVgcEaR46Xa2XIwvedEHRW5Wg/gZYmCsb PnZqB0obOYLNbH3oJbRngaa7DE7UAqeVsrWIBAqz1OvpD3yOjpmtGUw/4Xa0P9qjStwF 3ioRIfdJPEzYZrFRqFu1zDV7scqnN8NW6dicQvVD21FPpkYPzJzmSUg8Z0OF4bVj3iXd nVmg== 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=DxLEvgVZnhx6Th1Z2OcxhG+6S/6xQvOXu2TUf1VJeLk=; b=KsjS7/SMhvtyEGYqyqEiXJrbXxFmXLsyOPDqW2ImOnq6DMrz5FHPdZ93q4yI9tKZDD ex9yQQfk2AuJhH29IXzFeROUnz2OSAwwu0i5EJaeMW9xDHDua+gBAQ/q4PppePG3stWp TAgSHUbYSXo8F2DlFKO7pilX/TnUxil310Wcw4Pz7L3nRalKpcrbBR0aH0ak5SHyWq9N B0F09fG/F4VETMMPFbA2LcX2IxaDgdRQkHyFqToQiK4+4cJkbcKPjqVsTtpMPIUktmtm mSGFsZGECbYjsAQMI1/ebqUA/3U+BEUmE0Ouf5LJe0NhdDQOueCJbmaMr8/Z2gUgmFYS SR9g== 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 b10si325966ybm.766.2017.10.31.04.42.54 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:42:55 -0700 (PDT) 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]:44948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UwY-0000cW-Cq for patch@linaro.org; Tue, 31 Oct 2017 07:42:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhL-0004P1-7u for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UhG-0000ww-R5 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:11 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45468) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhG-0000wK-Ec for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:06 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 813AE54006B; Tue, 31 Oct 2017 14:27:05 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:27:06 +0300 Message-ID: <20171031112706.10516.50173.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 23/26] 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 | 14 ++++++++++---- util/qemu-thread-posix.c | 21 ++++++++++++--------- util/trace-events | 7 ++++--- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 9910f49..c51a7f1 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -22,9 +22,13 @@ 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 +43,9 @@ 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 7306475..1a838a9 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 Tue Oct 31 11:27:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117593 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3791245qgn; Tue, 31 Oct 2017 04:40:01 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RoR0a1bfG78dYuiLR9Z4OBYYKhF+KczTPSB1hSwOqSvmjs4Aj6LcJe4vwacyLcWdjQEzks X-Received: by 10.13.250.4 with SMTP id k4mr969369ywf.32.1509450001439; Tue, 31 Oct 2017 04:40:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450001; cv=none; d=google.com; s=arc-20160816; b=Lz/N3wkgFl3pJhkdZbpKmNl+Wrh5pzqsI5ijPIbcQol4FVm/V8bCR55dVL7Vy5/dMP GdssBDz7T7tB1gVWzLoUkU+SbbNOaBBhaEqS8rLhAI848AQAWnViJZWxlyPC/gRdthQ8 f5dIQ/opge4KDEHprdp16rCrCf/YdlPiUoEF1DEJWIZDFgKnUDA8dCGuBuMXLRgRuK89 zNFt0vbf4LefM3ClKgBKY2F+uMLpHOupACPThyNJK8UYGia3R0xG1cOaXU1TeVhIjQI3 X8Sq80sA93oCq/sFxhVhrffM31bj2VNaTMHR4FTeJAxw3VeUlw+hJvleeg6O5f6+2d1z LngA== 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=aT+AWYNLUZIktc+qFKMvvIRgCCvYlgEwbMv7GDlIC3k=; b=qyScuKi9KW2Gdejyoh3BlG9qKGaSsXCQiRda5aer/AOBZZQZ37DJzovA3mrb4BuYlF cOYRwavt1oZ2jksS0De2IQBTgDGN/Z0grc0+CxS00quFUiwyfOet5lOAWYoRSX53AFMA Rudy+eFoFNHaFk6fIFr1ExDZO6fLNoDhfs+pdtkKoDutuPbEwiYcYYK7qdu1wlE5JE8R n8uyRDMP89MgbRN7UwkOqDurKAPYObYORKcaXWrT0+S4clQ/cdSxViyAkAK62UkR2ShT ys+NSkxP15JpYa+Tf5eNuHrARtKXFJYEYH2wCpFQBjA0OLclQeMCyPWiA6e0xbFAT/LN gj3w== 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 j141si349178ybg.303.2017.10.31.04.40.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:40:01 -0700 (PDT) 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]:44932 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Utl-0006UV-0T for patch@linaro.org; Tue, 31 Oct 2017 07:40:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51335) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhO-0004TD-FI for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UhM-00016k-Bx for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:14 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45498) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhM-00015h-0e for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:12 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 2874E54006A; Tue, 31 Oct 2017 14:27:11 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:27:12 +0300 Message-ID: <20171031112712.10516.27701.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 24/26] 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 Tue Oct 31 11:27:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117598 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3853147edm; Tue, 31 Oct 2017 04:50:20 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Q85W/XUorV7hETXuCYSEywGh01lYE+ycK72CeeBGE3d4xP1kbNSz7kUPS+hXtAJL1wvAmR X-Received: by 10.37.188.141 with SMTP id e13mr1000225ybk.30.1509450620476; Tue, 31 Oct 2017 04:50:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450620; cv=none; d=google.com; s=arc-20160816; b=wSpcqHfI+j2XFrWfqaubo0sHZbnPX0544lTGVRXdusWAmn9KFgfQpQ3Wn7I45PQK+Z v0Qkf7mipPr++HjXHAQeLf1omxZadE4KQo5RItcE1xxsqL+myqter4q/fZFFRgJUOig5 xW7Mo0BH4j15WcAFL4kZ25DMCYfMCTldi+2KIcHkD8YbESifatyp5Qy7dtzeWQsKsEqr d7PsRT3mIRmi6IJXdGwBVkf+EbjiH9kwDMYXx2RrGJXKtT9AWBbGUuCuUXTgM3EUY3jz VbQ55NYZViwsIfjheN4KejBlti11iaJ+hlGBWwSWyd9W/Onn92aHnVXsjUEZJ64axyKZ bqcA== 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=t7Q16W46hGY0/4vznypm79ggdT9i2ZsOOIaY54eKsk4=; b=zKplzXss59XHG45+rFztfKKRcV5X/2aUHUUn6vEjtRWjhemzSSCVdNeWI+W6/uKyWD E9108D1VTMocP6DzByWwRRkuvVuJV8pZ78UvFgETrWRGz6ZjtMxTYQdVN2fGB4lyMJVu GmMbqmcZbGr/ioXF2qMovV8qXroAMMH3ZFaID8gxJ4u4WwC3104JAjR86oS+VsmycGY4 G7lU374SQIqA0WCZ2kGMU1yMxxiCMc4KnL9OjPWvjIsVlnEhfGVYUHE7jPRETNE/AH8j 2fZbhjS589bHxqJ4smEesIZk+acOOSSR4G2DbaTuygiHgK4Y8U0GlRdpj4olenXyB2hY yCUA== 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 x1si350759ywf.475.2017.10.31.04.50.20 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:50:20 -0700 (PDT) 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]:44998 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9V3j-00071t-UR for patch@linaro.org; Tue, 31 Oct 2017 07:50:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51409) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhU-0004Z7-5S for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UhS-0001II-0B for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:20 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45520) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhR-0001Hx-Jy for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:17 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id B086454006A; Tue, 31 Oct 2017 14:27:16 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:27:17 +0300 Message-ID: <20171031112717.10516.49147.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 25/26] 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 Tue Oct 31 11:27:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117596 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3850056edm; Tue, 31 Oct 2017 04:46:56 -0700 (PDT) X-Google-Smtp-Source: ABhQp+SqbHWXhAlR2mBTNo3PmBeFUGxHa20iWRTnsC57OqspICY0WkMWxMxOKe5GCZxsInd4uzOx X-Received: by 10.129.115.2 with SMTP id o2mr988721ywc.124.1509450416566; Tue, 31 Oct 2017 04:46:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509450416; cv=none; d=google.com; s=arc-20160816; b=B2YqpXpIPns1opyGwBdOh4VSkmSb/FGXMf/bpQ621hO45AEkaw+4BqnEku7Duiw9kz 1DMqbriWl7zjOAqw4xEVF1P+uKouIIJWxrXRyGR0Sbsoy2rgXNAETg752mAQ4IFC09hH meYjtbUD68miayqsB+PSKcRQTbUi6NE0Ivkg/d1ufbDS8IsLVVgJ5gfXDkF5Q4nteyvR kTbYNWm+ytFfK+HWGRuAMFjlLRox2sm6Ne+nkuq33IKpHrtqIeMWEckTI/9fL0hasR8B TQFD+VcxPqVKYR3MRmk7O/Lq907xPkocF6yGo+ZTGHCsqoI1VR8r5AhcrUEfE634FwSe cB8Q== 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=0mNrYB/7CQ13/nCWNidSOnK31xeLWYbx0BprAi0IOhM=; b=kJ9yUDDgQTGxHeEMmGJvkxuFp2QZrb7UjikkMPzFliOYJk4oCmmO9XBvZxaOjAGxr1 /hRjsJYngmbTkm4bRZQGcYi1ZH6W5s26ek7AIiOoDxs5QnMAPyyBPBYCY1TXInbLcD4W hYjbBp3up1H/qstzJOCjYYm7EfThLNTmB5zZKNkDfofc4WiSfa51SLLD8uskgmMZZteq YlIbCeFidRZyySUdSbOiLJS43l9K1w3zF3kEWINYvAnmjldEJdSoJjhcXpRQ/71MTqZl 35SlfVb7+2ieDei/cDHX83xA5yyqsGYQc6a6PvGOrrZS0ly3IC+jQjEOruKV33Ebz4gr B3aA== 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 x9si383268ywi.87.2017.10.31.04.46.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:46:56 -0700 (PDT) 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]:44977 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9V0S-0004Gw-1w for patch@linaro.org; Tue, 31 Oct 2017 07:46:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51467) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhY-0004cw-F4 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UhX-0001NB-Gd for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:24 -0400 Received: from mail.ispras.ru ([83.149.199.45]:45564) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhX-0001MT-5y for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:27:23 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4FA3154006A; Tue, 31 Oct 2017 14:27:22 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:27:23 +0300 Message-ID: <20171031112723.10516.89734.stgit@pasha-VirtualBox> In-Reply-To: <20171031112457.10516.8971.stgit@pasha-VirtualBox> References: <20171031112457.10516.8971.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 26/26] 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")