From patchwork Thu Mar 30 17:36:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suzuki K Poulose X-Patchwork-Id: 9654875 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 325BE602BD for ; Thu, 30 Mar 2017 17:37:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21D26285B0 for ; Thu, 30 Mar 2017 17:37:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1688F285B8; Thu, 30 Mar 2017 17:37:51 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BF93A285B6 for ; Thu, 30 Mar 2017 17:37:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933729AbdC3Rhj (ORCPT ); Thu, 30 Mar 2017 13:37:39 -0400 Received: from foss.arm.com ([217.140.101.70]:50832 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933259AbdC3Rhi (ORCPT ); Thu, 30 Mar 2017 13:37:38 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E092980D; Thu, 30 Mar 2017 10:37:36 -0700 (PDT) Received: from e107814-lin.cambridge.arm.com (e107814-lin.cambridge.arm.com [10.1.206.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 304303F220; Thu, 30 Mar 2017 10:37:35 -0700 (PDT) From: Suzuki K Poulose To: linux-arm-kernel@lists.infradead.org Cc: marc.zyngier@arm.com, mark.rutland@arm.com, peterz@infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Suzuki K Poulose , Frederic Weisbecker , Peter Zijlstra , Arnd Bergmann Subject: Re: KVM/ARM: sleeping function called from invalid context Date: Thu, 30 Mar 2017 18:36:07 +0100 Message-Id: <1490895367-10547-1-git-send-email-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <7047d954-5c43-600a-3511-4c7dbd60c175@arm.com> References: <7047d954-5c43-600a-3511-4c7dbd60c175@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I have confirmed the theory using a sample code like : spin_lock(&a); spin_lock(&b); cond_resched_lock(&b); spin_unlock(&b); spin_unlock(&a); Also, the following patch solves the problem for me. ----8>----- sched: Fix ___might_sleep preempt count checks ___might_sleep checks if the preempt_count equals the passed in preempt_offset to issue a warning. This could cause false warnings, when preempt_count is greater than the requested offset. Fix the check to make sure we handle this case. e.g, following code sequence could cause false warning: foo: spin_lock(&a); ... bar() ---------> bar: spin_lock(&b); cond_resched_lock(&b); do_something(); spin_unlock(&b); <----------- ... spin_unlock(&a) where locks a and b need not necessarily be related. Cc: Marc Zyngier Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnd Bergmann Reported-by: Mark Rutland Signed-off-by: Suzuki K Poulose --- kernel/sched/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3b31fc0..28842dc 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6144,11 +6144,11 @@ void __init sched_init(void) } #ifdef CONFIG_DEBUG_ATOMIC_SLEEP -static inline int preempt_count_equals(int preempt_offset) +static inline int preempt_count_safe(int preempt_offset) { int nested = preempt_count() + rcu_preempt_depth(); - return (nested == preempt_offset); + return (nested >= preempt_offset); } void __might_sleep(const char *file, int line, int preempt_offset) @@ -6179,7 +6179,7 @@ void ___might_sleep(const char *file, int line, int preempt_offset) /* WARN_ON_ONCE() by default, no rate limit required: */ rcu_sleep_check(); - if ((preempt_count_equals(preempt_offset) && !irqs_disabled() && + if ((preempt_count_safe(preempt_offset) && !irqs_disabled() && !is_idle_task(current)) || system_state != SYSTEM_RUNNING || oops_in_progress) return; @@ -6205,7 +6205,7 @@ void ___might_sleep(const char *file, int line, int preempt_offset) if (irqs_disabled()) print_irqtrace_events(current); if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) - && !preempt_count_equals(preempt_offset)) { + && !preempt_count_safe(preempt_offset)) { pr_err("Preemption disabled at:"); print_ip_sym(preempt_disable_ip); pr_cont("\n");