From patchwork Fri Jan 19 08:43:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125122 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp197646ljf; Fri, 19 Jan 2018 01:00:57 -0800 (PST) X-Google-Smtp-Source: ACJfBotXx+f58yRSreL17jqI/+YLENDpF9zPKTmdXses5QYAoAAjJrGEAypoVVZW2+5uSl+mMdtc X-Received: by 10.129.46.151 with SMTP id u145mr9216703ywu.164.1516352457881; Fri, 19 Jan 2018 01:00:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352457; cv=none; d=google.com; s=arc-20160816; b=wLDK0QN3P1mmikuy+s6WxaanD1/VWCwErjAq3p0e2iarE5S+EWNclSnzzS02m7mjbQ nrf8ius4441ntcHOOos++Z/ClAuIe2eI9F/F1/i3uCkoVsb6bgZ73W2BjARBf9RG6gaU GpSdR2XRSUvLHEk9ezsM6JJE8r50m/X37fp30cEvtbrtEULzzvL0Cgv0A/q778ArmiFp fy5bU5VijxtvC2jXTDiGZyCvRfjb7OfrfyJ7W/1I9NIROCuoLUWjLJqrb8HzHoI5mWwx WtXVSxLR7njExT4/ZN3KRs3GFEIgwRmqTtYvddsENXYxwUReT5fH+btxV9q8a7uCNX9A tuDA== 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=YWI4nsYRSSRinbGm5WikFDAgnOIofA9cSJPSnDpQGONd+MzLFrasADv7o/zYzZzBP1 ROdOtGkOdvrWf7OURJcAlI1uVm0Zyg9uQNdBn4o2uvtkhM5I1A14Zxhge4t/R0oyucPZ zMPPTFV8vjmzs1RvCDMq74vDrJQBj9mdEGohBqIYVrTqoR6swOQ5GGH8wxZu5ns0e9Sd M3Uvu0vtwJBgo9wsgsGPWfLiu4vAHgH+JPkjEtVlzDWpUvs2yLBASAU5FW8WNKZbXrhM A1iNvKCX5HBclJX1LaDi2oG52BCAGBl+QHKi/ChSMHNC0l6QzlH7ADCeZSvM69Ip5TSQ qE4g== 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 o196si924949ywd.411.2018.01.19.01.00.57 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 01:00:57 -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]:35686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSXh-0006DP-BB for patch@linaro.org; Fri, 19 Jan 2018 04:00:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54144) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHN-0001GM-4m for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHI-0005Ms-8r for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:05 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHI-0005Mg-1f for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:00 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 9FC3B54006A; Fri, 19 Jan 2018 11:43:58 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:43:59 +0300 Message-ID: <20180119084359.7100.2236.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 11/23] 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 Fri Jan 19 08:44:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125118 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp194001ljf; Fri, 19 Jan 2018 00:49:12 -0800 (PST) X-Google-Smtp-Source: ACJfBovPOBWnW+YCXFXM0RIBXmd1yupWLbUUQFYnE/Yebu3iGENZa8byO/VrQSjB2HoyZs5zb1up X-Received: by 10.13.197.193 with SMTP id h184mr8863690ywd.514.1516351751906; Fri, 19 Jan 2018 00:49:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516351751; cv=none; d=google.com; s=arc-20160816; b=NkoG03PQgn9s4O14GymszIYgBG/3zX71cRCJVVEIc7Ij6t3ufU6pJZPevwVNxRwIYw +SyrTXJ1HVmqTTy7C0+Ikrm1X1WUHcK5aGP/pHZdx7jri3slHZnTrjIV/m0iLH1RFGM3 EvZb+5feluhVA8IuSBqx0FRn054nGFO7TDKXuUyMSjAsEog52+mkfh6Plm9gjSiR3B6M JVx3f4qj0TVdeHA1B05aVTF9D3zAN8IlKp0mJXr1EVtRmpMgE/oe31z5Vw6IRbNSyQhG OwHmPiEByKwkwItbZOJsKq6KHpw2Vu9iWMObmAcL5R5PvS1SgLdW55u8pvbGNoRhVfkL HSlw== 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=nQX5XzsuFJgjFYfEiqavm3hARnT5AFVKPdF4TWYujVA=; b=vnUVZYekLu4IrcoCkex2Abesz6IC0rbhpjRPCV0iyrSD0haNcWjEeVN4f+M7aM/LW4 epwGVZMkqQujPE02UwMOL0z8YeM66che/udvaLMOWyl4ObRTEAunRffFEToqGjnLa9jM ASiv9rLTsTxAG5ehLMCJ3QOEyKpXBpq7HYzlf7tvFoB8ZrkeELgkyZMwR1/qCD/8VwWP CJOzWXlb+VKkA/mvJF7nAmP2grGO76PKEB00TE4v0o+YSANBx5bMmBLm/ZhitYlseSvo VQCJTsO+HFkof6dIW9ByNgtPIuAAgDGwA4hm/DM9EG1lkvvMyMupyJERP0h5kJ/I11qF PzZA== 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 w12si2107814ywg.372.2018.01.19.00.49.11 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 00:49:11 -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]:35355 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSMJ-0004AZ-71 for patch@linaro.org; Fri, 19 Jan 2018 03:49:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54180) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHQ-0001Jc-Ff for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHP-0005Pn-BW for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:08 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53694) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHO-0005PM-UG for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:07 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 001A154006A; Fri, 19 Jan 2018 11:44:04 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:09 +0300 Message-ID: <20180119084409.7100.23132.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 12/23] 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 | 22 +++++++++++++++------- dtc | 2 +- target/i386/hax-all.c | 2 -- 4 files changed, 16 insertions(+), 14 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 7b6ce74..ca86d9f 100644 --- a/cpus.c +++ b/cpus.c @@ -1150,10 +1150,14 @@ 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); } @@ -1190,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 { @@ -1232,10 +1238,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); @@ -1246,6 +1252,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) } qemu_mutex_lock_iothread(); qemu_wait_io_event(cpu); + qemu_mutex_unlock_iothread(); } return NULL; @@ -1334,11 +1341,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 @@ -1398,6 +1403,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(); @@ -1407,6 +1413,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(); @@ -1415,6 +1423,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + qemu_mutex_unlock_iothread(); + if (!cpu) { cpu = first_cpu; } @@ -1440,9 +1450,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) { @@ -1483,6 +1491,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) { @@ -1569,6 +1578,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 */ @@ -1593,9 +1603,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/dtc b/dtc index e543880..558cd81 160000 --- a/dtc +++ b/dtc @@ -1 +1 @@ -Subproject commit e54388015af1fb4bf04d0bca99caba1074d9cc42 +Subproject commit 558cd81bdd432769b59bff01240c44f82cfb1a9d diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index 934ec4a..54b1fc7 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -513,11 +513,9 @@ static int hax_vcpu_hax_exec(CPUArchState *env) hax_vcpu_interrupt(env); - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); hax_ret = hax_vcpu_run(vcpu); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); /* Simply continue the vcpu_run if system call interrupted */ if (hax_ret == -EINTR || hax_ret == -EAGAIN) { From patchwork Fri Jan 19 08:44: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: 125123 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp197794ljf; Fri, 19 Jan 2018 01:01:18 -0800 (PST) X-Google-Smtp-Source: ACJfBovxPOYSWEK2daTHzzoG0EJjJtuW5yJyu88u/XKWIOdOd45U/q3FO1pH3mHXE/xw+3RCVN9V X-Received: by 10.129.193.14 with SMTP id f14mr8982248ywi.508.1516352478830; Fri, 19 Jan 2018 01:01:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352478; cv=none; d=google.com; s=arc-20160816; b=oCt/wKcAS/lEjXFkayzfdfj/U1lXWU0Q6jw4VOlKn5j1D3uwq/QebUtoTT51X4nvYt CREqmbUpglYE9ymU68INyw1owSToFsmmfAy7H66Zp7/FK7cmwkbu5NQp4SB3jv58Phzw gOrJFzwy1i+7oZi8Auqg4KykuLBJ7NzsHbcU7/QYmLn6z45I+bn/DcXTUDFr30ZVS4Xg VKf7Mu5KO4tab6jW+JE0PGMmmyGG6iUH4jVMS28I+t8ftLsynMyf/DQ8/5Pk3sk1O6ji m/DVhAFYDo8dmKlrClxP7mPd42u9ZnUeMIqSX9d5QOny/Jk60sICGfyxRunpsTUiE4+g hjvg== 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=i1bq7mgwL6GD+8h38TC3Ho/RpK01gnYMaNzsRL3wKCc=; b=EjXc2fYrtWFNAI0NNOqmwyXZ+SNENGtIC/ZuVGTa5x+9GALkL2xMjFa8KKQ8Vj1tJg XxoXaR8AT1wPIBdjXX1AeLHbrvX7GbFQI+gChiryleFrAbEivepA97mqSeAg8sjzu+uO a2jDSoG/n59dz9/XCNDwcWhAfsnGJo5nulvp38eR38W5sIoBYMErCuHE7YdMnMJjq9iS LLJbNKZmgalQDvlIt85Z95CyN6yar9WatjWCWZ3pygKW5EnLXBaRfNbhdNhmmuQ/OAFu ofIvKJC/wL9ciFKXJwXdxhtwYvV2Ar0arhDV63dy3rsdOmNxjoLyM4hUnK3uaa3IF8Rm MEqQ== 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 k11si2245039ywl.783.2018.01.19.01.01.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 01:01:18 -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]:35895 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSY2-0007M6-7G for patch@linaro.org; Fri, 19 Jan 2018 04:01:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54202) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHb-0001Ra-7C for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHW-0005VC-A9 for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:19 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53714) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHW-0005Us-2A for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:14 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C081454006A; Fri, 19 Jan 2018 11:44:12 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:17 +0300 Message-ID: <20180119084417.7100.69568.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 13/23] 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 | 7 ++++--- 2 files changed, 9 insertions(+), 11 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 ca86d9f..c841333 100644 --- a/cpus.c +++ b/cpus.c @@ -1143,23 +1143,24 @@ static void qemu_wait_io_event_common(CPUState *cpu) static void qemu_tcg_rr_wait_io_event(CPUState *cpu) { while (all_cpu_threads_idle()) { + 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_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(); } #ifdef _WIN32 From patchwork Fri Jan 19 08:44:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125119 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp194853ljf; Fri, 19 Jan 2018 00:52:20 -0800 (PST) X-Google-Smtp-Source: ACJfBot76X+wcmsnSUuZfb+7I6axBdadaI197EED4N2q9Kzdn3W48m2oVaSJbakQYP2g8krQT48p X-Received: by 10.129.45.68 with SMTP id t65mr9009399ywt.216.1516351940624; Fri, 19 Jan 2018 00:52:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516351940; cv=none; d=google.com; s=arc-20160816; b=g71VTKo/ItFP/ZOcjgJROBKJihviPNoiHABuwrXClvegHIJ+jIG198UxQBKx2quYVI gHgD5PckwyMPZC5A63NmY7/vomxhXCvHy3hbYCcjm9Rru0+qG4B8ae27rZ+dpJKuGwKs e6F+Fk6khcyUYlxN/nHqgrHnOArKwe7DoJtSTmLokihfZDk30RZVwelAenOzB7NzbOAt YopCTFWRLxoC1vO48VVDeOXuBTfMSxM4aXKjQlrQkOZAQdvp8h0FpaiV30DKim7xLs1P K9FKX5Qb9UqfKX1Whp3gu7bv8J6xO85rEwlnObE23O7+/76JqoHhODXObeKIMlWoXxki I3Jw== 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=DRjs2MF+6ejzd8U+qqkVKFxs0r7izqpWkxsIbeADbitb5+J+ZWWZGNu6wVQ8CDGhPV FfEfWevEJccY0JtkQg6zoAbVkUnk0DikaJ/l6/lKyw/Kicm6xywdpLPQWOIg6SKgMpu+ qfRAw/WLd0wZOFxfb2VFBcH2rhUfs5OyMN1yHvjSAkRtLWNFGBDNp7OpMKUHHz2b7Vo7 IiqbIJ5ixT8flIYe7wfBhqw2kayK/KUV666LBaFMSzp6zMT/IYp5OdcSeXb8v5xnhyD6 Ir6xyJQOVY66b/Hn38CxSA9DYBGpFIP23aj5nG9F219hDUvo2BIgWcBw76boneR8m9Xl JcvA== 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 l21si2209145ywk.771.2018.01.19.00.52.20 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 00:52:20 -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]:35396 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSPL-0006po-Vq for patch@linaro.org; Fri, 19 Jan 2018 03:52:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54216) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHd-0001TP-D0 for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHc-0005as-Jl for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:21 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53734) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHc-0005ab-BV for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:20 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id F2EF354006A; Fri, 19 Jan 2018 11:44:18 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:23 +0300 Message-ID: <20180119084423.7100.17994.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 14/23] 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 Fri Jan 19 08:44:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125124 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp199537ljf; Fri, 19 Jan 2018 01:05:42 -0800 (PST) X-Google-Smtp-Source: ACJfBotiszLQl8hT+nuGy0iD+CDrEs3TrfXI5ZW5opuNx64fDqXsO+lt0W0UXTjHOmjpEGHQLCx3 X-Received: by 10.129.91.84 with SMTP id p81mr8564224ywb.278.1516352742221; Fri, 19 Jan 2018 01:05:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352742; cv=none; d=google.com; s=arc-20160816; b=YKUcdS1DD2tMpEiTPwKP1USjImWMi5qKDl1/ENq5QjZytniWe03/JNPmhaarmYWhma 0bqh5ZF0RGmmkTfhwRDmKgkNjuPqQwdCvIHCP8qt3FFgpTBx0q44J0QetCMKbin/+ja7 c7qiJfPVmDSSpqkzpzXBDt8Rux46qqo1MJ42s6TVngX4EQXr+I8R+UF5vAV391/Y4/66 jfeNuJCHED/quKTwhvchF6Z/LhPsYjNjZQAOU11QldI+bzIyBYlq8CVYeeG3WCt4d7se ZmSi1HnPiJ9rFRdu6YuNzdXGakLOzK3yfMaBhtKWX4+V35/zEGsrIQO/sd7sxx5CvZH9 zp+A== 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=Jgd6CitYF78f9/UC1SYrD3L8QE+BrEhug2J8OKUl2H815yEtLr5XZ37zFgg2oNCyLW RE/XQQf2YW7osQegKjjAuolweTaV13dcqytvPxJgmaDaSUWKL4fMUQT7CMftFrCJrWac zOsCR0J6VvZCOuTp0OozvVQRbuL/Uy04eeR3gza4T5AMsWsIizcHcJHDM7BmyG7Dti8E TbRYzehIkaccXaZr2sZdjwJHta6CqdCMBNCI8z9fWf1NJnytmFNuUAovAtPJuPB1zjJH LInip6gl7FGjdAij3fdpIU2H7VVJP9c6DdDxZD+zAiTbCEXGZBvAKE6E5nG80lb32m3B udvw== 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 v68si530570ybc.230.2018.01.19.01.05.42 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 01:05:42 -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]:36118 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecScH-0001lX-LT for patch@linaro.org; Fri, 19 Jan 2018 04:05:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54252) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHo-0001bH-Ag for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHj-0005cr-FB for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:32 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53754) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHj-0005ce-7F for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:27 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id D41EC54006A; Fri, 19 Jan 2018 11:44:25 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:30 +0300 Message-ID: <20180119084430.7100.10004.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 15/23] 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 Fri Jan 19 08:44:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125120 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp195238ljf; Fri, 19 Jan 2018 00:53:30 -0800 (PST) X-Google-Smtp-Source: ACJfBotL3WdY0U7Eibzf/8A/Y1OdUFFF4xgcta2ecSTcl4lLqo7h8kK74pIEzCOkcto0iuvsZcUw X-Received: by 10.129.172.19 with SMTP id k19mr8821845ywh.274.1516352010739; Fri, 19 Jan 2018 00:53:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352010; cv=none; d=google.com; s=arc-20160816; b=kXRc54f1LfhHHXMZdVK63FYyhQioClzdLFLaZPSNvv6moO05Oxxf6gOBfc5TQJN2Lb SYGnd+899bfyRrOUp8v7R1UPFxHHCHJRI667SY9S/aSMbJAhiqENO6/duH+SUw6LAUcQ LCalBhqkoH2mC9SXqVyBfm1Z2D/nZrUJ6e9k6o+BRu+Uit8pn0OPqvtzuSN76TLfDlnO is53gnNNPCbUx1AY+mGKGnw1XXg7M//UBZAFq+VGXcvXaEIe/zv7UWKoW2bkIkZqXrPK OsXlT+acXPhur6AOsqGg+6oh8yWfoYMr82GT3ByVc6ijGExgd8rfUgRBS/8HXY/W+ZjK nAvw== 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=qV1CEND4VSYI+Kf+wX7hdAKQT6mlxbktdjUfly3SnpAOU2YjCJQMgnpTkra0wpXBLE 3EB0zwf6fV6oasPx0+tXEIgxp94Z6OisykHQF4IpvTWu2WK2bZcMfnqOFLF6cKGTRvzv 37pwEuGO1ogCfmGLCQfra5uqzrVsRYV+CIEP4dbQMKy2CkcDWLifbj8KAJODi8zP1BW/ l9FfALXuysfceYp98RJcpw45FyoB9Kithe/QE18MpS62fmnKJQh5feARZsJlZi8QvfnN skocw8P4bIfheElvxsqDdH959dnRvo/onQvBBpPUs5MlP/9OhDVbVkfDzDJBvSYQtb6e fP9Q== 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 c141si2205984ywh.152.2018.01.19.00.53.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 00:53: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]:35397 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSQU-0007rn-3c for patch@linaro.org; Fri, 19 Jan 2018 03:53:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHr-0001dA-Nc for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHq-0005jE-Ql for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:35 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53798) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHq-0005j5-DU for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:34 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 7437F54006A; Fri, 19 Jan 2018 11:44:32 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:37 +0300 Message-ID: <20180119084437.7100.91521.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 16/23] 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 Fri Jan 19 08:44:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125125 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp200198ljf; Fri, 19 Jan 2018 01:07:44 -0800 (PST) X-Google-Smtp-Source: ACJfBottQWBV2VNk+QbF/X4D4qPda/Bi4Q53vCPaE+QrQbMb0XvqP7ONqkuF71EJ65AxcoVNYQxp X-Received: by 10.129.209.11 with SMTP id w11mr8659253ywi.475.1516352864441; Fri, 19 Jan 2018 01:07:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352864; cv=none; d=google.com; s=arc-20160816; b=Hxvcwh5ofwwZwmATc5FgD5EnRLCLem/1mCrWn2AhbWbP89PUFfWWT3cL9M8yQndjQd ZCp1zPNzkGGJuQMQjRbjDyLD1fYdUMH9mNgUC7D7r1yCoe+WIXnpdwK8D2yzNkw9djQ8 5EoeVtEv2jKFSMGJde6JLTB3RgyBy/RkQzCeIlx1KpvMXNp0KcXVcVQIiOtaz2LKmAgJ jcJJXgTT3tF7qRq6eSVyk7S82hrSekJSFGYMCcm6x1Y2IUFJfQ097A7x6S+K8CrskQcy kC4I98+4kz/7WC7OG7EttQFpaxZfbkUe7fTn3mOoTYCzrcEB8UHb8FOROgUsHUfXltBX Db1A== 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=xGOfCR32txfkju7LJGicJEv5N4J4dtZFIVM4MY8z14Y=; b=zJ4N40tKjglW0iar6mp7ex4Ev+dmYp1oDPHH7E/7ywgJXlbtkZCkLGWbFez3612c/x ra4hUevZDEpgTIYfBPr0uUZbvwEYYM5XdCDTcoMvxhxFHVtItZjydVI7WuXBnubIbns3 5BWielX1Z/9FxakZ6CVRnm9SgmFpgmUyGtUXV5FbsauQ530v4Gq5YxL/pz4n9DH/T/7j Hs1ssruA0wqMK1Jw0oWuAGBCHyJDUXopv+qf1n00htGYj0l35q0xkqjdBNenpARFYxpX jrWJvTam+7A+lhCa9INsE0YMQgnri7BxeZPQeYYGSuO+0soY0dyhXzN05p8+LEVLU9Uo 4Ysg== 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 f66si533674ybc.178.2018.01.19.01.07.44 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 01:07:44 -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]:36227 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSeF-0003AH-O0 for patch@linaro.org; Fri, 19 Jan 2018 04:07:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54422) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSI3-0001oJ-1T for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSHy-0005qF-IV for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:47 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53820) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSHy-0005pc-1j for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:44:42 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id A416054006A; Fri, 19 Jan 2018 11:44:39 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:44:44 +0300 Message-ID: <20180119084444.7100.30839.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 17/23] 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 c841333..f7cc45f 100644 --- a/cpus.c +++ b/cpus.c @@ -1313,6 +1313,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(); } } @@ -1328,6 +1330,8 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + replay_mutex_unlock(); } } @@ -1414,6 +1418,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. */ @@ -1426,6 +1431,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); + if (!cpu) { cpu = first_cpu; } @@ -1732,12 +1739,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 fdc7798..1a92051 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 Fri Jan 19 08:45:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 125121 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp196162ljf; Fri, 19 Jan 2018 00:56:27 -0800 (PST) X-Google-Smtp-Source: ACJfBotAKq8D9H97FUk3nJjIlvl+pLzpHdb1eI8jCu4pJ9UO1E71KGV8olAgh1QShn8+KQdS51a1 X-Received: by 10.37.66.17 with SMTP id p17mr43161063yba.76.1516352187466; Fri, 19 Jan 2018 00:56:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516352187; cv=none; d=google.com; s=arc-20160816; b=Ve03/3yhVcBZicvwfQlM0Pg6z5ZAWsMUXxUo+BfimyrMRXOp/3R/b7dbRIBGdhJnYN 0lOmTbygEpbgyT8sC4dOgu0Se/rrPTjicFlWcXn0Gv+NAY1/GmjrhTMRlQNTVtIpVMZv rtG6P/BBn3LX5uADPfFWopYX+oQIoHRaoYYLCZmqT+rsAxtc35GjJScsd+2sSXe10K/f gjEzx0OLKEjgs3HtkgW/f2z0yu7+b2G0qpKBFChU3ydLBPq7or76LLXxPuPyCOolCAMc tQ/mSwpBrY7B7W8uJ7ePplpIKboJKTuzEE06iHKjUXzJQnsvlZSJ+76LIwoXEIAHgD3I YRyA== 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=m/Ym9dXFuH1QElxAVx7FHU5UQGoULjm6D4skBkI+w+voGzmD6kxtRsMiylCXLukYVk tVsKBOusPKxEProN/nlUGO9c3yVmVMMFno1TtH9BLy6sMVqCoJ0FeroBlh2W14sTJdcM ezVslA0oWnN5BEUWAaHc7HjwRFLmGhTZ2YzU0H4XaNG9wYlfx41gv9p2FbMOqLOQkEG5 eKJaHv9iXo2YOtJrV5X/wsqInaZ/0biH0FpO1X/oJt/tGr8yrkvyJm1NvrwXNLeY/CbP X0BsNeK7qip/drLALuvEIDN+FTvIhuFIw/m/i7zTOzp7ZrWKSx+NVFKg4bEsRhzByYlg MssA== 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 81si1265979ywe.730.2018.01.19.00.56.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 19 Jan 2018 00:56:27 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:35432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSTK-0002CH-Rh for patch@linaro.org; Fri, 19 Jan 2018 03:56:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54744) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSIV-0002DA-TK for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:45:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ecSIQ-0006DQ-Lv for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:45:15 -0500 Received: from mail.ispras.ru ([83.149.199.45]:53908) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ecSIQ-0006DG-8R for qemu-devel@nongnu.org; Fri, 19 Jan 2018 03:45:10 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id CF18554006A; Fri, 19 Jan 2018 11:45:08 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Fri, 19 Jan 2018 11:45:13 +0300 Message-ID: <20180119084513.7100.70875.stgit@pasha-VirtualBox> In-Reply-To: <20180119084235.7100.98318.stgit@pasha-VirtualBox> References: <20180119084235.7100.98318.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 v4 21/23] 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)