From patchwork Mon Jan 9 11:18:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9504371 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6135160710 for ; Mon, 9 Jan 2017 11:19:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E6362848D for ; Mon, 9 Jan 2017 11:19:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6298128494; Mon, 9 Jan 2017 11:19:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F37DB2848D for ; Mon, 9 Jan 2017 11:19:29 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cQXz5-0008Bw-Bg; Mon, 09 Jan 2017 11:19:27 +0000 Received: from mail-lf0-x232.google.com ([2a00:1450:4010:c07::232]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cQXz1-00081e-Og for linux-arm-kernel@lists.infradead.org; Mon, 09 Jan 2017 11:19:25 +0000 Received: by mail-lf0-x232.google.com with SMTP id m78so71056594lfg.2 for ; Mon, 09 Jan 2017 03:19:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=zYR4FC1qRAgA55rDl8f8px908156fwNyCmv9dyxyYSQ=; b=eRF7jk4r4CM27NcBE5Qj5PG4HxCxuLWPQM+lgDHqjV5fL3onjMM+tdzMXsq/KZim12 KyiYH6cdipOPChm3QMXAszbrAFydRxb6Qbxhvje7OcGHgRUJaz3ZyLPLQdrVUy57JyC6 dVl4ZXShKyNbQiXh3oZWPfDUFD85SfPH+KTNk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=zYR4FC1qRAgA55rDl8f8px908156fwNyCmv9dyxyYSQ=; b=HqsyEKd1XXR8BwOFyN9DHE+plI+aa/yXraTQ+jEB+cocuaahh4pJNUNAe7C03dMD+b DBLXQclS1e7mYsRC5zCOAC/iauDvPf5HrqkKg852P7lUi3hyV3KrHzYHlI7hnMPzV7jp iaGzPhtBvgBlzdZV/EU8tZHuP03KJsq9+fjNpVJWRgVbUdkTd0nVajW2is3aVm7Zkj9p GhjN2vJVgJpC4Lxowkd5FpxI88pOtUl7pcycReC6VigMqjhdd0DuJhYzp0dzTH8fUtA3 ogrkfcG2YQR+LwZFDkR5jV6WOY3Dj8RI1vZDugviRqKJN8DS+RdbIOXO5ozqja3trBdb Voog== X-Gm-Message-State: AIkVDXLvbEUN9xjMEp0FaMrPAQSWcXIxwO7d7YWkOc62jIuBT0ILuHs4fLZ0CM2Szutq4oCo X-Received: by 10.25.227.72 with SMTP id c8mr32319545lfk.106.1483960741306; Mon, 09 Jan 2017 03:19:01 -0800 (PST) Received: from localhost.localdomain (x1-6-50-6a-03-de-ec-c2.cpe.webspeed.dk. [2.108.209.202]) by smtp.gmail.com with ESMTPSA id 70sm10891326lfw.11.2017.01.09.03.19.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jan 2017 03:19:00 -0800 (PST) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2] KVM: arm/arm64: Fix occasional warning from the timer work function Date: Mon, 9 Jan 2017 12:18:56 +0100 Message-Id: <20170109111856.8439-1-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.9.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170109_031924_034415_DDC480C7 X-CRM114-Status: GOOD ( 17.28 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , mbrugger@suse.com, Christoffer Dall , kvm@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP When a VCPU blocks (WFI) and has programmed the vtimer, we program a soft timer to expire in the future to wake up the vcpu thread when appropriate. Because such as wake up involves a vcpu kick, and the timer expire function can get called from interrupt context, and the kick may sleep, we have to schedule the kick in the work function. The work function currently has a warning that gets raised if it turns out that the timer shouldn't fire when it's run, which was added because the idea was that in that case the work should never have been cancelled. However, it turns out that this whole thing is racy and we can get spurious warnings. The problem is that we clear the armed flag in the work function, which may run in parallel with the kvm_timer_unschedule->timer_disarm() call. This results in a possible situation where the timer_disarm() call does not call cancel_work_sync(), which effectively synchronizes the completion of the work function with running the VCPU. As a result, the VCPU thread proceeds before the work function completees, causing changes to the timer state such that kvm_timer_should_fire(vcpu) returns false in the work function. All we do in the work function is to kick the VCPU, and an occasional rare extra kick never harmed anyone. Since the race above is extremely rare, we don't bother checking if the race happens but simply remove the check and the clearing of the armed flag from the work function. Reported-by: Matthias Brugger Signed-off-by: Christoffer Dall Reviewed-by: Marc Zyngier --- Changes since v1: - Don't add a second call to cancel_work_sync, but avoid clearing the armed flag to let the timer_disarm() function call cancel_work_sync on every unschedule call. - Note that I chose to remove the warning, despite it shouldn't really happen anymore, because I don't see the value in the warning and it does a bit of potentially unnecessary checking in a potentially hot path. virt/kvm/arm/arch_timer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index a2dbbcc..a7fe606 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -89,9 +89,6 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) struct kvm_vcpu *vcpu; vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired); - vcpu->arch.timer_cpu.armed = false; - - WARN_ON(!kvm_timer_should_fire(vcpu)); /* * If the vcpu is blocked we want to wake it up so that it will see