From patchwork Tue Oct 31 11:07:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117574 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3816216edm; Tue, 31 Oct 2017 04:13:08 -0700 (PDT) X-Google-Smtp-Source: ABhQp+R7880sQ6/Y3Q6zxN00ybJ9P88nwFeiV1WDmR3KbGujEtpoA1CHENbEnde+rjUqjJ/rlfVe X-Received: by 10.37.14.193 with SMTP id 184mr906778ybo.156.1509448388846; Tue, 31 Oct 2017 04:13:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448388; cv=none; d=google.com; s=arc-20160816; b=Su8shlH1aNcjfrkYJ3iiNwpBWQoYfRO3Zlidp6WihrLPi5f6GuZLomG/9zdqhH9Hwv A61dksih5ZykGBI/0Ru4g9K18wglODeQRgmzY8+6oFs4ZizGKLIhW6UeFbPa06ZgiI4e Rlkh71dwPc8vTto9nfOxmTqD0jUJ+YBEgIBBUfRDYLNjSg3D3pAYKNF+8X1WJOseMs/3 NTvBRdC3uZ27bvlgTTbzfnk9QtJ5VEct/mc9pC102N90mwL2SH1+AWt/2K2yjRP0J7Ac VJG056kG4Pb0NF4BQboB9BYjJdjcKnHqpI89hqfqieVvVFbu2gffI5EiY/Lr6lirTyBu zicQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=rs1qWJWv8UDbdM1egYNaxIk0TpwVSiUjobYQ5TjYI7s=; b=XCmZ0UBYRl6Z7kcbCpyYEouYgNlmzABIxa11m8QfDqUWbRK9Nc6tC5dwWB7EoJGPvF y4RNLNnL02XNem+RwitLy/G6k21BazPkao9jxXwNg6B9TAJpGr29YcWtUNyiGoYCW3sj 5gJG0O464Ibdwsz//7tSswT2abMinNk0XTvki5XqdM28XmzJVB4j/w5ewjLn5lVjTrBc QhRZlSxKZmvucmmwSNQuqqCkoP+S+LwKXES4czvmJXobn/EOqhtpMCb4do4uk4SOI8Ox l6Z8+7qH4+NfSWC5Yj6bLiCFQdQvE8X5N9JjF6mPhndGSRgbiAIeXqFOpzFeGu8In4Nq 2Mrw== 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 o127si338538ywf.618.2017.10.31.04.13.08 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:13:08 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44806 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UTk-0000bD-8k for patch@linaro.org; Tue, 31 Oct 2017 07:13:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39626) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOT-0004WX-Oq for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOS-0006n6-QT for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:41 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOS-0006mn-Hm for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:40 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E2C7654006A; Tue, 31 Oct 2017 14:07:39 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:07:40 +0300 Message-ID: <20171031110740.5836.65111.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 11/26] target/arm/arm-powertctl: drop BQL assertions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The powerctl code is run in the context of the vCPU changing power state. It does not need the BQL to protect its changes. Signed-off-by: Alex Bennée --- target/arm/arm-powerctl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c index 25207cb..9661a59 100644 --- a/target/arm/arm-powerctl.c +++ b/target/arm/arm-powerctl.c @@ -124,7 +124,6 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state, g_free(info); /* Finally set the power status */ - assert(qemu_mutex_iothread_locked()); target_cpu->power_state = PSCI_ON; } @@ -135,8 +134,6 @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id, ARMCPU *target_cpu; struct CpuOnInfo *info; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 " (EL %d, %s) @ 0x%" PRIx64 " with R0 = 0x%" PRIx64 "\n", cpuid, target_el, target_aa64 ? "aarch64" : "aarch32", entry, context_id); @@ -227,7 +224,6 @@ static void arm_set_cpu_off_async_work(CPUState *target_cpu_state, { ARMCPU *target_cpu = ARM_CPU(target_cpu_state); - assert(qemu_mutex_iothread_locked()); target_cpu->power_state = PSCI_OFF; target_cpu_state->halted = 1; target_cpu_state->exception_index = EXCP_HLT; @@ -238,8 +234,6 @@ int arm_set_cpu_off(uint64_t cpuid) CPUState *target_cpu_state; ARMCPU *target_cpu; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 "\n", cpuid); /* change to the cpu we are powering up */ @@ -274,8 +268,6 @@ int arm_reset_cpu(uint64_t cpuid) CPUState *target_cpu_state; ARMCPU *target_cpu; - assert(qemu_mutex_iothread_locked()); - DPRINTF("cpu %" PRId64 "\n", cpuid); /* change to the cpu we are resetting */ From patchwork Tue Oct 31 11:07:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117576 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3819360edm; Tue, 31 Oct 2017 04:15:51 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QN6ZSKcC2TVcmNI2XsIVumD5yAsd5+NwqqgR2F8buW00o9ebypZRfaKVJn1v2dp/qK3CNi X-Received: by 10.37.183.201 with SMTP id u9mr872640ybj.333.1509448551371; Tue, 31 Oct 2017 04:15:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448551; cv=none; d=google.com; s=arc-20160816; b=b+CMZvQABGL4icD9HNMHfgxCgMjV3THwaFQLynWL+YObkMtm3z3jMcUrvapAzF81l0 VE0+xIM32WtHF30wr5Qr33Mf7JXwOg9kKjUoUB6jIkxC6ZDVxoBTWo9adcocNf7HsZfK wjOe5IeGhXibVCA8FWKURl83o7S5hDUSFNqsk68HNSIvHFB2W+x1BUWm2XBllU9YApFc iRyi+cJbi9lXRDGQawJNKc+rDqa3dtflMpsvRFoUYkfuKBqqs0d0rDRhNkEVLBWvubmU pRqfVk2DnXD8lkWxHt5SbW4ANtDxSBZow1T8w6gjCc3SxuMKwOcwVcXEZxh/iaFDW6Kt +PGA== 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=diK02vrX1gEvxS7L4IYMR0ovKU/aBGih6y7HHEZ/asQ=; b=wLy8XunDrXj6JVCS00wGrLJqOGK4kzSAAHHVPT+3IL6/0vX8dFFvDahml+yqEqh0kM ehYKEQXrMEkMLy+T8trEg6WvNd5k6mbwU8Z6yqSBHU9u97rEraDPPEm7WujEalN1HNq2 hcxSS+hORt/nXSvmRFMB5/ssXFCTO9+8hWSNQAKkW5mKOkiVDiw1zW0LUsh51mOzWUe3 fKy6ORG1xur7lyxkqpssJ/v81NTXRz/WUoARgfR+E+fJV8UvwgM1Ndsk2VZSDbzM42+A T/v4KWMjq2FTuk6n6kyDGYQLs3wwex1awomaiSuY70FGiABaPjK0sH/Swh3ptEeFYYGt uzKw== 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 186si348249ybf.34.2017.10.31.04.15.51 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:15:51 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44822 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UWM-00034X-MQ for patch@linaro.org; Tue, 31 Oct 2017 07:15:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOc-0004eX-Pt for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOY-0006rR-9S for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:50 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42296) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOX-0006qn-T5 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:46 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 5052D54006A; Tue, 31 Oct 2017 14:07:45 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:07:46 +0300 Message-ID: <20171031110746.5836.30236.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 12/26] cpus: push BQL lock to qemu_*_wait_io_event X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- accel/kvm/kvm-all.c | 4 ---- cpus.c | 27 ++++++++++++++++++++------- target/i386/hax-all.c | 3 +-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index f290f48..8d1d2c4 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1857,9 +1857,7 @@ int kvm_cpu_exec(CPUState *cpu) return EXCP_HLT; } - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); - do { MemTxAttrs attrs; @@ -1989,8 +1987,6 @@ int kvm_cpu_exec(CPUState *cpu) } while (ret == 0); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); - if (ret < 0) { cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE); vm_stop(RUN_STATE_INTERNAL_ERROR); diff --git a/cpus.c b/cpus.c index 2eec54f..efde5c1 100644 --- a/cpus.c +++ b/cpus.c @@ -1127,6 +1127,8 @@ static bool qemu_tcg_should_sleep(CPUState *cpu) static void qemu_tcg_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); + while (qemu_tcg_should_sleep(cpu)) { stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); @@ -1135,15 +1137,21 @@ static void qemu_tcg_wait_io_event(CPUState *cpu) start_tcg_kick_timer(); qemu_wait_io_event_common(cpu); + + qemu_mutex_unlock_iothread(); } static void qemu_kvm_wait_io_event(CPUState *cpu) { + qemu_mutex_lock_iothread(); + while (cpu_thread_is_idle(cpu)) { qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } qemu_wait_io_event_common(cpu); + + qemu_mutex_unlock_iothread(); } static void *qemu_kvm_cpu_thread_fn(void *arg) @@ -1169,6 +1177,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) /* signal CPU creation */ cpu->created = true; + qemu_mutex_unlock_iothread(); + qemu_cond_signal(&qemu_cpu_cond); do { @@ -1211,10 +1221,10 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) /* signal CPU creation */ cpu->created = true; + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); while (1) { - qemu_mutex_unlock_iothread(); do { int sig; r = sigwait(&waitset, &sig); @@ -1225,6 +1235,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) } qemu_mutex_lock_iothread(); qemu_wait_io_event_common(cpu); + qemu_mutex_unlock_iothread(); } return NULL; @@ -1313,11 +1324,9 @@ static int tcg_cpu_exec(CPUState *cpu) #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); ret = cpu_exec(cpu); cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); #ifdef CONFIG_PROFILER tcg_time += profile_getclock() - ti; #endif @@ -1377,6 +1386,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_wait_io_event_common(cpu); } } + qemu_mutex_unlock_iothread(); start_tcg_kick_timer(); @@ -1386,6 +1396,9 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu->exit_request = 1; while (1) { + + qemu_mutex_lock_iothread(); + /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ qemu_account_warp_timer(); @@ -1394,6 +1407,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) */ handle_icount_deadline(); + qemu_mutex_unlock_iothread(); + if (!cpu) { cpu = first_cpu; } @@ -1419,9 +1434,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) cpu_handle_guest_debug(cpu); break; } else if (r == EXCP_ATOMIC) { - qemu_mutex_unlock_iothread(); cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); break; } } else if (cpu->stop) { @@ -1462,6 +1475,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg) current_cpu = cpu; hax_init_vcpu(cpu); + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); while (1) { @@ -1512,6 +1526,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) cpu->created = true; cpu->can_do_io = 1; current_cpu = cpu; + qemu_mutex_unlock_iothread(); qemu_cond_signal(&qemu_cpu_cond); /* process any pending work */ @@ -1536,9 +1551,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) g_assert(cpu->halted); break; case EXCP_ATOMIC: - qemu_mutex_unlock_iothread(); cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); default: /* Ignore everything else? */ break; diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index 3ce6950..99af6bb 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -513,11 +513,10 @@ static int hax_vcpu_hax_exec(CPUArchState *env) hax_vcpu_interrupt(env); - qemu_mutex_unlock_iothread(); cpu_exec_start(cpu); hax_ret = hax_vcpu_run(vcpu); + current_cpu = cpu; cpu_exec_end(cpu); - qemu_mutex_lock_iothread(); /* Simply continue the vcpu_run if system call interrupted */ if (hax_ret == -EINTR || hax_ret == -EAGAIN) { From patchwork Tue Oct 31 11:07:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117578 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3822404edm; Tue, 31 Oct 2017 04:18:41 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RaVzmZ8cUWnUKRkicFSIgwVzAKkbaaCBq0D8xZKjEKaRrctEHnlczy8NcWSY+RwdH+NlD8 X-Received: by 10.129.4.206 with SMTP id 197mr956857ywe.45.1509448721615; Tue, 31 Oct 2017 04:18:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448721; cv=none; d=google.com; s=arc-20160816; b=pMJjCR4RTrWnNMrahO6pxJ5E8cSZLzoU30GKMxwtyWliv5SmPIEemL24Wg6c8azaUs BolDnVyAbY/dvpBE39k9QdUeLNoJWH73f6Oc8YdlRAMffiwozOMSdH4AChhZKkZwiOgq DZ5djR9/rllWqzV/Uj/eaJt7tOKLLIR81UlthO7yBqcGMWioxRmuM0E6herp5CTgrOig w3JybqjxApezi35DuIzkEO7TKhCreXdXzGITyhTD/4yT65N71DYhk0Ih0VTlQG5/lv6/ VLYcTlMbaxGcEs6Webp7TC3zeWUrSJyrY57CB5pNOYzlXegpQUCSFxO6tMopDLqHeyQX XDwQ== 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=8W/ovF+pNP4R6zkQ0YBiysLimkvlkFH3QXx5jt6gKCA=; b=wsJ7QOSd5K5c/3L8ro7oJGE797KNzwB0HgFxDjhQ7B3+X7OR/vQW9vZCaxhxmXjINK PjS0zj/nW6PaF/QYPWVNQwy/U+0T4L7ytzeNZIUb6PH0ZXtNq5S3wK4AZ5gOb4R3PNDl t1gCjNNmb8IDhD9m5qCldqutC6jozyBAizZqMogEKSe0BE72XjtxkHsnavH1OmmJ615l tYJTa7iKsiL6xWjmebcxVXfiHMvcgIzyE/3OmOeedu3a9424FK0JSiI5f27XsR7KSK+K 1Vnx6O44gZiJuCm2o+Yy2Ce+TOz7uAo4p4jgGf3Wyz57KSRlaaOb8qikR0vbtbkxIDt8 8CXw== 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 z189si339568ybz.146.2017.10.31.04.18.41 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:18:41 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44830 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UZ6-00061c-V0 for patch@linaro.org; Tue, 31 Oct 2017 07:18:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39721) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOe-0004gB-MI for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOd-0006wZ-Hh for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:52 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42306) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOd-0006w6-9T for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:51 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id A55D454006A; Tue, 31 Oct 2017 14:07:50 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:07:51 +0300 Message-ID: <20171031110751.5836.64445.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 13/26] cpus: only take BQL for sleeping threads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- cpus-common.c | 13 +++++-------- cpus.c | 10 ++++------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/cpus-common.c b/cpus-common.c index 59f751e..64661c3 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -310,6 +310,11 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, queue_work_on_cpu(cpu, wi); } +/* Work items run outside of the BQL. This is essential for avoiding a + * deadlock for exclusive work but also applies to non-exclusive work. + * If the work requires cross-vCPU changes then it should use the + * exclusive mechanism. + */ void process_queued_cpu_work(CPUState *cpu) { struct qemu_work_item *wi; @@ -327,17 +332,9 @@ void process_queued_cpu_work(CPUState *cpu) } qemu_mutex_unlock(&cpu->work_mutex); if (wi->exclusive) { - /* Running work items outside the BQL avoids the following deadlock: - * 1) start_exclusive() is called with the BQL taken while another - * CPU is running; 2) cpu_exec in the other CPU tries to takes the - * BQL, so it goes to sleep; start_exclusive() is sleeping too, so - * neither CPU can proceed. - */ - qemu_mutex_unlock_iothread(); start_exclusive(); wi->func(cpu, wi->data); end_exclusive(); - qemu_mutex_lock_iothread(); } else { wi->func(cpu, wi->data); } diff --git a/cpus.c b/cpus.c index efde5c1..de6dfce 100644 --- a/cpus.c +++ b/cpus.c @@ -1127,31 +1127,29 @@ static bool qemu_tcg_should_sleep(CPUState *cpu) static void qemu_tcg_wait_io_event(CPUState *cpu) { - qemu_mutex_lock_iothread(); while (qemu_tcg_should_sleep(cpu)) { + qemu_mutex_lock_iothread(); stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); + qemu_mutex_unlock_iothread(); } start_tcg_kick_timer(); qemu_wait_io_event_common(cpu); - - qemu_mutex_unlock_iothread(); } static void qemu_kvm_wait_io_event(CPUState *cpu) { - qemu_mutex_lock_iothread(); while (cpu_thread_is_idle(cpu)) { + qemu_mutex_lock_iothread(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); + qemu_mutex_unlock_iothread(); } qemu_wait_io_event_common(cpu); - - qemu_mutex_unlock_iothread(); } static void *qemu_kvm_cpu_thread_fn(void *arg) From patchwork Tue Oct 31 11:07:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117572 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3813424edm; Tue, 31 Oct 2017 04:10:32 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Sen2lizgW2BMBXeHDwyfntsl3cdlvL3Ko5lId0M/LGCBjUmyDsS/bs4gD4Ey8zBMOF2YAJ X-Received: by 10.37.43.135 with SMTP id r129mr858341ybr.251.1509448232153; Tue, 31 Oct 2017 04:10:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448232; cv=none; d=google.com; s=arc-20160816; b=psi5VxI7skyXJ+Qep+7GKJBgESpcz6KzJnhU8twOYH+pP3XkPofEzBaXNqxmfrEfqz 0An9ywOWh7lbrA1OgpDlgYdflBTT/piqbyJa4PxCzYpIq/fvM75TqpAb+aimEkc0L0Zp GKgopvQvHAz9wG7G/3fNVnzmzCyYfkLW+jjRbSo7c7i56VSKnD77sJN2LRxMtLJfZ500 w3BSBIM9W7PWNAxqaClBjwjVca+odgdS/0DGjBHMlE+NmK6VY6vPqFju7A2NrKUJl01b 9Hb4z4Gbbtua90lyRHIRFktRpuSA8T/Cwee6UMotYwzSMBwPJpxmIy81I4NNJE48pSd9 e2FQ== 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=tAvhg3p0IyzpFdcSgNC569rDtjTphyVJOTTRCiT5160=; b=kDVVJjyjvAAQH75VoKQMdH3JxNZOf7QRWnQ0leli8lNX/ZXf7K7a2n2hksYAVFi+Xd lh9U05/NU0IFt1OeN0Fa7dcuLYE0rM9GkfhccccezyN0D59PRXnjeLyhi8REg7H9qR5c 0/Knghiw2HUplg/Wdkj3Lfr9nD/+a3RhEIxYSVF6ManXrQ1t9Tkit4WBmsjUXjQb77ub Jn0rRVK6a9dyANx3k35c8udQfdz8dpt3CCRQ5zgwPd7C/3g+Gp8s7Hc6tAMyGKx1PNkC iLq8kmafCecTUXEKv94EvH02LL0vKbmbhaHwtOHp01BTzEJXxon5V/queaiQqupqXdcU XeBA== 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 b35si302725ybi.414.2017.10.31.04.10.31 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:10:32 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44796 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9URD-0006gr-Er for patch@linaro.org; Tue, 31 Oct 2017 07:10:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOo-0004pU-US for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOi-00070q-VL for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:02 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42314) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOi-00070W-NM for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:07:56 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 11C3A54006A; Tue, 31 Oct 2017 14:07:56 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:07:57 +0300 Message-ID: <20171031110756.5836.9617.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 14/26] replay/replay.c: bump REPLAY_VERSION again X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- replay/replay-internal.h | 2 +- replay/replay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/replay/replay-internal.h b/replay/replay-internal.h index be96d7e..8e4c701 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -12,7 +12,7 @@ * */ - +/* Any changes to order/number of events will need to bump REPLAY_VERSION */ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, diff --git a/replay/replay.c b/replay/replay.c index ff58a5a..4f24498 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02006 +#define REPLAY_VERSION 0xe02007 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) From patchwork Tue Oct 31 11:08:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117573 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3815452edm; Tue, 31 Oct 2017 04:12:25 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QGPWjpClOvkGD4VWfHyU+FwwHu9V6YQ9jloLYzZZ+O5+ijYR+bygHBCQR2wQ0upeqFmCxD X-Received: by 10.37.216.208 with SMTP id p199mr850333ybg.429.1509448345833; Tue, 31 Oct 2017 04:12:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448345; cv=none; d=google.com; s=arc-20160816; b=Ok8ngM/Xatw4HXbI3p6klqZT6EP/L9xhVQLE47h8uuOFD4yjny7VMRVIhFWkooh2GN 3O05i1RaofrYYLTdNlKYcwhJ8s7VE9yvykjNzSfYeanEzmbKqEot7iET/CjB61/eJ5iL wz7Mx1kUOuQhjwv/OTnUE4z78NYcRVDPFS6roNnFS4nrNiPpUjaeBi6h/MXaDws2kQae y47p5oObo85FR90qd5sNsNgTXajX9UhmVuOqTWwkZOeMw1mS82/7fUsYgfBW9oQ6p7mc MBQ+Z3F1WcbT0hbx14QZhCbkW7nzbcdvhLD6mrkeVJp28Y/oSA6EEfdtCmhC2tO6GJ9/ CKHg== 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=pF0QrcMOQzBo8+2c/JnytGGHLAaegxxMsZDOaVmEl2M=; b=Gblr2U24vIYpcduXAU1I0UL4Jzo6PQSkToI7jVDSgnHaDrgfUA558cuSQeavju+OMs EGLtVR3ubZDN0mYpzKICZLmiQnoJ9bGAA6L3xz2eb3m6s5Na8ARssf23PXZdoaCuFIYX /j4Cw7BzCIFWhJ/w6uFQgmcmpMAI10UyM8YZ6MxU0Go3lewdXF6oPLfYBCg/VIPnzjOQ S6DOjXmnI4sjcWqm1M7HHusIqRaMrJYhZosuyPqbZNO5fuSTQ5oVtlp0xmHw5Fs9d4Vn nT2mXnakiN2leswKFTGDfpaDBEXo20wZpPCchOsB79Kez6+e2KmrYbzonKhDYrQxi6aw 0SZA== 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 s7si330275ywd.729.2017.10.31.04.12.25 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:12:25 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44805 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UT3-0008NA-5Q for patch@linaro.org; Tue, 31 Oct 2017 07:12:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39824) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOs-0004sc-4z for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOo-00075g-CK for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:06 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42330) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOo-00075A-4K for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:02 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 79CC854006A; Tue, 31 Oct 2017 14:08:01 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:02 +0300 Message-ID: <20171031110802.5836.80558.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 15/26] replay/replay-internal.c: track holding of replay_lock X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- replay/replay-internal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/replay/replay-internal.c b/replay/replay-internal.c index fca8514..157c863 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -179,13 +179,24 @@ void replay_mutex_destroy(void) qemu_mutex_destroy(&lock); } +static __thread bool replay_locked; + +static bool replay_mutex_locked(void) +{ + return replay_locked; +} + void replay_mutex_lock(void) { + g_assert(!replay_mutex_locked()); qemu_mutex_lock(&lock); + replay_locked = true; } void replay_mutex_unlock(void) { + g_assert(replay_mutex_locked()); + replay_locked = false; qemu_mutex_unlock(&lock); } From patchwork Tue Oct 31 11:08:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117579 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3771348qgn; Tue, 31 Oct 2017 04:21:10 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QRdc37qtmvIgrvc3mUGMx4PX/YhcIFc8i20fWT6T7dAqn1WF5CawbRTTJXi+AGY1HfHZ7h X-Received: by 10.129.14.212 with SMTP id 203mr955772ywo.445.1509448870280; Tue, 31 Oct 2017 04:21:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448870; cv=none; d=google.com; s=arc-20160816; b=LwCtZubOUHfZT7thbfGCJ097p5VLwwLQL8W7Hgmcp0vFE/MWNCX//yHz9yjyHCk+00 +JNPXadbAldXi4MZ0HgweAfFzuyBdAI8sT/ILm+QlgbO8spZsmt7TRQDifB8RYUeGUMN M7lVVXWipPRm2KhoU+JG0WWxnqEEphzuuJw6/RhtN6HoLMha1MkZXELas/MzPt9QS7Wp 5zymOfqezSgnJYBpRtFUyHj6UOeM2ywL8gOsdXxw3ymNntYPyL4wPk6n6GILlKniUNfW Rzb/YHUYtQGh28qo5QCX7z3U1Trew/LFgikHQDDOnF7Z6wND4M9sS6+DFT6ttYAOWGWg FF4w== 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=FSE9bDlMw/zvW8KUyVcMJvoFYW1J2vc+F5rPhK6u+NY=; b=XW99LXnxnGqD3AnERhK/xlWUUvcbR2lCm2jAYezbA7DyM6JzUfcIr/AetW5KvqeXy4 u11n5qv5d526l8WkBchZym5tdjiGuodgf5GXQKF2eSdcfDpw86tRMBTrBYjiDfjTzIhe aXO+oV/w5U1ipml89B9rLASoM+MMEdJlwrkCJyPgOhAnypiC7nOa0DN++B2iG9jTTAGe 0d/rxL6GR0RG3MK5CxutJurtWQfLV8O5QhnSkQevaBUIIxleuzUZstgpK1GMBe6jZVaK +the3INHqgk1dAg3yDQbB+m0OKSjF/G9rcG3fP9CmRb4LvAQHHMSmN08wX+i1fm+si9U EDYg== 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 x67si328231ywc.757.2017.10.31.04.21.10 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:21:10 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44846 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UbV-00082S-SK for patch@linaro.org; Tue, 31 Oct 2017 07:21:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UP3-00053d-Qr for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOu-0007AC-05 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:17 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42342) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOt-00079L-IP for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:07 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id DC6EE54006A; Tue, 31 Oct 2017 14:08:06 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:07 +0300 Message-ID: <20171031110807.5836.50809.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 16/26] replay: make locking visible outside replay code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- include/sysemu/replay.h | 14 ++++++++++++++ replay/replay-internal.c | 5 ++--- replay/replay-internal.h | 5 ++--- stubs/replay.c | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index b86d6bb..9973849 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -47,6 +47,20 @@ extern ReplayMode replay_mode; /* Name of the initial VM snapshot */ extern char *replay_snapshot; +/* Replay locking + * + * The locks are needed to protect the shared structures and log file + * when doing record/replay. They also are the main sync-point between + * the main-loop thread and the vCPU thread. This was a role + * previously filled by the BQL which has been busy trying to reduce + * its impact across the code. This ensures blocks of events stay + * sequential and reproducible. + */ + +void replay_mutex_lock(void); +void replay_mutex_unlock(void); +bool replay_mutex_locked(void); + /* Replay process control functions */ /*! Enables recording or saving event log with specified parameters */ diff --git a/replay/replay-internal.c b/replay/replay-internal.c index 157c863..e6b2fdb 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -181,7 +181,7 @@ void replay_mutex_destroy(void) static __thread bool replay_locked; -static bool replay_mutex_locked(void) +bool replay_mutex_locked(void) { return replay_locked; } @@ -204,7 +204,7 @@ void replay_mutex_unlock(void) void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); int diff = (int)(replay_get_current_step() - replay_state.current_step); /* Time can only go forward */ @@ -215,6 +215,5 @@ void replay_save_instructions(void) replay_put_dword(diff); replay_state.current_step += diff; } - replay_mutex_unlock(); } } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 8e4c701..f5f8e96 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -100,12 +100,11 @@ int64_t replay_get_qword(void); void replay_get_array(uint8_t *buf, size_t *size); void replay_get_array_alloc(uint8_t **buf, size_t *size); -/* Mutex functions for protecting replay log file */ +/* Mutex functions for protecting replay log file and ensuring + * synchronisation between vCPU and main-loop threads. */ void replay_mutex_init(void); void replay_mutex_destroy(void); -void replay_mutex_lock(void); -void replay_mutex_unlock(void); /*! Checks error status of the file. */ void replay_check_error(void); diff --git a/stubs/replay.c b/stubs/replay.c index 9991ee5..cb050ef 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -73,3 +73,18 @@ uint64_t blkreplay_next_id(void) { return 0; } + +void replay_mutex_lock(void) +{ + abort(); +} + +void replay_mutex_unlock(void) +{ + abort(); +} + +bool replay_mutex_locked(void) +{ + return false; +} From patchwork Tue Oct 31 11:08:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117575 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3816318edm; Tue, 31 Oct 2017 04:13:13 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Sh4mOqyd0SnHjhv4wW0Pf8OL8zoD/xR67IKQs7jJ9RGOnBkbuFtQwmGkZV7LnhKxM8PvYu X-Received: by 10.37.189.83 with SMTP id p19mr857837ybm.232.1509448393124; Tue, 31 Oct 2017 04:13:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448393; cv=none; d=google.com; s=arc-20160816; b=VNJSNsX8MQjTJFU7p2b9sFjJXsyQ9EGHEN/w162AEDrzTKXMO2r+2lbGUF3Af23HyM RxFiIWzqSlhgYUxtUpmzltlHkMWCNSGNkrLiAVg/yp1PPtSjHXped9Rry5XVEpHMZ/uU ilfvetVF/aGHDtx0Zm34HkdRrSGVe2uprcp96MMAxVnBdWCXgmlqVnAS35xZ1jOfrD/4 f8z2xKfosbSPBdL7yoHz2sksH/lG5QwjE8NEykdS+pdPohFKWFKGmvkq47ASFD9MRHw0 VsLn8ZpuhWAgA+GV3JFiTgaiMeGqOGFxgpi5CFAy/3iq8T6dgHu0NF/DfGF00uycPW8g W8Mg== 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=MkOfHqgy2VO15bdcY2G7qUBXz5lu6BwzN92uEdXrk6A=; b=qayeL5KTARMjQ8Hc76pPw+8UjNvR2dW36XTPESNxswKzo4IRCaxhep5Og3HourN/3p 2sap5bY0rdK6UAbWURkICbcsMxqD1ABaxsfTVSPCgFZ1wtm3gze+QAQGcu5jRjtisVNV 6OoP0mof2iAU6zuOVtIONy/CwJM95PZTIMdCEHpyQa+2CyN2vsKu/QtqQTeLcJCzKbB9 i4eeLnj5c5FeNu/Wn8hlI0VN6D6enINdfg7RYzfBfN+F9saAFYdyEl6JCtltkhBYwc5p ok8/k9yEzJyCuQnGVIUSBW2ohv1Q7EPiqx5jnrHwMueUUSl45hfkWUbUX0fGtCQpBeDe ii4w== 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 n1si343518ywl.227.2017.10.31.04.13.12 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:13:13 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44807 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UTo-0000eP-Dx for patch@linaro.org; Tue, 31 Oct 2017 07:13:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UP4-00054H-J5 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UOz-0007Hn-GQ for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:18 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42362) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UOy-0007GB-W4 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:13 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 5B45854006A; Tue, 31 Oct 2017 14:08:12 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:13 +0300 Message-ID: <20171031110813.5836.45226.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 17/26] replay: push replay_mutex_lock up the call tree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru 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 --- cpus.c | 32 ++++++++++++++++++++++++++++++++ docs/replay.txt | 19 +++++++++++++++++++ include/sysemu/replay.h | 2 ++ replay/replay-char.c | 21 ++++++++------------- replay/replay-events.c | 18 +++++------------- replay/replay-internal.c | 18 +++++++++++++----- replay/replay-time.c | 10 +++++----- replay/replay.c | 40 ++++++++++++++++++++-------------------- util/main-loop.c | 23 ++++++++++++++++++++--- vl.c | 2 ++ 10 files changed, 126 insertions(+), 59 deletions(-) diff --git a/cpus.c b/cpus.c index de6dfce..110ce0a 100644 --- a/cpus.c +++ b/cpus.c @@ -1293,6 +1293,10 @@ static void prepare_icount_for_run(CPUState *cpu) insns_left = MIN(0xffff, cpu->icount_budget); cpu->icount_decr.u16.low = insns_left; cpu->icount_extra = cpu->icount_budget - insns_left; + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); + } } } @@ -1308,6 +1312,10 @@ static void process_icount_data(CPUState *cpu) cpu->icount_budget = 0; replay_account_executed_instructions(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } } } @@ -1395,6 +1403,10 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) while (1) { + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); + } + qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ @@ -1407,6 +1419,10 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_unlock_iothread(); + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } + if (!cpu) { cpu = first_cpu; } @@ -1677,12 +1693,28 @@ void pause_all_vcpus(void) cpu_stop_current(); } + /* We need to drop the replay_lock so any vCPU threads woken up + * can finish their replay tasks + */ + if (replay_mode != REPLAY_MODE_NONE) { + g_assert(replay_mutex_locked()); + qemu_mutex_unlock_iothread(); + replay_mutex_unlock(); + qemu_mutex_lock_iothread(); + } + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { qemu_cpu_kick(cpu); } } + + if (replay_mode != REPLAY_MODE_NONE) { + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); + } } void cpu_resume(CPUState *cpu) diff --git a/docs/replay.txt b/docs/replay.txt index c52407f..994153e 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -49,6 +49,25 @@ Modifications of qemu include: * recording/replaying user input (mouse and keyboard) * adding internal checkpoints for cpu and io synchronization +Locking and thread synchronisation +---------------------------------- + +Previously the synchronisation of the main thread and the vCPU thread +was ensured by the holding of the BQL. However the trend has been to +reduce the time the BQL was held across the system including under TCG +system emulation. As it is important that batches of events are kept +in sequence (e.g. expiring timers and checkpoints in the main thread +while instruction checkpoints are written by the vCPU thread) we need +another lock to keep things in lock-step. This role is now handled by +the replay_mutex_lock. It used to be held only for each event being +written but now it is held for a whole execution period. This results +in a deterministic ping-pong between the two main threads. + +As deadlocks are easy to introduce a new rule is introduced that the +replay_mutex_lock is taken before any BQL locks. Conversely you cannot +release the replay_lock while the BQL is still held. + + Non-deterministic events ------------------------ diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 9973849..d026b28 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -63,6 +63,8 @@ bool replay_mutex_locked(void); /* Replay process control functions */ +/*! Enables and take replay locks (even if we don't use it) */ +void replay_init_locks(void); /*! Enables recording or saving event log with specified parameters */ void replay_configure(struct QemuOpts *opts); /*! Initializes timers used for snapshotting and enables events recording */ diff --git a/replay/replay-char.c b/replay/replay-char.c index cbf7c04..736cc8c 100755 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -96,25 +96,24 @@ void *replay_event_char_read_load(void) void replay_char_write_event_save(int res, int offset) { + g_assert(replay_mutex_locked()); + replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_WRITE); replay_put_dword(res); replay_put_dword(offset); - replay_mutex_unlock(); } void replay_char_write_event_load(int *res, int *offset) { + g_assert(replay_mutex_locked()); + replay_account_executed_instructions(); - replay_mutex_lock(); if (replay_next_event_is(EVENT_CHAR_WRITE)) { *res = replay_get_dword(); *offset = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); } else { - replay_mutex_unlock(); error_report("Missing character write event in the replay log"); exit(1); } @@ -122,23 +121,21 @@ void replay_char_write_event_load(int *res, int *offset) int replay_char_read_all_load(uint8_t *buf) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + if (replay_next_event_is(EVENT_CHAR_READ_ALL)) { size_t size; int res; replay_get_array(buf, &size); replay_finish_event(); - replay_mutex_unlock(); res = (int)size; assert(res >= 0); return res; } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) { int res = replay_get_dword(); replay_finish_event(); - replay_mutex_unlock(); return res; } else { - replay_mutex_unlock(); error_report("Missing character read all event in the replay log"); exit(1); } @@ -146,19 +143,17 @@ int replay_char_read_all_load(uint8_t *buf) void replay_char_read_all_save_error(int res) { + g_assert(replay_mutex_locked()); assert(res < 0); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL_ERROR); replay_put_dword(res); - replay_mutex_unlock(); } void replay_char_read_all_save_buf(uint8_t *buf, int offset) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_CHAR_READ_ALL); replay_put_array(buf, offset); - replay_mutex_unlock(); } diff --git a/replay/replay-events.c b/replay/replay-events.c index e858254..a941efb 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -79,16 +79,14 @@ bool replay_has_events(void) void replay_flush_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } void replay_disable_events(void) @@ -102,14 +100,14 @@ void replay_disable_events(void) void replay_clear_events(void) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } - replay_mutex_unlock(); } /*! Adds specified async event to the queue */ @@ -136,9 +134,8 @@ void replay_add_event(ReplayAsyncEventKind event_kind, event->opaque2 = opaque2; event->id = id; - replay_mutex_lock(); + g_assert(replay_mutex_locked()); QTAILQ_INSERT_TAIL(&events_list, event, events); - replay_mutex_unlock(); } void replay_bh_schedule_event(QEMUBH *bh) @@ -210,10 +207,7 @@ void replay_save_events(int checkpoint) while (!QTAILQ_EMPTY(&events_list)) { Event *event = QTAILQ_FIRST(&events_list); replay_save_event(event, checkpoint); - - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); QTAILQ_REMOVE(&events_list, event, events); g_free(event); } @@ -299,9 +293,7 @@ void replay_read_events(int checkpoint) } replay_finish_event(); read_event_kind = -1; - replay_mutex_unlock(); replay_run_event(event); - replay_mutex_lock(); g_free(event); } diff --git a/replay/replay-internal.c b/replay/replay-internal.c index e6b2fdb..d036a02 100644 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -174,11 +174,6 @@ void replay_mutex_init(void) qemu_mutex_init(&lock); } -void replay_mutex_destroy(void) -{ - qemu_mutex_destroy(&lock); -} - static __thread bool replay_locked; bool replay_mutex_locked(void) @@ -186,15 +181,28 @@ bool replay_mutex_locked(void) return replay_locked; } +void replay_mutex_destroy(void) +{ + if (replay_mutex_locked()) { + qemu_mutex_unlock(&lock); + } + qemu_mutex_destroy(&lock); +} + + +/* Ordering constraints, replay_lock must be taken before BQL */ void replay_mutex_lock(void) { + g_assert(!qemu_mutex_iothread_locked()); g_assert(!replay_mutex_locked()); qemu_mutex_lock(&lock); replay_locked = true; } +/* BQL can't be held when releasing the replay_lock */ void replay_mutex_unlock(void) { + g_assert(!qemu_mutex_iothread_locked()); g_assert(replay_mutex_locked()); replay_locked = false; qemu_mutex_unlock(&lock); diff --git a/replay/replay-time.c b/replay/replay-time.c index f70382a..6a7565e 100644 --- a/replay/replay-time.c +++ b/replay/replay-time.c @@ -17,13 +17,13 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock) { - replay_save_instructions(); if (replay_file) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); + + replay_save_instructions(); replay_put_event(EVENT_CLOCK + kind); replay_put_qword(clock); - replay_mutex_unlock(); } return clock; @@ -46,16 +46,16 @@ void replay_read_next_clock(ReplayClockKind kind) /*! Reads next clock event from the input. */ int64_t replay_read_clock(ReplayClockKind kind) { + g_assert(replay_file && replay_mutex_locked()); + replay_account_executed_instructions(); if (replay_file) { int64_t ret; - replay_mutex_lock(); if (replay_next_event_is(EVENT_CLOCK + kind)) { replay_read_next_clock(kind); } ret = replay_state.cached_clock[kind]; - replay_mutex_unlock(); return ret; } diff --git a/replay/replay.c b/replay/replay.c index 4f24498..7fc50ea 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -80,8 +80,9 @@ int replay_get_instructions(void) void replay_account_executed_instructions(void) { + g_assert(replay_mutex_locked()); + if (replay_mode == REPLAY_MODE_PLAY) { - replay_mutex_lock(); if (replay_state.instructions_count > 0) { int count = (int)(replay_get_current_step() - replay_state.current_step); @@ -100,24 +101,22 @@ void replay_account_executed_instructions(void) qemu_notify_event(); } } - replay_mutex_unlock(); } } bool replay_exception(void) { + if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_EXCEPTION); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_exception(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -129,10 +128,9 @@ bool replay_has_exception(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_EXCEPTION); - replay_mutex_unlock(); } return res; @@ -141,17 +139,15 @@ bool replay_has_exception(void) bool replay_interrupt(void) { if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_save_instructions(); - replay_mutex_lock(); replay_put_event(EVENT_INTERRUPT); - replay_mutex_unlock(); return true; } else if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); bool res = replay_has_interrupt(); if (res) { - replay_mutex_lock(); replay_finish_event(); - replay_mutex_unlock(); } return res; } @@ -163,10 +159,9 @@ bool replay_has_interrupt(void) { bool res = false; if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); replay_account_executed_instructions(); - replay_mutex_lock(); res = replay_next_event_is(EVENT_INTERRUPT); - replay_mutex_unlock(); } return res; } @@ -174,9 +169,8 @@ bool replay_has_interrupt(void) void replay_shutdown_request(ShutdownCause cause) { if (replay_mode == REPLAY_MODE_RECORD) { - replay_mutex_lock(); + g_assert(replay_mutex_locked()); replay_put_event(EVENT_SHUTDOWN + cause); - replay_mutex_unlock(); } } @@ -190,9 +184,9 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) return true; } - replay_mutex_lock(); if (replay_mode == REPLAY_MODE_PLAY) { + g_assert(replay_mutex_locked()); if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) { replay_finish_event(); } else if (replay_state.data_kind != EVENT_ASYNC) { @@ -205,15 +199,21 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint) checkpoint were processed */ res = replay_state.data_kind != EVENT_ASYNC; } else if (replay_mode == REPLAY_MODE_RECORD) { + g_assert(replay_mutex_locked()); replay_put_event(EVENT_CHECKPOINT + checkpoint); replay_save_events(checkpoint); res = true; } out: - replay_mutex_unlock(); return res; } +void replay_init_locks(void) +{ + replay_mutex_init(); + replay_mutex_lock(); /* Hold while we start-up */ +} + static void replay_enable(const char *fname, int mode) { const char *fmode = NULL; @@ -233,8 +233,6 @@ static void replay_enable(const char *fname, int mode) atexit(replay_finish); - replay_mutex_init(); - replay_file = fopen(fname, fmode); if (replay_file == NULL) { fprintf(stderr, "Replay: open %s: %s\n", fname, strerror(errno)); @@ -274,6 +272,8 @@ void replay_configure(QemuOpts *opts) Location loc; if (!opts) { + /* we no longer need this lock */ + replay_mutex_destroy(); return; } diff --git a/util/main-loop.c b/util/main-loop.c index 7558eb5..7c5b163 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" // struct in_addr needed for libslirp.h #include "sysemu/qtest.h" #include "sysemu/cpus.h" +#include "sysemu/replay.h" #include "slirp/libslirp.h" #include "qemu/main-loop.h" #include "block/aio.h" @@ -245,19 +246,26 @@ static int os_host_main_loop_wait(int64_t timeout) timeout = SCALE_MS; } + if (timeout) { spin_counter = 0; - qemu_mutex_unlock_iothread(); } else { spin_counter++; } + qemu_mutex_unlock_iothread(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout); - if (timeout) { - qemu_mutex_lock_iothread(); + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); } + qemu_mutex_lock_iothread(); + glib_pollfds_poll(); g_main_context_release(context); @@ -463,8 +471,17 @@ static int os_host_main_loop_wait(int64_t timeout) poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout); qemu_mutex_unlock_iothread(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_unlock(); + } + g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns); + if (replay_mode != REPLAY_MODE_NONE) { + replay_mutex_lock(); + } + qemu_mutex_lock_iothread(); if (g_poll_ret > 0) { for (i = 0; i < w->num; i++) { diff --git a/vl.c b/vl.c index a8e0d03..77fc1ef 100644 --- a/vl.c +++ b/vl.c @@ -3137,6 +3137,8 @@ int main(int argc, char **argv, char **envp) qemu_init_cpu_list(); qemu_init_cpu_loop(); + + replay_init_locks(); qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); From patchwork Tue Oct 31 11:08:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117583 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3775515qgn; Tue, 31 Oct 2017 04:24:58 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QDxRuaDmBBepgppNOGbkuy0Lubmqb2nxkIZkUspGn37AFtq0Fa6AD9cPkoNZd4bNEX5b0t X-Received: by 10.37.115.136 with SMTP id o130mr900265ybc.35.1509449098145; Tue, 31 Oct 2017 04:24:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449098; cv=none; d=google.com; s=arc-20160816; b=b4z3tIm25rAtZyTLkAj0V0q1fZFhIeYCM/EN77CHXtFZufoR02It9ySfnmCh5LAn/p flRAoCjoL8tpPbqpxgUHj2M5bws7P/n28nZTJUcTr4bMpjwYb8wZKMSx3bg8I6opyVvG bn4yBoT3vxRIBKKU1RJn/rHjTxKKQiI8ty2vPFM9mjKhGIDAgNa+psV6fnTi+pQ+rk/C f38Kogw9nPZyoktU/DeFeBsQmbLpjFaV/9j7gsVKFNCTylAAK8JRzyi7Q3OdrQMmNb8a 6PsG95KKU7JLaziY/HSTvMMR1dD2c2QRJ/6d63e6sBiAZyP/Ae/U5gmZuQsf092QKVOm dvDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=8/Vw8eOcmoeZm82a8jz9Lqv6EaUsIFnni1lghWpg+Ng=; b=aWHQ/SiS9/goIJVhCZrdEtvqC7HS2LqV7nwPXLEMW7DXtz1Yie6o+VA1/1oW0xs9m9 A0OjkmhBTKEQLq6Oel1jvEghlFHmKDl2aZfbTQGJDwIKtdItIvFndG6Rnb/RgOZKp0mR QCn2b5tjkn+1yz0EPd2TJ8Uvb8nAiIO50MxNQwJQdZnW2KsijkwsS1ttWCSNWaFcy3t8 R/BAbPImK9gXqLv8tI4ViYhUvk2lrpnur4KGNizVv4N80/p3B6KWqbxhNHtNz41hdgCy kmKius7AZWEOQj0cXSyw7tibJW2Wnp/jK1u4yk2QkHDSmHe/RvQ+YcFkyckruEH83P9j Cmcw== 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 l14si323589ybm.757.2017.10.31.04.24.58 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:24:58 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44864 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UfB-0002Ov-O6 for patch@linaro.org; Tue, 31 Oct 2017 07:24:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40415) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPR-0005QF-CA for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UPQ-0007iy-7E for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:41 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42446) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPP-0007id-WF for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:40 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 572BE54006A; Tue, 31 Oct 2017 14:08:39 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:40 +0300 Message-ID: <20171031110840.5836.82943.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 22/26] scripts/qemu-gdb: add simple tcg lock status helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Add a simple helper to dump lock state. Signed-off-by: Alex Bennée --- scripts/qemu-gdb.py | 3 ++- scripts/qemugdb/tcg.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 scripts/qemugdb/tcg.py diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index b3f8e04..d58213e 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -26,7 +26,7 @@ import os, sys sys.path.append(os.path.dirname(__file__)) -from qemugdb import aio, mtree, coroutine +from qemugdb import aio, mtree, coroutine, tcg class QemuCommand(gdb.Command): '''Prefix for QEMU debug support commands''' @@ -38,6 +38,7 @@ QemuCommand() coroutine.CoroutineCommand() mtree.MtreeCommand() aio.HandlersCommand() +tcg.TCGLockStatusCommand() coroutine.CoroutineSPFunction() coroutine.CoroutinePCFunction() diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py new file mode 100644 index 0000000..8c7f1d7 --- /dev/null +++ b/scripts/qemugdb/tcg.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# GDB debugging support, TCG status +# +# Copyright 2016 Linaro Ltd +# +# Authors: +# Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. +# +# Contributions after 2012-01-13 are licensed under the terms of the +# GNU GPL, version 2 or (at your option) any later version. + +# 'qemu tcg-lock-status' -- display the TCG lock status across threads + +import gdb + +class TCGLockStatusCommand(gdb.Command): + '''Display TCG Execution Status''' + def __init__(self): + gdb.Command.__init__(self, 'qemu tcg-lock-status', gdb.COMMAND_DATA, + gdb.COMPLETE_NONE) + + def invoke(self, arg, from_tty): + gdb.write("Thread, BQL (iothread_mutex), Replay, Blocked?\n") + for thread in gdb.inferiors()[0].threads(): + thread.switch() + + iothread = gdb.parse_and_eval("iothread_locked") + replay = gdb.parse_and_eval("replay_locked") + + frame = gdb.selected_frame() + if frame.name() == "__lll_lock_wait": + frame.older().select() + mutex = gdb.parse_and_eval("mutex") + owner = gdb.parse_and_eval("mutex->__data.__owner") + blocked = ("__lll_lock_wait waiting on %s from %d" % + (mutex, owner)) + else: + blocked = "not blocked" + + gdb.write("%d/%d, %s, %s, %s\n" % (thread.num, thread.ptid[1], + iothread, replay, blocked)) From patchwork Tue Oct 31 11:08:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117584 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3777702qgn; Tue, 31 Oct 2017 04:27:06 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Q8Oyo11XAE9YY95Fh17xC1L7aPKbmjZLqitmAoYbFj+ViduTOcLTaQh+tH0ne+OJomHM5+ X-Received: by 10.129.99.85 with SMTP id x82mr918617ywb.225.1509449226741; Tue, 31 Oct 2017 04:27:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449226; cv=none; d=google.com; s=arc-20160816; b=WauXh5io/CNPxrX4f9evZkbZZUZ0SDWtUkKdDVU55cutMnNvsSfvxgfc7Ywx2sekma yOFXR8gav61IYrFSb7wQGgQOuTB20S0HVHYaPwYwsI8vxIc76yZVHfcDE9rczwiWljhZ Bpcxzw0818iGiDqYl1D/rlYJ0ezGAwjX6I8ZQvPM0Xf/bB1lJqwAyJZL8o2RzuhIwun6 A7A7oQ9jg+niGFJs47gTwifupOLR0S3UViurD2b1kxpSeiIpbKoIICP5aaqh/RLcLL2a e/baXWFe1sVX2xy46v7nuFTKK1ziZ7pi6S9+7Py9xLk0N0b1hqOI1ykWNwsjyid7ssvk gHrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=DxLEvgVZnhx6Th1Z2OcxhG+6S/6xQvOXu2TUf1VJeLk=; b=lDiqNkSYN/YfJMOPmv8DP641kawg4h5wU0ptjIUicZd5KZHbrR4tFtF1iPqr3jjORz EmZ6Qd9LnphmplM/tnMi1SOkR2s/H9iVNWeTOg6r9CPFYH5r8Q/qH8Mv0H+FQNndPmOY rgBo/MIMvjTJignDz+lvLDVmf543nJxEKWU0D47aBaYRSqNa0sHH07U8pH7zGPRD7oSL uMnyauAtcCB4z8blSaOYqU+Y5JgvD1QFIOD2NJxZhGXhES98OT9NTkeXFEaMzyVS17Pa Y4ROeakWek6j19UVr1ov3O8bL4YOMxhd8p1qSqc4N/0+hvivGVzddR3tODj2oETnJzqx UL8w== 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 d3si329778ybk.391.2017.10.31.04.27.06 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:27:06 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44877 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UhG-0003z4-6e for patch@linaro.org; Tue, 31 Oct 2017 07:27:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40541) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPZ-0005X4-L2 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UPV-0007mo-NH for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:49 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42462) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPV-0007mJ-Az for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:45 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id B51F254006A; Tue, 31 Oct 2017 14:08:44 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:45 +0300 Message-ID: <20171031110845.5836.63979.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 23/26] util/qemu-thread-*: add qemu_lock, locked and unlock trace events X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Signed-off-by: Alex Bennée --- v1 - fix merge conflicts with existing tracing - add trylock/cond_wait traces --- include/qemu/thread.h | 14 ++++++++++---- util/qemu-thread-posix.c | 21 ++++++++++++--------- util/trace-events | 7 ++++--- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 9910f49..c51a7f1 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -22,9 +22,13 @@ typedef struct QemuThread QemuThread; void qemu_mutex_init(QemuMutex *mutex); void qemu_mutex_destroy(QemuMutex *mutex); -void qemu_mutex_lock(QemuMutex *mutex); -int qemu_mutex_trylock(QemuMutex *mutex); -void qemu_mutex_unlock(QemuMutex *mutex); +int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line); +void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line); +void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line); + +#define qemu_mutex_lock(mutex) qemu_mutex_lock_impl(mutex, __FILE__, __LINE__) +#define qemu_mutex_trylock(mutex) qemu_mutex_trylock_impl(mutex, __FILE__, __LINE__) +#define qemu_mutex_unlock(mutex) qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__) /* Prototypes for other functions are in thread-posix.h/thread-win32.h. */ void qemu_rec_mutex_init(QemuRecMutex *mutex); @@ -39,7 +43,9 @@ void qemu_cond_destroy(QemuCond *cond); */ void qemu_cond_signal(QemuCond *cond); void qemu_cond_broadcast(QemuCond *cond); -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); +void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line); + +#define qemu_cond_wait(cond, mutex) qemu_cond_wait_impl(cond, mutex, __FILE__, __LINE__) void qemu_sem_init(QemuSemaphore *sem, int init); void qemu_sem_post(QemuSemaphore *sem); diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 7306475..1a838a9 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -57,26 +57,28 @@ void qemu_mutex_destroy(QemuMutex *mutex) error_exit(err, __func__); } -void qemu_mutex_lock(QemuMutex *mutex) +void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); + trace_qemu_mutex_lock(mutex, file, line); + err = pthread_mutex_lock(&mutex->lock); if (err) error_exit(err, __func__); - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); } -int qemu_mutex_trylock(QemuMutex *mutex) +int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); err = pthread_mutex_trylock(&mutex->lock); if (err == 0) { - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); return 0; } if (err != EBUSY) { @@ -85,15 +87,16 @@ int qemu_mutex_trylock(QemuMutex *mutex) return -EBUSY; } -void qemu_mutex_unlock(QemuMutex *mutex) +void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line) { int err; assert(mutex->initialized); - trace_qemu_mutex_unlocked(mutex); err = pthread_mutex_unlock(&mutex->lock); if (err) error_exit(err, __func__); + + trace_qemu_mutex_unlock(mutex, file, line); } void qemu_rec_mutex_init(QemuRecMutex *mutex) @@ -152,14 +155,14 @@ void qemu_cond_broadcast(QemuCond *cond) error_exit(err, __func__); } -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) +void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line) { int err; assert(cond->initialized); - trace_qemu_mutex_unlocked(mutex); + trace_qemu_mutex_unlock(mutex, file, line); err = pthread_cond_wait(&cond->cond, &mutex->lock); - trace_qemu_mutex_locked(mutex); + trace_qemu_mutex_locked(mutex, file, line); if (err) error_exit(err, __func__); } diff --git a/util/trace-events b/util/trace-events index 025499f..515e625 100644 --- a/util/trace-events +++ b/util/trace-events @@ -56,6 +56,7 @@ lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d" lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d" lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter" -# util/qemu-thread-posix.c -qemu_mutex_locked(void *lock) "locked mutex %p" -qemu_mutex_unlocked(void *lock) "unlocked mutex %p" +# util/qemu-thread.c +qemu_mutex_lock(void *mutex, const char *file, const int line) "waiting on mutex %p (%s:%d)" +qemu_mutex_locked(void *mutex, const char *file, const int line) "taken mutex %p (%s:%d)" +qemu_mutex_unlock(void *mutex, const char *file, const int line) "released mutex %p (%s:%d)" From patchwork Tue Oct 31 11:08:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117586 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3780460qgn; Tue, 31 Oct 2017 04:29:43 -0700 (PDT) X-Google-Smtp-Source: ABhQp+SrgYwFylyIWfI40SW/RxvwDjrmh4cVchZcTrDztkCMA6yte4kDzpCvJAgTsvxOe9z7SnNG X-Received: by 10.13.209.70 with SMTP id t67mr948489ywd.102.1509449383412; Tue, 31 Oct 2017 04:29:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449383; cv=none; d=google.com; s=arc-20160816; b=rUndQ3eSPsVHsBoNymBEciynZnorHyO267e9Q+eqbfI+Vq/+2O5NvQhCtikMf0eDZw UwtL1MhZTaHBl4lY3ltqex5QUemUlpOa0qH16z/Kz3NgjDSym9qH7wkSwJ8OTgqw5XRa QYZHRKfwsdIUXw+INpcdSpf92IMxsbmM6AAPZp9CeMXhQEgPlwBNkepBr0hOkItAI1HS gsM8Ge4GflekdSnpWfzBDmtNpKU/gQAumu8BkylmJpDnu242KUuw9dXYdbSicUoH97u/ EbygqUnQdTj1LBSBslah2SPcEXW+YtHTEeZNmGaOyGD2Zqmg4rL5Nj6Uwx0J/zSkxz1n 7EIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=aT+AWYNLUZIktc+qFKMvvIRgCCvYlgEwbMv7GDlIC3k=; b=PfWSowmItL7/bJ5BWFVN7iHAm9mjwcHT+K9yKFiUIGuhmT8KXzYCOk/e8FBC6dJZRw wAFl28D+VLDTUOtDx+xAdDJNxBmqgGFYmKMsuvaQ7s+1UEgfeU+7bzzE1tDdD6aWde92 bfWdGrXnPh7CkKzl4+37ttnf9izjctDhM6HiS6jjWjAAmCDvzd/DstjvLizPS6k6r/RR wKgp723IMSF6qsxcVzNTgao7Ao4g1s5b4hGHjfnfByBuLB4ql80v8AtQj87xYWlLqSrd vsllzzLK03jo5i6o2rktIXdJlWTFScF7ONO3jGvxFsN2/CstM32yUjl6THTAYK9fAI/q 1syA== 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 e66si337956ybb.794.2017.10.31.04.29.43 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:29:43 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44885 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9Ujm-0006If-Uc for patch@linaro.org; Tue, 31 Oct 2017 07:29:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40591) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPc-0005Zk-Gg for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UPb-0007u6-Bu for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:52 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42472) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPa-0007tb-Ss for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:51 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 1CD9F54006A; Tue, 31 Oct 2017 14:08:50 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:51 +0300 Message-ID: <20171031110851.5836.85776.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 24/26] scripts/analyse-locks-simpletrace.py: script to analyse lock times X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This script allows analysis of mutex acquisition and hold times based on a trace file. Given a trace control file of: qemu_mutex_lock qemu_mutex_locked qemu_mutex_unlock And running with: $QEMU $QEMU_ARGS -trace events=./lock-trace You can analyse the results with: ./scripts/analyse-locks-simpletrace.py trace-events-all ./trace-21812 Signed-off-by: Alex Bennée --- scripts/analyse-locks-simpletrace.py | 99 ++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 scripts/analyse-locks-simpletrace.py diff --git a/scripts/analyse-locks-simpletrace.py b/scripts/analyse-locks-simpletrace.py new file mode 100755 index 0000000..b72c951 --- /dev/null +++ b/scripts/analyse-locks-simpletrace.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Analyse lock events and +# +# Author: Alex Bennée +# + +import os +import simpletrace +import argparse +import numpy as np + +class MutexAnalyser(simpletrace.Analyzer): + "A simpletrace Analyser for checking locks." + + def __init__(self): + self.locks = 0 + self.locked = 0 + self.unlocks = 0 + self.mutex_records = {} + + def _get_mutex(self, mutex): + if not mutex in self.mutex_records: + self.mutex_records[mutex] = {"locks": 0, + "lock_time": 0, + "acquire_times": [], + "locked": 0, + "locked_time": 0, + "held_times": [], + "unlocked": 0} + + return self.mutex_records[mutex] + + def qemu_mutex_lock(self, timestamp, mutex, filename, line): + self.locks += 1 + rec = self._get_mutex(mutex) + rec["locks"] += 1 + rec["lock_time"] = timestamp[0] + rec["lock_loc"] = (filename, line) + + def qemu_mutex_locked(self, timestamp, mutex, filename, line): + self.locked += 1 + rec = self._get_mutex(mutex) + rec["locked"] += 1 + rec["locked_time"] = timestamp[0] + acquire_time = rec["locked_time"] - rec["lock_time"] + rec["locked_loc"] = (filename, line) + rec["acquire_times"].append(acquire_time) + + def qemu_mutex_unlock(self, timestamp, mutex, filename, line): + self.unlocks += 1 + rec = self._get_mutex(mutex) + rec["unlocked"] += 1 + held_time = timestamp[0] - rec["locked_time"] + rec["held_times"].append(held_time) + rec["unlock_loc"] = (filename, line) + + +def get_args(): + "Grab options" + parser = argparse.ArgumentParser() + parser.add_argument("--output", "-o", type=str, help="Render plot to file") + parser.add_argument("events", type=str, help='trace file read from') + parser.add_argument("tracefile", type=str, help='trace file read from') + return parser.parse_args() + +if __name__ == '__main__': + args = get_args() + + # Gather data from the trace + analyser = MutexAnalyser() + simpletrace.process(args.events, args.tracefile, analyser) + + print ("Total locks: %d, locked: %d, unlocked: %d" % + (analyser.locks, analyser.locked, analyser.unlocks)) + + # Now dump the individual lock stats + for key, val in sorted(analyser.mutex_records.iteritems(), + key=lambda (k,v): v["locks"]): + print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" % + (key, val["locks"], val["locked"], val["unlocked"])) + + acquire_times = np.array(val["acquire_times"]) + if len(acquire_times) > 0: + print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" % + (acquire_times.min(), np.median(acquire_times), + acquire_times.mean(), acquire_times.max())) + + held_times = np.array(val["held_times"]) + if len(held_times) > 0: + print (" Held Time: min:%d median:%d avg:%.2f max:%d" % + (held_times.min(), np.median(held_times), + held_times.mean(), held_times.max())) + + # Check if any locks still held + if val["locks"] > val["locked"]: + print (" LOCK HELD (%s:%s)" % (val["locked_loc"])) + print (" BLOCKED (%s:%s)" % (val["lock_loc"])) From patchwork Tue Oct 31 11:08:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117589 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3783631qgn; Tue, 31 Oct 2017 04:32:28 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QAUhrjZDJZIs3Q4KWc3eTflo/2fbkfBvaVMpuvlkgf1eNocw0JjrxySXu+yybhYiGjQuWP X-Received: by 10.129.175.12 with SMTP id n12mr968728ywh.151.1509449548651; Tue, 31 Oct 2017 04:32:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509449548; cv=none; d=google.com; s=arc-20160816; b=TKmOyPXedc3rVT07dZLcsedrX6j6UWsR9IX40UUa3pXtK6HTM5RfNnby8SlBU2JBn6 lXudlqJ3Ri9VrNtyh1v374FFUd82T0LrqceM3o4bI9xCh7lDhwzrjdRMufF472Y7gaRD X8Ra8Exe+OV/LdZt+x1pIjbwkVWRfzJhQ2ckax2PIWRjm+uHzptgn7fe4y+1ITlisnQZ Q8akQAELJ6DNrFJWsHjslj1fv90ORTSGKH58nmp+b0Fpg/fog0lWgWSoxdnI/b+GeCAv 3sZt/1fmePKn/s1Fj4uJFTC8dL3KS0DgrJ2PCAcFIYoN+91RMdyGCefsNsDx6MxOKURw OR3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=t7Q16W46hGY0/4vznypm79ggdT9i2ZsOOIaY54eKsk4=; b=kKrgfyQyLTQ7j1EgZoCrMZoMe3m1+yVJVfO36PtJwxLALMVlMX+d+GmZoocR/6zr1V ADZZNQBdO+HvflalIPGvOInBOKj3yBFU0yStgmT/MR84yTzb1HHnVNN4Evd3rTvPikcs Wvcz5phF5wMgJXrzH/e2wDZE1bANdSf2BTcffv4BY+5byaPIZiAWVqzcVigb6f1orN+L pcdszf3BPPTCQAZzg6S3E7LDsIhMAm9Q2bNOv7Mmu/cYxscurYpqwmCQJT6wSe7TOTdF SVK7+EHpmD9XGNvscnkRS/daUntSA7VprFZGe32rp5esOgM8cOpOcJKY9iCsS5jxSko5 a2Jg== 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 h14si340880ywc.577.2017.10.31.04.32.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:32:28 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44899 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UmS-0000Eb-3c for patch@linaro.org; Tue, 31 Oct 2017 07:32:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40734) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPl-0005hp-KL for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:09:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UPg-0007zQ-J0 for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:09:01 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42482) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPg-0007ym-6T for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:08:56 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 85B5F54006A; Tue, 31 Oct 2017 14:08:55 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:08:56 +0300 Message-ID: <20171031110856.5836.12982.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 25/26] scripts/replay-dump.py: replay log dumper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This script is a debugging tool for looking through the contents of a replay log file. It is incomplete but should fail gracefully at events it doesn't understand. It currently understands two different log formats as the audio record/replay support was merged during since MTTCG. It was written to help debug what has caused the BQL changes to break replay support. Signed-off-by: Alex Bennée --- v2 - yet another update to the log format --- scripts/replay-dump.py | 308 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100755 scripts/replay-dump.py diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py new file mode 100755 index 0000000..203bb31 --- /dev/null +++ b/scripts/replay-dump.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Dump the contents of a recorded execution stream +# +# Copyright (c) 2017 Alex Bennée +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +import argparse +import struct +from collections import namedtuple + +# This mirrors some of the global replay state which some of the +# stream loading refers to. Some decoders may read the next event so +# we need handle that case. Calling reuse_event will ensure the next +# event is read from the cache rather than advancing the file. + +class ReplayState(object): + def __init__(self): + self.event = -1 + self.event_count = 0 + self.already_read = False + self.current_checkpoint = 0 + self.checkpoint = 0 + + def set_event(self, ev): + self.event = ev + self.event_count += 1 + + def get_event(self): + self.already_read = False + return self.event + + def reuse_event(self, ev): + self.event = ev + self.already_read = True + + def set_checkpoint(self): + self.checkpoint = self.event - self.checkpoint_start + + def get_checkpoint(self): + return self.checkpoint + +replay_state = ReplayState() + +# Simple read functions that mirror replay-internal.c +# The file-stream is big-endian and manually written out a byte at a time. + +def read_byte(fin): + "Read a single byte" + return struct.unpack('>B', fin.read(1))[0] + +def read_event(fin): + "Read a single byte event, but save some state" + if replay_state.already_read: + return replay_state.get_event() + else: + replay_state.set_event(read_byte(fin)) + return replay_state.event + +def read_word(fin): + "Read a 16 bit word" + return struct.unpack('>H', fin.read(2))[0] + +def read_dword(fin): + "Read a 32 bit word" + return struct.unpack('>I', fin.read(4))[0] + +def read_qword(fin): + "Read a 64 bit word" + return struct.unpack('>Q', fin.read(8))[0] + +# Generic decoder structure +Decoder = namedtuple("Decoder", "eid name fn") + +def call_decode(table, index, dumpfile): + "Search decode table for next step" + decoder = next((d for d in table if d.eid == index), None) + if not decoder: + print "Could not decode index: %d" % (index) + print "Entry is: %s" % (decoder) + print "Decode Table is:\n%s" % (table) + return False + else: + return decoder.fn(decoder.eid, decoder.name, dumpfile) + +# Print event +def print_event(eid, name, string=None, event_count=None): + "Print event with count" + if not event_count: + event_count = replay_state.event_count + + if string: + print "%d:%s(%d) %s" % (event_count, name, eid, string) + else: + print "%d:%s(%d)" % (event_count, name, eid) + + +# Decoders for each event type + +def decode_unimp(eid, name, _unused_dumpfile): + "Unimplimented decoder, will trigger exit" + print "%s not handled - will now stop" % (name) + return False + +# Checkpoint decoder +def swallow_async_qword(eid, name, dumpfile): + "Swallow a qword of data without looking at it" + step_id = read_qword(dumpfile) + print " %s(%d) @ %d" % (name, eid, step_id) + return True + +async_decode_table = [ Decoder(0, "REPLAY_ASYNC_EVENT_BH", swallow_async_qword), + Decoder(1, "REPLAY_ASYNC_INPUT", decode_unimp), + Decoder(2, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), + Decoder(3, "REPLAY_ASYNC_CHAR_READ", decode_unimp), + Decoder(4, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), + Decoder(5, "REPLAY_ASYNC_EVENT_NET", decode_unimp), +] +# See replay_read_events/replay_read_event +def decode_async(eid, name, dumpfile): + """Decode an ASYNC event""" + + print_event(eid, name) + + async_event_kind = read_byte(dumpfile) + async_event_checkpoint = read_byte(dumpfile) + + if async_event_checkpoint != replay_state.current_checkpoint: + print " mismatch between checkpoint %d and async data %d" % ( + replay_state.current_checkpoint, async_event_checkpoint) + return True + + return call_decode(async_decode_table, async_event_kind, dumpfile) + + +def decode_instruction(eid, name, dumpfile): + ins_diff = read_dword(dumpfile) + print_event(eid, name, "0x%x" % (ins_diff)) + return True + +def decode_audio_out(eid, name, dumpfile): + audio_data = read_dword(dumpfile) + print_event(eid, name, "%d" % (audio_data)) + return True + +def decode_checkpoint(eid, name, dumpfile): + """Decode a checkpoint. + + Checkpoints contain a series of async events with their own specific data. + """ + replay_state.set_checkpoint() + # save event count as we peek ahead + event_number = replay_state.event_count + next_event = read_event(dumpfile) + + # if the next event is EVENT_ASYNC there are a bunch of + # async events to read, otherwise we are done + if next_event != 3: + print_event(eid, name, "no additional data", event_number) + else: + print_event(eid, name, "more data follows", event_number) + + replay_state.reuse_event(next_event) + return True + +def decode_checkpoint_init(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_interrupt(eid, name, dumpfile): + print_event(eid, name) + return True + +def decode_clock(eid, name, dumpfile): + clock_data = read_qword(dumpfile) + print_event(eid, name, "0x%x" % (clock_data)) + return True + + +# pre-MTTCG merge +v5_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_CLOCK_HOST", decode_clock), + Decoder(9, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(10, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(11, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(12, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(13, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(14, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(15, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(17, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(18, "EVENT_CP_RESET", decode_checkpoint), +] + +# post-MTTCG merge, AUDIO support added +v6_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(8, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(9, "EVENT_AUDIO_IN", decode_unimp), + Decoder(10, "EVENT_CLOCK_HOST", decode_clock), + Decoder(11, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(12, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(13, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(14, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(15, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(16, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(17, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(18, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(19, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(20, "EVENT_CP_RESET", decode_checkpoint), +] + +# Shutdown cause added +v7_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), + Decoder(1, "EVENT_INTERRUPT", decode_interrupt), + Decoder(2, "EVENT_EXCEPTION", decode_unimp), + Decoder(3, "EVENT_ASYNC", decode_async), + Decoder(4, "EVENT_SHUTDOWN", decode_unimp), + Decoder(5, "EVENT_SHUTDOWN_HOST_ERR", decode_unimp), + Decoder(6, "EVENT_SHUTDOWN_HOST_QMP", decode_unimp), + Decoder(7, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_unimp), + Decoder(8, "EVENT_SHUTDOWN_HOST_UI", decode_unimp), + Decoder(9, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_unimp), + Decoder(10, "EVENT_SHUTDOWN_GUEST_RESET", decode_unimp), + Decoder(11, "EVENT_SHUTDOWN_GUEST_PANIC", decode_unimp), + Decoder(12, "EVENT_SHUTDOWN___MAX", decode_unimp), + Decoder(13, "EVENT_CHAR_WRITE", decode_unimp), + Decoder(14, "EVENT_CHAR_READ_ALL", decode_unimp), + Decoder(15, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), + Decoder(16, "EVENT_AUDIO_OUT", decode_audio_out), + Decoder(17, "EVENT_AUDIO_IN", decode_unimp), + Decoder(18, "EVENT_CLOCK_HOST", decode_clock), + Decoder(19, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), + Decoder(20, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), + Decoder(21, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), + Decoder(22, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), + Decoder(23, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), + Decoder(24, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), + Decoder(25, "EVENT_CP_CLOCK_HOST", decode_checkpoint), + Decoder(26, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), + Decoder(27, "EVENT_CP_INIT", decode_checkpoint_init), + Decoder(28, "EVENT_CP_RESET", decode_checkpoint), +] + +def parse_arguments(): + "Grab arguments for script" + parser = argparse.ArgumentParser() + parser.add_argument("-f", "--file", help='record/replay dump to read from', + required=True) + return parser.parse_args() + +def decode_file(filename): + "Decode a record/replay dump" + dumpfile = open(filename, "rb") + + # read and throwaway the header + version = read_dword(dumpfile) + junk = read_qword(dumpfile) + + print "HEADER: version 0x%x" % (version) + + if version == 0xe02007: + event_decode_table = v7_event_table + replay_state.checkpoint_start = 12 + elif version == 0xe02006: + event_decode_table = v6_event_table + replay_state.checkpoint_start = 12 + else: + event_decode_table = v5_event_table + replay_state.checkpoint_start = 10 + + try: + decode_ok = True + while decode_ok: + event = read_event(dumpfile) + decode_ok = call_decode(event_decode_table, event, dumpfile) + finally: + dumpfile.close() + +if __name__ == "__main__": + args = parse_arguments() + decode_file(args.file) From patchwork Tue Oct 31 11:09:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 117577 Delivered-To: patch@linaro.org Received: by 10.80.245.45 with SMTP id t42csp3819783edm; Tue, 31 Oct 2017 04:16:13 -0700 (PDT) X-Google-Smtp-Source: ABhQp+SEvCl0k7vmvGKQCZc2FMbApsrvJ9hPmb05Be1Z5k+fnjDPTStr1lAuG8T/q9VsrzBT5q0Z X-Received: by 10.129.108.3 with SMTP id h3mr902183ywc.327.1509448573635; Tue, 31 Oct 2017 04:16:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509448573; cv=none; d=google.com; s=arc-20160816; b=njJ1DgNLZcofdedN7O72xxYMIc2tphRmEb09/QRDeSvNgXYAQUBaoL+Mjt9gtTyxhl Z3cYu80VtN9f5VV4CcyTlP0BtpSPs8AGbdjxL5cdvgCG/ik0ftI25Yt/4+nDTGCCW2jt O4TWVG9TrV/f9DESY94cIdscifiVFBrEEdLaTCFrFKAniiH4RUOkUXarOXHydbw8okJD cc1NCwvi9mRMSWOJy9xOsVqcaTDXZ166f994yKkC5HbDn2YHD+w7IC+MnRnFOc2W9GJ0 mnB7jg+kORbLcM4LN/QmEO0njg9HHpRSfswUPWsvwYzyKMMXV8/YXeKlMWHAWPLTu7hC aVzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=0mNrYB/7CQ13/nCWNidSOnK31xeLWYbx0BprAi0IOhM=; b=O3cuCWlBOMxx0+VXKIZWfa6/0ZkMQzjLzM8Pi6Nqt02ISiL8D2QpRzPPgqHqIf/hMc fdL26Cbc6h3tm4tLmITdCOcuDUE+cFnh7O5CxtqHkNTE9RJLpO15OrH5Zid9nCuvfDl9 xdp+IQWKsJ6GQZWEgt9N0R7HGvAxVSxW0Hb4/X4wcCnAG6xD4Adox6kyNFfIKEq4dkcr Deh2BkP5DEl7+576r8FomxuoowWJSlN3UZr+ESB8+v/tK7W5YZP4ljHelMQ+0pKVuEWz Nj9SU8lqzp+GjKGfplvf34kS/YJ34nZAq9PeF5wL2WCzSFE8NTcgHI72ccqSysR+vXSR TUhQ== 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 i13si350106ywl.685.2017.10.31.04.16.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 31 Oct 2017 04:16:13 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:44825 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UWj-0003N1-1I for patch@linaro.org; Tue, 31 Oct 2017 07:16:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40751) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPn-0005jB-2e for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:09:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e9UPl-00084b-Sa for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:09:03 -0400 Received: from mail.ispras.ru ([83.149.199.45]:42500) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e9UPl-000846-Jt for qemu-devel@nongnu.org; Tue, 31 Oct 2017 07:09:01 -0400 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id F0F1354006A; Tue, 31 Oct 2017 14:09:00 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 31 Oct 2017 14:09:01 +0300 Message-ID: <20171031110901.5836.26880.stgit@pasha-VirtualBox> In-Reply-To: <20171031110641.5836.43266.stgit@pasha-VirtualBox> References: <20171031110641.5836.43266.stgit@pasha-VirtualBox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 26/26] scripts/qemu-gdb/timers.py: new helper to dump timer state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dovgaluk@ispras.ru Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée This introduces the qemu-gdb command "qemu timers" which will dump the state of the main timers in the system. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé --- scripts/qemu-gdb.py | 3 ++- scripts/qemugdb/timers.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 scripts/qemugdb/timers.py diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index d58213e..690827e 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -26,7 +26,7 @@ import os, sys sys.path.append(os.path.dirname(__file__)) -from qemugdb import aio, mtree, coroutine, tcg +from qemugdb import aio, mtree, coroutine, tcg, timers class QemuCommand(gdb.Command): '''Prefix for QEMU debug support commands''' @@ -39,6 +39,7 @@ coroutine.CoroutineCommand() mtree.MtreeCommand() aio.HandlersCommand() tcg.TCGLockStatusCommand() +timers.TimersCommand() coroutine.CoroutineSPFunction() coroutine.CoroutinePCFunction() diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py new file mode 100644 index 0000000..be71a00 --- /dev/null +++ b/scripts/qemugdb/timers.py @@ -0,0 +1,54 @@ +#!/usr/bin/python +# GDB debugging support +# +# Copyright 2017 Linaro Ltd +# +# Author: Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. + +# 'qemu timers' -- display the current timerlists + +import gdb + +class TimersCommand(gdb.Command): + '''Display the current QEMU timers''' + + def __init__(self): + 'Register the class as a gdb command' + gdb.Command.__init__(self, 'qemu timers', gdb.COMMAND_DATA, + gdb.COMPLETE_NONE) + + def dump_timers(self, timer): + "Follow a timer and recursively dump each one in the list." + # timer should be of type QemuTimer + gdb.write(" timer %s/%s (cb:%s,opq:%s)\n" % ( + timer['expire_time'], + timer['scale'], + timer['cb'], + timer['opaque'])) + + if int(timer['next']) > 0: + self.dump_timers(timer['next']) + + + def process_timerlist(self, tlist, ttype): + gdb.write("Processing %s timers\n" % (ttype)) + gdb.write(" clock %s is enabled:%s, last:%s\n" % ( + tlist['clock']['type'], + tlist['clock']['enabled'], + tlist['clock']['last'])) + if int(tlist['active_timers']) > 0: + self.dump_timers(tlist['active_timers']) + + + def invoke(self, arg, from_tty): + 'Run the command' + main_timers = gdb.parse_and_eval("main_loop_tlg") + + # This will break if QEMUClockType in timer.h is redfined + self.process_timerlist(main_timers['tl'][0], "Realtime") + self.process_timerlist(main_timers['tl'][1], "Virtual") + self.process_timerlist(main_timers['tl'][2], "Host") + self.process_timerlist(main_timers['tl'][3], "Virtual RT")