From patchwork Tue Nov 14 08:17:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 118852 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp2772765qgn; Tue, 14 Nov 2017 00:37:24 -0800 (PST) X-Google-Smtp-Source: AGs4zMZuF32A3NZDvJfyNpOgviZCbz6D3y/yk20KdJvQzVDdAnUsFNP5QnquTTfcwUnhl3NglgA2 X-Received: by 10.129.85.198 with SMTP id j189mr2885075ywb.504.1510648644640; Tue, 14 Nov 2017 00:37:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510648644; cv=none; d=google.com; s=arc-20160816; b=kVyytgGIB6Oixm9HNg8Xt2wLDxJLDieBkLDS8dEAT10rlyP+0XHPXriE8l9IQkberP Stj0+6zBaOiAHorRZSed+ZiDIC0IY3d01SMZ9hTcV2YXC6b+Yusyiq1Yo4uMwJ49BoBY tUTn6DV3a3rls7kPH0IrotI51lC543x5+tw/8YrsBslg2J+93x/mNaasBcuyKBJyHVNk hUW4wG3FoNd54mH3JPsWuaiTWNBXlVfgdWJLPSsWPNAIpEgV4QUdo97hb6ASlxo776ob 8qw90N4jnM6eUkb/Q4A6u+QlnOdYBQB4oi46sgS7TUGluAia7aoRc++/U8BR7A38eM6f m8ig== 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=KTldzkGteZd5nXNJsshgm9XwU0W5Aa64fuyzC+n/2BA=; b=QteggGl77ABMuFi2lLG41BImrV24GwgsuBX+J2169h8JRtugYF0pqrqYiM2eJZwxDC VlxRmVFTBnGCh82W9Szvuk/U4jMAUJwkKtpeUJEO4luQF5VLhURp9RUfzucRHDpsyNUi 10L2y04+WO6bN2YWIr92jZ48FC9EXZ6KhDJeLx4e2a/6JYUGeDMyIXZlFcJzgkudIRud c2hhCG9YFUk0wX/Dv1M3UtS1vFg9g6nJMLK2PSRdBDHc6TsQTC2yx2o9OKtn+T2DqPIc huHv3ZxnjIY5aIGdbGHQyIqx304gsMxBpMFUf6dRUFns9XUh9ixn8qeBwoY9pxa7t0Ba O/PA== 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 e127si753550ywh.257.2017.11.14.00.37.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Nov 2017 00:37:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:58273 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEWii-0001mZ-60 for patch@linaro.org; Tue, 14 Nov 2017 03:37:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40536) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEWPd-0008T0-Dx for qemu-devel@nongnu.org; Tue, 14 Nov 2017 03:17:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEWPZ-0006VA-Dd for qemu-devel@nongnu.org; Tue, 14 Nov 2017 03:17:41 -0500 Received: from mail.ispras.ru ([83.149.199.45]:52674) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEWPZ-0006UT-1q for qemu-devel@nongnu.org; Tue, 14 Nov 2017 03:17:37 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 3829754006A; Tue, 14 Nov 2017 11:17:36 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Tue, 14 Nov 2017 11:17:44 +0300 Message-ID: <20171114081744.27640.58377.stgit@pasha-VirtualBox> In-Reply-To: <20171114081630.27640.53933.stgit@pasha-VirtualBox> References: <20171114081630.27640.53933.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 v2 13/26] cpus: only take BQL for sleeping threads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, peter.maydell@linaro.org, pavel.dovgaluk@ispras.ru, mst@redhat.com, jasowang@redhat.com, quintela@redhat.com, zuban32s@gmail.com, maria.klimushenkova@ispras.ru, dovgaluk@ispras.ru, kraxel@redhat.com, boost.lists@gmail.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée Now the only real need to hold the BQL is for when we sleep on the cpu->halt conditional. The lock is actually dropped while the thread sleeps so the actual window for contention is pretty small. This also means we can remove the special case hack for exclusive work and simply declare that work no longer has an implicit BQL held. This isn't a major problem async work is generally only changing things in the context of its own vCPU. If it needs to work across vCPUs it should be using the exclusive mechanism or possibly taking the lock itself. Signed-off-by: Alex Bennée Tested-by: Pavel Dovgalyuk --- cpus-common.c | 13 +++++-------- cpus.c | 10 ++++------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/cpus-common.c b/cpus-common.c index 59f751e..64661c3 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -310,6 +310,11 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, queue_work_on_cpu(cpu, wi); } +/* Work items run outside of the BQL. This is essential for avoiding a + * deadlock for exclusive work but also applies to non-exclusive work. + * If the work requires cross-vCPU changes then it should use the + * exclusive mechanism. + */ void process_queued_cpu_work(CPUState *cpu) { struct qemu_work_item *wi; @@ -327,17 +332,9 @@ void process_queued_cpu_work(CPUState *cpu) } qemu_mutex_unlock(&cpu->work_mutex); if (wi->exclusive) { - /* Running work items outside the BQL avoids the following deadlock: - * 1) start_exclusive() is called with the BQL taken while another - * CPU is running; 2) cpu_exec in the other CPU tries to takes the - * BQL, so it goes to sleep; start_exclusive() is sleeping too, so - * neither CPU can proceed. - */ - qemu_mutex_unlock_iothread(); start_exclusive(); wi->func(cpu, wi->data); end_exclusive(); - qemu_mutex_lock_iothread(); } else { wi->func(cpu, wi->data); } diff --git a/cpus.c b/cpus.c index 3aeba5d..1800a3b 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)