From patchwork Thu Jan 11 08:26:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 124162 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp375738qgn; Thu, 11 Jan 2018 00:41:27 -0800 (PST) X-Google-Smtp-Source: ACJfBouOMRf9j6jS5rQ+0uvGY3FmtjzBpjmHo3prCCfljIIUviThdR+pn84OhKxDdDo/zFBUhiEV X-Received: by 10.37.76.131 with SMTP id z125mr19651526yba.298.1515660087746; Thu, 11 Jan 2018 00:41:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515660087; cv=none; d=google.com; s=arc-20160816; b=f3dk/Bwq6z8qB9qUFP7Ok8eSIOC2GfKQtMZ4XI0IXTQypDlVFPf0WnfyGgSsqCYlFE cVYodVvWd/YLQXWnLvVIFHjZKI7rTuV7doZ+If/NKjpPXb2VrAAsrM7Cu6086xul0E7m rVbhJy592aJ+bvDVUKoy55gI5QJ+t+au6laJ4fCcOEOt/7LvxqwJONx/uO53WgxV6Cua eenqLWnKI9eodRKgN5sXSLsWGZSxPzO9xR/OlPr+BZmwkik3awV3diXyIg6vn6vlJ8RR nS+vVn0yMPFcNxHEDgqJ81xi1KFmLnWn1dsKNi7wQkGVFzKhe3sadbZZondQSO4cSQnh maRw== 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=p8PbdddRaStnDU5J19juloMNJJWAiKmFUj76hk+vNXo=; b=UAMblHeevDGQKI8Cgvhbv17aEXj/Y8v7tH+MEblqkcurGEX3oNplBMn0tbe/GdpP9Y UQc3l5r77esoSolHBMBG2jssR6U03Nebust6VbRbRnzpBnHM2+c2TtBYP1/9dyJg7ET5 biDSffMaErFK2BTaFLEwgq/s/OOw/A5L+ccSE9dUFS0hRj2KIqEUtJXtgPe112tM+3nE IZ9WhVz+Ow/OqgwcH6Ump0h5vvDuZ9J+CPSTNp7rs3jdWBHF5evmdSeuCYdRSM6OuYK3 fHpRa8rzmCG0zFJRmvrZR5QGRdH/mxhEVthPylZ+mgMbnDTL2CRjqLh2w6whlEb+803U JUrg== 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 z5si1162218ywd.330.2018.01.11.00.41.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 11 Jan 2018 00:41:27 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:53101 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYQR-0003yq-6h for patch@linaro.org; Thu, 11 Jan 2018 03:41:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46684) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBv-0000ck-5s for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZYBu-0001Po-4G for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:27 -0500 Received: from mail.ispras.ru ([83.149.199.45]:41792) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZYBt-0001Ow-Nf for qemu-devel@nongnu.org; Thu, 11 Jan 2018 03:26:26 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E2CE454006B; Thu, 11 Jan 2018 11:26:24 +0300 (MSK) From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Thu, 11 Jan 2018 11:26:26 +0300 Message-ID: <20180111082626.27295.52919.stgit@pasha-VirtualBox> In-Reply-To: <20180111082452.27295.85707.stgit@pasha-VirtualBox> References: <20180111082452.27295.85707.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 v3 16/30] 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 82dcbf8..79dda49 100644 --- a/cpus.c +++ b/cpus.c @@ -1149,31 +1149,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_hvf_wait_io_event(CPUState *cpu)