From patchwork Tue Jan 23 08:54:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125479 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1630936ljf; Tue, 23 Jan 2018 00:59:39 -0800 (PST) X-Google-Smtp-Source: AH8x224VtL9yd++YXEhG2VTd+5t71TL4TgEGRe+jUpaNi3eKv9XHUb9V6pZd/Dm7eKxLhvK2QmkS X-Received: by 10.13.219.22 with SMTP id d22mr1664392ywe.93.1516697978954; Tue, 23 Jan 2018 00:59:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516697978; cv=none; d=google.com; s=arc-20160816; b=B/pqn6TfBUGhIdOFYRgNIMl3uf8edj3TFU/OvLSiAXlsCwmroJF6fUbzVaESGXtj3D evpju6zCc4fshyfGg+XG8W3ozc+GpPG3OiaCcqlBaMnk2/5FoVWeUeLgTgj7QHgPYJwo Ge/4HFMy07D1iCQihr6mMImPePTEszfigZQvkiD7wpfSAIxlzseI6YXcAFi7KiiTqWVC i+z5kZC1+24B3wc7Jah4vcYOCtJLQh28GX2ZamI3aR38/m1pETnL/Z6AA8bop3BBQgkz 4Ra0Ku+0TEFVPBqzMm8/vr335S1ezrEqhXu37b6rA9EU3AFgtY3VsPODzUvvYWnTRHeG 42iA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=wTFEK1rP/PsAYVE6lDn8t3/G3KRjFANptpcyQJugdR4=; b=D+PBApuq6jztWGNDAiMrKu/n8ZXLwIIX5w6cnoN6EB36CSs6IVegnj/WHmHw0jk5Qt 88HJ2qPibaOT7gWa64ONOh28bId6+gq8nqzH/Yhbg50vjbBFDU5Hn0vQqEU3LX64HFyD lMQ65w9sIED6uCYYFHovKCQe4UrIN5DCuVtlq/biiqm+GkWK5WHFNu21cvQkklqdOGj+ wHKK61xkv4QB/VzJvAvjJMQQmry/Jc4StaopIfXNMKreEfVklug8mVq2RIfV9xLxwqq/ DWuHws+V4JSG4HY+01Epga0RfCwIxzHMhaF68rD/0jdQS42PTsOIBB0ybH5oPQLw+D86 obFQ== 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 v191si1427472ybv.406.2018.01.23.00.59.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 00:59:38 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:45936 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduQc-0006GG-9j for patch@linaro.org; Tue, 23 Jan 2018 03:59:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLS-0001eA-U0 for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduLP-0008Rr-T9 for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:19 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57176) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLP-0008Rc-Lr for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:15 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id A542454006A; Tue, 23 Jan 2018 11:54:14 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:15 +0300 Message-ID: <20180123085415.3419.37058.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 10/24] 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 Jan 23 08:54:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125486 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1633745ljf; Tue, 23 Jan 2018 01:05:23 -0800 (PST) X-Google-Smtp-Source: AH8x225slFdpteRYWu6M1zCN+n1eMseNvaqKRfqHsszAwrpyLyY+cY4v1KGLu/14VB7O63fx+Gh9 X-Received: by 10.129.229.10 with SMTP id s10mr1716470ywl.205.1516698323266; Tue, 23 Jan 2018 01:05:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698323; cv=none; d=google.com; s=arc-20160816; b=jxb60jAO2U6MQPH5rdGcR9k50dGS6c+VNOiFkIgs4/EjtLqPvpsHyhppbMwAUV1HQW CGsocRNeNi1vhdgevYDSgIYpPn3wiHLP4jRHy66JWZl2aLjhLJmHJPWhRtP7srTXIWgF 1NWhnajKz8rexbWQFZR82c30ZnvBqXWIOXx4M9kAG7QGIKT3fhEbCt/MvfW+OF/T7aSX p1X94uMVcZWpxIoGSo8V0WnpN0uRSD1D6cZGd5ccKYx7pp6N+jg1kvu1jTS+HnIifEAT 6UaPTdYN3deo0qxrlaa0n4PFqy1yA2J5wUayg/CoPcMwM6F015U+4HJVtI4cesrS9xXx aYwA== 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=Ngaf2lylkazXDsKEI9oyh9DZneQJRWWnvK0mxFTW69U=; b=t1wzfEljpvYiKQNEi8cUcJJoiqiDtrIhY9u2QOVTRFSYSOlmJ3N3r4uK2YlhypG0e4 DvzZ7V/Oax/xhGC6RUxeCaucwxaOxL0In3v4+fcRxRzfI3WcmINa5CAQbGCkCjBFc6FX Ngl71qYKNTUjfkJYm65/z3o21BUVYeibHRye2N0kt4YrSxDzlC5zriczY0GpbPMD7lnS WXWw+DRs9rCpB5W0HRIHfe5WsK+6X/JiMpb6J9EMvyraFnasQW0N8wixvQQ8/G2S6Msu OYBNf4vl0cUI4YlODFXRG23bL0MziOX+vzyqJOJn8kTYkMzIWB4CddczsL9HCIRPVWbW J8AA== 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 v10si2344181ybk.334.2018.01.23.01.05.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:05:23 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:45984 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduWA-0002so-NI for patch@linaro.org; Tue, 23 Jan 2018 04:05:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40560) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLW-0001iJ-UE for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduLV-0008Ux-Ix for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:23 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57202) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLV-0008Ul-69 for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:21 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3DD8154006A; Tue, 23 Jan 2018 11:54:20 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:21 +0300 Message-ID: <20180123085421.3419.45127.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 11/24] 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 Signed-off-by: Pavel Dovgalyuk --- accel/kvm/kvm-all.c | 1 - cpus.c | 29 +++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 071f4f5..9628512 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1863,7 +1863,6 @@ int kvm_cpu_exec(CPUState *cpu) qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); - do { MemTxAttrs attrs; diff --git a/cpus.c b/cpus.c index 2cb0af9..577c764 100644 --- a/cpus.c +++ b/cpus.c @@ -1141,6 +1141,7 @@ static void qemu_wait_io_event_common(CPUState *cpu) static void qemu_tcg_rr_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); while (all_cpu_threads_idle()) { stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); @@ -1149,10 +1150,13 @@ static void qemu_tcg_rr_wait_io_event(CPUState *cpu) start_tcg_kick_timer(); qemu_wait_io_event_common(cpu); + qemu_mutex_unlock_iothread(); } static void qemu_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); + while (cpu_thread_is_idle(cpu)) { qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } @@ -1164,6 +1168,7 @@ static void qemu_wait_io_event(CPUState *cpu) } #endif qemu_wait_io_event_common(cpu); + qemu_mutex_unlock_iothread(); } static void *qemu_kvm_cpu_thread_fn(void *arg) @@ -1189,6 +1194,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 { @@ -1204,7 +1211,6 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) qemu_kvm_destroy_vcpu(cpu); cpu->created = false; qemu_cond_signal(&qemu_cpu_cond); - qemu_mutex_unlock_iothread(); return NULL; } @@ -1231,10 +1237,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); @@ -1243,7 +1249,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) perror("sigwait"); exit(1); } - qemu_mutex_lock_iothread(); qemu_wait_io_event(cpu); } @@ -1333,11 +1338,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 @@ -1397,6 +1400,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(); @@ -1406,6 +1410,8 @@ 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(); @@ -1414,6 +1420,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + qemu_mutex_unlock_iothread(); + if (!cpu) { cpu = first_cpu; } @@ -1439,9 +1447,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) { @@ -1482,6 +1488,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) { @@ -1518,8 +1525,9 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) hvf_init_vcpu(cpu); - /* signal CPU creation */ cpu->created = true; + qemu_mutex_unlock_iothread(); + /* signal CPU creation */ qemu_cond_signal(&qemu_cpu_cond); do { @@ -1535,7 +1543,6 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) hvf_vcpu_destroy(cpu); cpu->created = false; qemu_cond_signal(&qemu_cpu_cond); - qemu_mutex_unlock_iothread(); return NULL; } @@ -1568,6 +1575,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 */ @@ -1592,9 +1600,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; @@ -1603,7 +1609,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) qemu_tcg_destroy_vcpu(cpu); cpu->created = false; qemu_cond_signal(&qemu_cpu_cond); - qemu_mutex_unlock_iothread(); return NULL; } From patchwork Tue Jan 23 08:54:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125489 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1634915ljf; Tue, 23 Jan 2018 01:07:56 -0800 (PST) X-Google-Smtp-Source: AH8x2263SHC5n42ed/aDeJFB9WSVS7JQ7vjXr4DHnS0dWiZyM+BRKNzPIAyBh2JwjHcMiA5BrfrG X-Received: by 10.129.51.68 with SMTP id z65mr1674994ywz.327.1516698476246; Tue, 23 Jan 2018 01:07:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698476; cv=none; d=google.com; s=arc-20160816; b=dySDzNBZxPBN3rrfacWIRboFCnhEhSMqwHMPAkD/M78KeKHzifx1gI7mrcrC5E3zIZ Atw1U6tiltohUirNzo4KS8zSkdSANvYsyQnpzt7hJ2ivenvF11p0NMfqJW5MD+1vr/qi HULci2Irv8ePhJTGgjcEcxM3hC6MNPJfPWlQ966eivtU1t4fhXPuHd7npB0HPi3yNl2t 3liIz4HDs5z9SSx1ALGkoYrfq7C846UJKfZI+OEKVKDiiHeFeUaJRQItVHwqLyqm9SzG 7pA0n+F0JaiJ8djU5hZWD+7PUx9a/no0nAz1ECzh0jlPVVBVMS5pC9yc8320UMpSYqOc eEQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=6kS1RHPs34/96la2ZIym1jAXpkol9kfn4sBc0vgnhnY=; b=cXPqly9Bgwhm2QrIviw48fEy+o7Bd6fV2MumoGn272OO7Xr0Np4rKIlBtBlGef+jvE E4sXtg39Srx9Tn8CmdNt674NTMgrk4InR84ZBMX6swuIvifUzt81IQ3hcrsQDv0NPvUY PkbFsvT3L/h1RoY0vxBednFLGiuRn1v6x3bUptTBQibFQtGmnsb+X3VQlUdQucGN0ISs Wyc6UBdwPsey+pdMqdoh4QckLQ1Kz2onfXdnPyMK2CT57hbcOlDdmn44Um21A33Nd7mv +p1bp4GUfeKXadKWg4z5duuyddZLFrZ3BGFrKHMIrsbyVfYijxdcDou8lPXnObMVniTe 40YA== 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 g189si1894735ybg.140.2018.01.23.01.07.55 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:07:56 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:46140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduYd-0004zd-1n for patch@linaro.org; Tue, 23 Jan 2018 04:07:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40718) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLp-00020d-PU for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduLm-0000DE-12 for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:41 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57274) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLl-0000Ca-PE for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:37 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id D2F6754006A; Tue, 23 Jan 2018 11:54:36 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:38 +0300 Message-ID: <20180123085438.3419.21839.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 14/24] replay/replay.c: bump REPLAY_VERSION again X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This time commit 802f045a5f61b781df55e4492d896b4d20503ba7 broke the replay file format. Also add a comment about this to replay-internal.h. Signed-off-by: Alex Bennée Reviewed-off-by: Pavel Dovgalyuk Acked-by: Paolo Bonzini --- replay/replay-internal.h | 2 +- replay/replay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/replay/replay-internal.h b/replay/replay-internal.h index be96d7e..8e4c701 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -12,7 +12,7 @@ * */ - +/* Any changes to order/number of events will need to bump REPLAY_VERSION */ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, diff --git a/replay/replay.c b/replay/replay.c index ff58a5a..4f24498 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02006 +#define REPLAY_VERSION 0xe02007 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) From patchwork Tue Jan 23 08:54:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125490 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1635784ljf; Tue, 23 Jan 2018 01:09:58 -0800 (PST) X-Google-Smtp-Source: AH8x227nbcEJ62vQpyOC4Ab7PF9bHhNwa2hJTCx9ZgSFp5KLySOHN80fvOaBpHkuApP3CRbgWOjV X-Received: by 10.13.221.211 with SMTP id g202mr1744382ywe.134.1516698598083; Tue, 23 Jan 2018 01:09:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698598; cv=none; d=google.com; s=arc-20160816; b=d47ew3HvhIkoJcQ3sw/SeHxZYZOixTVgJGhuVm8UNHhl+HQ2UANwoTFoBoto8Ydom3 oTKsNK0Yy3JgNkC4TyI/eb3BXg5CEbks67VHtqA4FlnfYLP+BhpPa/+Ihq1v37hsHn6I OwbIoVMTtVCcKhicaqfPLOlpoenDBUFAdyc/4hd5FdfpNDMa533mQG75E0I+n8s1AVS3 mxLuNPe7MO0vVrkb62DwMBbkrmZLktMMcColnSz1vOThCRxBvEmbR0m/vhg0MvpN8SVx EWdTS+3Mp3kujCVoUakk0NA1OzxNJyUMdFsoIcb4Y+iIjve7vKNxKNeQ1dQIXeJxoGp4 QnTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=ojZ3xwW7SZ3qXlFlE9UIGPYeYK0OwSzlNRlNQlIVsDw=; b=SOl9zGsy/OuTiBLsBUV+aJNaoPaCcRRqW6gJsXvJu4jifQdwer+c90Kv3KBBUtdY7q auP5OzUcowHfBWYWDVws021pSD23LZkhZ3zF+7BpWWkUa6JNJfCR8WZ8CMqAXREfDiu0 l0SxoktltYd7a/4311wAT7mYjVuDTnSNImf3ccZIa/4hzU4L/bE3jn9iC+NWrQAYi8DX xbuF1GVMggoPtfhaVbhn2mRzo7TScC0frneekjgfV5w8egJrNY1KPjbsSdMTTPtaj0cD hr1iA8RcMK+bQBaLXRGV5oc26rYJqJEu/jgoOjhPg/PFIAoQmjFJ6et7x3TzfV4zPypM j+tg== 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 b69si3935253ywe.676.2018.01.23.01.09.57 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:09:58 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:46170 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduab-0006eD-GZ for patch@linaro.org; Tue, 23 Jan 2018 04:09:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLs-00023L-CB for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduLr-0000Gj-Le for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:44 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57310) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLr-0000GQ-Bi for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:43 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 5B15054006A; Tue, 23 Jan 2018 11:54:42 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:43 +0300 Message-ID: <20180123085443.3419.1663.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 15/24] 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 Jan 23 08:54:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125487 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1633796ljf; Tue, 23 Jan 2018 01:05:30 -0800 (PST) X-Google-Smtp-Source: AH8x2251TyhmogtUjv02bBHajrtmGwA/Di82Ec2r79HjFnR+GKnCTR5xd9VdxXb9axpODtmpaYCl X-Received: by 10.37.13.129 with SMTP id 123mr1712799ybn.156.1516698330441; Tue, 23 Jan 2018 01:05:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698330; cv=none; d=google.com; s=arc-20160816; b=wueK7mBv+FtbW0AV/MWzUkNa/7QE87kgtrf1tmaDOZaRr+64Of9HLNQsn0AxAj34LL tD9D46mNWYXMjvlklscsecw7apltAt82JP/2EbZPf7a3ZmNV3w1WVYnHXT7lgvSvAPzN vfEJxrZB91RMJtqGgOINcxc/lGwax4YhKldRhkHGDk2Hdg9UBJt4huGxrH35XT1KquSu iNe3+lfs1xnA6R9shiHtpszFgpXsulcR5HzTsqY7Rs5O4W62t2kDk8QkVWMFnKcROlg3 3uNKVQ+m6TosYV2ubbl3ipUEKrdsQaeON4pbaNTA6t0Gwop1yvKiKlrV1SxuKKwuO14h YEHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=KzpNJiMEg8uyfEWj1jsl3leIXmlNYLnok6xi9ReuC1E=; b=I/uz1yBv4GZgDUwC14GO+oaOTXNDONTWS0IZCpXSSFHmL8e9CMSnIheUoVABpELI3/ SqovBM4slT3doxhLvZEj/haoSY6dD1pk/Zn9PbguA/bWZVDAXODjLIHGAVXIEVkmhyXK BPgU/nSDi+EOqV4+RdqF3Jc6NtWqXU1OEgfvbGqai3tf4dn+i6/UsAqACdLqupLCXoQ9 fXEw20vrPBIFI3VyuDzW0WuOV6Qi8PjPghBvEn0L88Ul1V0icolgmMPeQheJJcVfJKFz KleKHVnhqb8je2NjzaY1xYnkq8eQThRjrXW1mAzxR/mc7JBFx/Wy+R8O/+3o3jJ+e7r6 Oitw== 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 u29si2351273ybd.664.2018.01.23.01.05.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:05:30 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:45996 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduWH-0002zZ-Ou for patch@linaro.org; Tue, 23 Jan 2018 04:05:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduM1-0002AM-CH for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduLx-0000Jt-AJ for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:53 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57324) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduLw-0000JX-Ts for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:49 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 00B2B54006A; Tue, 23 Jan 2018 11:54:47 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:49 +0300 Message-ID: <20180123085449.3419.11778.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 16/24] replay: make locking visible outside replay code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The replay_mutex_lock/unlock/locked functions are now going to be used for ensuring lock-step behaviour between the two threads. Make them public API functions and also provide stubs for non-QEMU builds on common paths. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 14 ++++++++++++++ replay/replay-internal.c | 9 ++++----- replay/replay-internal.h | 5 ++--- stubs/replay.c | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b86d6bb..9973849 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -47,6 +47,20 @@ extern ReplayMode replay_mode; /* Name of the initial VM snapshot */ extern char *replay_snapshot; +/* Replay locking + * + * The locks are needed to protect the shared structures and log file + * when doing record/replay. They also are the main sync-point between + * the main-loop thread and the vCPU thread. This was a role + * previously filled by the BQL which has been busy trying to reduce + * its impact across the code. This ensures blocks of events stay + * sequential and reproducible. + */ + +void replay_mutex_lock(void); +void replay_mutex_unlock(void); +bool replay_mutex_locked(void); + /* Replay process control functions */ /*! Enables recording or saving event log with specified parameters */ diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 157c863..a9a6a64 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -169,6 +169,8 @@ void replay_finish_event(void) replay_fetch_data_kind(); } +static __thread bool replay_locked; + void replay_mutex_init(void) { qemu_mutex_init(&lock); @@ -179,9 +181,7 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } -static __thread bool replay_locked; - -static bool replay_mutex_locked(void) +bool replay_mutex_locked(void) { return replay_locked; } @@ -204,7 +204,7 @@ void replay_mutex_unlock(void) void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); int diff = (int)(replay_get_current_step() - replay_state.current_step); /* Time can only go forward */ @@ -215,6 +215,5 @@ void replay_save_instructions(void) replay_put_dword(diff); replay_state.current_step += diff; } - replay_mutex_unlock(); } } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 8e4c701..f5f8e96 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -100,12 +100,11 @@ int64_t replay_get_qword(void); void replay_get_array(uint8_t *buf, size_t *size); void replay_get_array_alloc(uint8_t **buf, size_t *size); -/* Mutex functions for protecting replay log file */ +/* Mutex functions for protecting replay log file and ensuring + * synchronisation between vCPU and main-loop threads. */ void replay_mutex_init(void); void replay_mutex_destroy(void); -void replay_mutex_lock(void); -void replay_mutex_unlock(void); /*! Checks error status of the file. */ void replay_check_error(void); diff --git a/stubs/replay.c b/stubs/replay.c index 9991ee5..cb050ef 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -73,3 +73,18 @@ uint64_t blkreplay_next_id(void) { return 0; } + +void replay_mutex_lock(void) +{ + abort(); +} + +void replay_mutex_unlock(void) +{ + abort(); +} + +bool replay_mutex_locked(void) +{ + return false; +} From patchwork Tue Jan 23 08:54:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125482 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1632534ljf; Tue, 23 Jan 2018 01:02:48 -0800 (PST) X-Google-Smtp-Source: AH8x227eODsyjFhr/w8dIKOTxU3/vRsygn0UAHC8Cx3B0xzMPHXqqexp62NaBSNaj7Vhkgr6sQce X-Received: by 10.37.106.65 with SMTP id f62mr1650303ybc.460.1516698168628; Tue, 23 Jan 2018 01:02:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698168; cv=none; d=google.com; s=arc-20160816; b=qpG1T7QBQrcML9/9vliniBCN91nMjJ1lBF5sGRzODPTgBmxnxDn6uDgfXalsd5tvpe lExUO+jMg9FElDzas6OYVGkjC9LrdJa/u2kTTjXIHmyoXxwseCwZVFZtSBGO9TpcRgxr V1GVYPDvZReQSLf7GwuILb+p0DvpDnURlE+Ea3WE842+eTT2pg6Zmh+Q1YjnjI776B11 BfANk3/L38tQVSmTGMtJTZFfxdgacwUkPZ8heEqQHqbvdCstpK2qAuqIl/MdzdFn1oOt B3eS8OhEdze0sychg+GphbNrxUb5OVx6H0VaPr1cnW4wlrSXfmSc188nDZZyMGcHSnPw kFFA== 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=G5XmA5OZXHsA0+tihtYk3aaESR9mz836Ho0ASTq6Eoc=; b=snbBseHRvAavzDtaGtytC6lkVHNMlNtdDfQXB8C930QM6r7EL9MB3J+V0obG4sY0FZ Rtygoh8cOp55OyMZ3p6gBPMp9AdUPjxtA/3YewUNZgFFsWIuBxomkpDlfmyX6khP1pZ3 OIhPJHB/hX9cjiDaEttNAYxUSEc+BXMfhbmfhM53sjWNGab3p2jlifDk21lwKgpfZtkc n4WjuFlJ0KhQrmpP+cquXKTVqAqKOw0lLBtTRak5l+/lqKkCtdv20D0UEdLhOyDaGU15 VgjLOyEWqVBZTD+7/7pGHqq8gWrlrRGpaLSdUInlaP+LLnNldS2R95aDhNxWyEjeKS3l wejA== 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 t9si982715ybk.393.2018.01.23.01.02.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:02:48 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:45972 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduTf-0000aY-UC for patch@linaro.org; Tue, 23 Jan 2018 04:02:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40867) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduM5-0002FF-8v for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduM3-0000OS-1v for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:57 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57350) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduM2-0000No-HH for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:54:54 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 88D4854006A; Tue, 23 Jan 2018 11:54:53 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:54:54 +0300 Message-ID: <20180123085454.3419.80253.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 17/24] replay: push replay_mutex_lock up the call tree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Now instead of using the replay_lock to guard the output of the log we now use it to protect the whole execution section. This replaces what the BQL used to do when it was held during TCG execution. We also introduce some rules for locking order - mainly that you cannot take the replay_mutex while holding the BQL. This leads to some slight sophistry during start-up and extending the replay_mutex_destroy function to unlock the mutex without checking for the BQL condition so it can be cleanly dropped in the non-replay case. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk -- v2: updated replay_mutex_lock/unlock functions as suggested by Paolo Bonzini updated docs --- cpus.c | 16 ++++++++++++++++ docs/replay.txt | 22 ++++++++++++++++++++++ include/sysemu/replay.h | 2 ++ replay/replay-char.c | 21 ++++++++------------- replay/replay-events.c | 18 +++++------------- replay/replay-internal.c | 33 +++++++++++++++++++++++---------- replay/replay-time.c | 10 +++++----- replay/replay.c | 38 ++++++++++++++++++-------------------- util/main-loop.c | 17 +++++++++++++---- vl.c | 2 ++ 10 files changed, 114 insertions(+), 65 deletions(-) diff --git a/cpus.c b/cpus.c index 577c764..a1f8808 100644 --- a/cpus.c +++ b/cpus.c @@ -1309,6 +1309,8 @@ static void prepare_icount_for_run(CPUState *cpu) insns_left = MIN(0xffff, cpu->icount_budget); cpu->icount_decr.u16.low = insns_left; cpu->icount_extra = cpu->icount_budget - insns_left; + + replay_mutex_lock(); } } @@ -1324,6 +1326,8 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + replay_mutex_unlock(); } } @@ -1410,6 +1414,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu->exit_request = 1; while (1) { + replay_mutex_lock(); qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ @@ -1422,6 +1427,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); + if (!cpu) { cpu = first_cpu; } @@ -1727,12 +1734,21 @@ void pause_all_vcpus(void) } } + /* We need to drop the replay_lock so any vCPU threads woken up + * can finish their replay tasks + */ + replay_mutex_unlock(); + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { qemu_cpu_kick(cpu); } } + + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); } void cpu_resume(CPUState *cpu) diff --git a/docs/replay.txt b/docs/replay.txt index c52407f..959633e 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -49,6 +49,28 @@ Modifications of qemu include: * recording/replaying user input (mouse and keyboard) * adding internal checkpoints for cpu and io synchronization +Locking and thread synchronisation +---------------------------------- + +Previously the synchronisation of the main thread and the vCPU thread +was ensured by the holding of the BQL. However the trend has been to +reduce the time the BQL was held across the system including under TCG +system emulation. As it is important that batches of events are kept +in sequence (e.g. expiring timers and checkpoints in the main thread +while instruction checkpoints are written by the vCPU thread) we need +another lock to keep things in lock-step. This role is now handled by +the replay_mutex_lock. It used to be held only for each event being +written but now it is held for a whole execution period. This results +in a deterministic ping-pong between the two main threads. + +As the BQL is now a finer grained lock than the replay_lock it is almost +certainly a bug, and a source of deadlocks, to take the +replay_mutex_lock while the BQL is held. This is enforced by an assert. +While the unlocks are usually in the reverse order, this is not +necessary; you can drop the replay_lock while holding the BQL, without +doing a more complicated unlock_iothread/replay_unlock/lock_iothread +sequence. + Non-deterministic events ------------------------ diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 9973849..d026b28 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -63,6 +63,8 @@ bool replay_mutex_locked(void); /* Replay process control functions */ +/*! Enables and take replay locks (even if we don't use it) */ +void replay_init_locks(void); /*! Enables recording or saving event log with specified parameters */ void replay_configure(struct QemuOpts *opts); /*! Initializes timers used for snapshotting and enables events recording */ diff --git a/replay/replay-char.c b/replay/replay-char.c index cbf7c04..736cc8c 100755 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -96,25 +96,24 @@ void *replay_event_char_read_load(void) void replay_char_write_event_save(int res, int offset) { + g_assert(replay_mutex_locked()); + replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_WRITE); replay_put_dword(res); replay_put_dword(offset); - replay_mutex_unlock(); } void replay_char_write_event_load(int *res, int *offset) { + g_assert(replay_mutex_locked()); + replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_CHAR_WRITE)) { *res = replay_get_dword(); *offset = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing character write event in the replay log"); exit(1); } @@ -122,23 +121,21 @@ void replay_char_write_event_load(int *res, int *offset) int replay_char_read_all_load(uint8_t *buf) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + if (replay_next_event_is(EVENT_CHAR_READ_ALL)) { size_t size; int res; replay_get_array(buf, &size); replay_finish_event(); - replay_mutex_unlock(); res = (int)size; assert(res >= 0); return res; } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) { int res = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); return res; } else { - replay_mutex_unlock(); error_report("Missing character read all event in the replay log"); exit(1); } @@ -146,19 +143,17 @@ int replay_char_read_all_load(uint8_t *buf) void replay_char_read_all_save_error(int res) { + g_assert(replay_mutex_locked()); assert(res < 0); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL_ERROR); replay_put_dword(res); - replay_mutex_unlock(); } void replay_char_read_all_save_buf(uint8_t *buf, int offset) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL); replay_put_array(buf, offset); - replay_mutex_unlock(); } diff --git a/replay/replay-events.c b/replay/replay-events.c index e858254..a941efb 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -79,16 +79,14 @@ bool replay_has_events(void) void replay_flush_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } void replay_disable_events(void) @@ -102,14 +100,14 @@ void replay_disable_events(void) void replay_clear_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } /*! Adds specified async event to the queue */ @@ -136,9 +134,8 @@ void replay_add_event(ReplayAsyncEventKind event_kind, event->opaque2 = opaque2; event->id = id; - replay_mutex_lock(); + g_assert(replay_mutex_locked()); QTAILQ_INSERT_TAIL(&events_list, event, events); - replay_mutex_unlock(); } void replay_bh_schedule_event(QEMUBH *bh) @@ -210,10 +207,7 @@ void replay_save_events(int checkpoint) while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); replay_save_event(event, checkpoint); - - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } @@ -299,9 +293,7 @@ void replay_read_events(int checkpoint) } replay_finish_event(); read_event_kind = -1; - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); g_free(event); } diff --git a/replay/replay-internal.c b/replay/replay-internal.c index a9a6a64..a1a7686 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -174,30 +174,43 @@ static __thread bool replay_locked; void replay_mutex_init(void) { qemu_mutex_init(&lock); + /* Hold the mutex while we start-up */ + qemu_mutex_lock(&lock); + replay_locked = true; } -void replay_mutex_destroy(void) +bool replay_mutex_locked(void) { - qemu_mutex_destroy(&lock); + return replay_locked; } -bool replay_mutex_locked(void) +void replay_mutex_destroy(void) { - return replay_locked; + if (replay_mutex_locked()) { + qemu_mutex_unlock(&lock); + } + qemu_mutex_destroy(&lock); } +/* Ordering constraints, replay_lock must be taken before BQL */ void replay_mutex_lock(void) { - g_assert(!replay_mutex_locked()); - qemu_mutex_lock(&lock); - replay_locked = true; + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(!qemu_mutex_iothread_locked()); + g_assert(!replay_mutex_locked()); + qemu_mutex_lock(&lock); + replay_locked = true; + } } +/* BQL can't be held when releasing the replay_lock */ void replay_mutex_unlock(void) { - g_assert(replay_mutex_locked()); - replay_locked = false; - qemu_mutex_unlock(&lock); + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(replay_mutex_locked()); + replay_locked = false; + qemu_mutex_unlock(&lock); + } } /*! Saves cached instructions. */ diff --git a/replay/replay-time.c b/replay/replay-time.c index f70382a..6a7565e 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -17,13 +17,13 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock) { - replay_save_instructions(); if (replay_file) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + + replay_save_instructions(); replay_put_event(EVENT_CLOCK + kind); replay_put_qword(clock); - replay_mutex_unlock(); } return clock; @@ -46,16 +46,16 @@ void replay_read_next_clock(ReplayClockKind kind) /*! Reads next clock event from the input. */ int64_t replay_read_clock(ReplayClockKind kind) { + g_assert(replay_file && replay_mutex_locked()); + replay_account_executed_instructions(); if (replay_file) { int64_t ret; - replay_mutex_lock(); if (replay_next_event_is(EVENT_CLOCK + kind)) { replay_read_next_clock(kind); } ret = replay_state.cached_clock[kind]; - replay_mutex_unlock(); return ret; } diff --git a/replay/replay.c b/replay/replay.c index 4f24498..a3ab3bb 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -81,7 +81,7 @@ int replay_get_instructions(void) void replay_account_executed_instructions(void) { if (replay_mode == REPLAY_MODE_PLAY) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); if (replay_state.instructions_count > 0) { int count = (int)(replay_get_current_step() - replay_state.current_step); @@ -100,24 +100,22 @@ void replay_account_executed_instructions(void) qemu_notify_event(); } } - replay_mutex_unlock(); } } bool replay_exception(void) { + if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_EXCEPTION); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_exception(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -129,10 +127,9 @@ bool replay_has_exception(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_EXCEPTION); - replay_mutex_unlock(); } return res; @@ -141,17 +138,15 @@ bool replay_has_exception(void) bool replay_interrupt(void) { if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_INTERRUPT); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_interrupt(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -163,10 +158,9 @@ bool replay_has_interrupt(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_INTERRUPT); - replay_mutex_unlock(); } return res; } @@ -174,9 +168,8 @@ bool replay_has_interrupt(void) void replay_shutdown_request(ShutdownCause cause) { if (replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); replay_put_event(EVENT_SHUTDOWN + cause); - replay_mutex_unlock(); } } @@ -190,9 +183,9 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) return true; } - replay_mutex_lock(); if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) { replay_finish_event(); } else if (replay_state.data_kind != EVENT_ASYNC) { @@ -205,15 +198,20 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) checkpoint were processed */ res = replay_state.data_kind != EVENT_ASYNC; } else if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_put_event(EVENT_CHECKPOINT + checkpoint); replay_save_events(checkpoint); res = true; } out: - replay_mutex_unlock(); return res; } +void replay_init_locks(void) +{ + replay_mutex_init(); +} + static void replay_enable(const char *fname, int mode) { const char *fmode = NULL; @@ -233,8 +231,6 @@ static void replay_enable(const char *fname, int mode) atexit(replay_finish); - replay_mutex_init(); - replay_file = fopen(fname, fmode); if (replay_file == NULL) { fprintf(stderr, "Replay: open %s: %s\n", fname, strerror(errno)); @@ -274,6 +270,8 @@ void replay_configure(QemuOpts *opts) Location loc; if (!opts) { + /* we no longer need this lock */ + replay_mutex_destroy(); return; } diff --git a/util/main-loop.c b/util/main-loop.c index 7558eb5..1e928b3 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" #include "sysemu/cpus.h" +#include "sysemu/replay.h" #include "slirp/libslirp.h" #include "qemu/main-loop.h" #include "block/aio.h" @@ -245,18 +246,21 @@ static int os_host_main_loop_wait(int64_t timeout) timeout = SCALE_MS; } + if (timeout) { spin_counter = 0; - qemu_mutex_unlock_iothread(); } else { spin_counter++; } + qemu_mutex_unlock_iothread(); + + replay_mutex_unlock(); ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); - if (timeout) { - qemu_mutex_lock_iothread(); - } + replay_mutex_lock(); + + qemu_mutex_lock_iothread(); glib_pollfds_poll(); @@ -463,8 +467,13 @@ static int os_host_main_loop_wait(int64_t timeout) poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout); qemu_mutex_unlock_iothread(); + + replay_mutex_unlock(); + g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); if (g_poll_ret > 0) { for (i = 0; i < w->num; i++) { diff --git a/vl.c b/vl.c index 1d5ea70..287704c 100644 --- a/vl.c +++ b/vl.c @@ -3091,6 +3091,8 @@ int main(int argc, char **argv, char **envp) qemu_init_cpu_list(); qemu_init_cpu_loop(); + + replay_init_locks(); qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); From patchwork Tue Jan 23 08:55:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125491 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1638135ljf; Tue, 23 Jan 2018 01:15:51 -0800 (PST) X-Google-Smtp-Source: AH8x227QFsAQsj+DlGfLR1fSJtFgeEwgISJFym9Np9dsCcdSruFhSSneCh5ykCmCtaV+2JGjIyFX X-Received: by 10.13.224.65 with SMTP id j62mr1639342ywe.185.1516698951696; Tue, 23 Jan 2018 01:15:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516698951; cv=none; d=google.com; s=arc-20160816; b=wrgCf2DKLRe2UyQXrQwwzaB9NAFjLW5uphM9OM9Vgh+v/ygQPtLxZFgigx+GDZRzxb 37tRmnU//GJYtczVQ/izgJKPbY12fIIDh8GfK4YHL8ApdUzrVTYJ+fU9+ETMO6r0pzBY XYqEy4NzePmszbrA1HgweyCfSpsoomylidCPEJWeVnxhXeSoXaDciw2isA/gvlwrWnbN hoc98tUWSkET7pbLQZ19SWRtSoXTwLA6ILr9l8PMh0EDu4l/s1JBF7YhK7WBeA/cCjN2 ySPc6oTWtzppNlOaT4R2fZ8pHCXMoc2K6qhwxCh2tXg/11UM3QRawYAOz12vnaLhXkS+ i7yA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=v9IcqYv/yTMbdIsaamfWIMaz4pDbaHYdRiABxfCNKtU=; b=PCZHt/mJen3G7PeWoadVAXJDBSihUnz0K8M5ZuR3IFC+Z94XaGeBQkPYuOmC47beEj oGRTAuBWYyTQ6Wbt0LQUtic+NaqV1DrKUd/+x6e0ILZw1WDHy5pZRF08iUj2pk+IyyEL R5k06PvSfX/Vdwt017OlmETAUiBKbIBj2xnhB13w872J/hMWRMorOTZujWpplY3T0Zz3 m3s6nuuauRJVfAyp3QRfc0PC/FO+pGk2vz0PgkueHSs9SlNQhaKXkE5QMpGkug1O67/c aUYO+lODsKdToUBKwosbuda0zdGWahxZ9Gc8hFJ1XH+pC9T2qMlh4VTs5GPVWdxAOIMs 0owA== 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 g70si3955413ywb.156.2018.01.23.01.15.51 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 23 Jan 2018 01:15:51 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:46453 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edugJ-0002VD-4q for patch@linaro.org; Tue, 23 Jan 2018 04:15:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41002) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduMW-0002l4-Lu for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:55:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eduMQ-0000dS-4f for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:55:24 -0500 Received: from mail.ispras.ru ([83.149.199.45]:57436) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eduMO-0000cl-Oq for qemu-devel@nongnu.org; Tue, 23 Jan 2018 03:55:18 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id CEC7D54006A; Tue, 23 Jan 2018 11:55:15 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 23 Jan 2018 11:55:17 +0300 Message-ID: <20180123085517.3419.36217.stgit@pasha-VirtualBox> In-Reply-To: <20180123085319.3419.97865.stgit@pasha-VirtualBox> References: <20180123085319.3419.97865.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 v5 21/24] 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)