Received: by 2002:a05:6a10:6d25:0:0:0:0 with SMTP id gq37csp1844744pxb; Mon, 13 Sep 2021 06:48:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzjc+E6qG1NYdllyPKZ7pbqTKeZe4bcPhy5JVsj8Tlrlo/LJpwZntYpObI1GkHDMooRr2w6 X-Received: by 2002:a92:cd8d:: with SMTP id r13mr2489833ilb.244.1631540884974; Mon, 13 Sep 2021 06:48:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631540884; cv=none; d=google.com; s=arc-20160816; b=lCDSAz8P1k2eKSJWAf09nSoxBCnnMmp66bPR12ixe6uQgz2MtqFPrf+pJhzzOD0UDo Qt7VRloLQzfssBBQ5l5PX3d0bm+99aGrhn8PCt8V7N24ncwfW8KlB+0F1NBeFQ3ALeZe MzrL03TisXN80FGc438Bc0z3Mhsfi0H+MVdGEc4sRqFFmreyh8e6x7On4Ry+49L7M60u PkbgNI+pK0YZESumCCFrUG0WCaSyPzila1BuUqXA/kKkTVQFRhLEN8cVQPh2ADl008qr chc+DsjAPYtp9xH4ZPAjOb7RdXH/c3hlJhEZ2Moe+M6twP13d4OF3gWVEqnxgjm651wM 9uUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=JheCzaPrHp/8HVAaYvLXU2IExUg2XJ1oZVeW/aMbJXw=; b=Vcb/eyA4fNYFTBEjt4AJYAehiHapKyQ4gdYfgH9AtuJfMMmRANcclRxTJSxGeBA/F4 WKyS04g6nuxG9GZxpMFUS2mY+24Sg1UXA39G+qBurdT/1XwM1w8p01nqSaroRlrvQT26 JovRbIISrRf6aFFbMk6M3NEz9xZP5aVg+1Tuu5FUUAM5+tTCEaT5DC5of2necQ1f2+0H OqkxipzYn09SK48w3bxXrwCOxPoMvcaGxKwa9F5WGbA4N+H7lHkCSf6WgHJIUiHz/oMV MiLqjr1ye2GMRYnntNv0fpqv33+YOwJlRgBoyR47i/JKIuu490MJD8hUAA6peA3W05YL kphA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iJEOpvYP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q17si7047671ilc.49.2021.09.13.06.47.52; Mon, 13 Sep 2021 06:48:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iJEOpvYP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242282AbhIMNqV (ORCPT + 99 others); Mon, 13 Sep 2021 09:46:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:41696 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239090AbhIMNk7 (ORCPT ); Mon, 13 Sep 2021 09:40:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 46AB46127C; Mon, 13 Sep 2021 13:29:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631539781; bh=ohwEJtFRB3PaxDtINta776MDdnaHFIlz/gMmTM7tb7s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iJEOpvYP+X1Q9sme1LGBRrPpGS7LDvT+dtkbNcD+4ZRt5z5pZAl29xBkay8ZMQcIX sdVwyNyu2kX6RwNdzFu3h7a1Xl5XLrfZ8ClViThq4lkjnKKsocC0zh1VcPZGaz/qnJ FrTkroOpVEBfEu9q20vaer+ItINzDoptFY+sINTc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Valentin Schneider , Sebastian Andrzej Siewior , "Rafael J. Wysocki" , Sasha Levin Subject: [PATCH 5.10 158/236] PM: cpu: Make notifier chain use a raw_spinlock_t Date: Mon, 13 Sep 2021 15:14:23 +0200 Message-Id: <20210913131105.757862600@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210913131100.316353015@linuxfoundation.org> References: <20210913131100.316353015@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Valentin Schneider [ Upstream commit b2f6662ac08d0e7c25574ce53623c71bdae9dd78 ] Invoking atomic_notifier_chain_notify() requires acquiring a spinlock_t, which can block under CONFIG_PREEMPT_RT. Notifications for members of the cpu_pm notification chain will be issued by the idle task, which can never block. Making *all* atomic_notifiers use a raw_spinlock is too big of a hammer, as only notifications issued by the idle task are problematic. Special-case cpu_pm_notifier_chain by kludging a raw_notifier and raw_spinlock_t together, matching the atomic_notifier behavior with a raw_spinlock_t. Fixes: 70d932985757 ("notifier: Fix broken error handling pattern") Signed-off-by: Valentin Schneider Acked-by: Sebastian Andrzej Siewior Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- kernel/cpu_pm.c | 50 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index f7e1d0eccdbc..246efc74e3f3 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -13,19 +13,32 @@ #include #include -static ATOMIC_NOTIFIER_HEAD(cpu_pm_notifier_chain); +/* + * atomic_notifiers use a spinlock_t, which can block under PREEMPT_RT. + * Notifications for cpu_pm will be issued by the idle task itself, which can + * never block, IOW it requires using a raw_spinlock_t. + */ +static struct { + struct raw_notifier_head chain; + raw_spinlock_t lock; +} cpu_pm_notifier = { + .chain = RAW_NOTIFIER_INIT(cpu_pm_notifier.chain), + .lock = __RAW_SPIN_LOCK_UNLOCKED(cpu_pm_notifier.lock), +}; static int cpu_pm_notify(enum cpu_pm_event event) { int ret; /* - * atomic_notifier_call_chain has a RCU read critical section, which - * could be disfunctional in cpu idle. Copy RCU_NONIDLE code to let - * RCU know this. + * This introduces a RCU read critical section, which could be + * disfunctional in cpu idle. Copy RCU_NONIDLE code to let RCU know + * this. */ rcu_irq_enter_irqson(); - ret = atomic_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL); + rcu_read_lock(); + ret = raw_notifier_call_chain(&cpu_pm_notifier.chain, event, NULL); + rcu_read_unlock(); rcu_irq_exit_irqson(); return notifier_to_errno(ret); @@ -33,10 +46,13 @@ static int cpu_pm_notify(enum cpu_pm_event event) static int cpu_pm_notify_robust(enum cpu_pm_event event_up, enum cpu_pm_event event_down) { + unsigned long flags; int ret; rcu_irq_enter_irqson(); - ret = atomic_notifier_call_chain_robust(&cpu_pm_notifier_chain, event_up, event_down, NULL); + raw_spin_lock_irqsave(&cpu_pm_notifier.lock, flags); + ret = raw_notifier_call_chain_robust(&cpu_pm_notifier.chain, event_up, event_down, NULL); + raw_spin_unlock_irqrestore(&cpu_pm_notifier.lock, flags); rcu_irq_exit_irqson(); return notifier_to_errno(ret); @@ -49,12 +65,17 @@ static int cpu_pm_notify_robust(enum cpu_pm_event event_up, enum cpu_pm_event ev * Add a driver to a list of drivers that are notified about * CPU and CPU cluster low power entry and exit. * - * This function may sleep, and has the same return conditions as - * raw_notifier_chain_register. + * This function has the same return conditions as raw_notifier_chain_register. */ int cpu_pm_register_notifier(struct notifier_block *nb) { - return atomic_notifier_chain_register(&cpu_pm_notifier_chain, nb); + unsigned long flags; + int ret; + + raw_spin_lock_irqsave(&cpu_pm_notifier.lock, flags); + ret = raw_notifier_chain_register(&cpu_pm_notifier.chain, nb); + raw_spin_unlock_irqrestore(&cpu_pm_notifier.lock, flags); + return ret; } EXPORT_SYMBOL_GPL(cpu_pm_register_notifier); @@ -64,12 +85,17 @@ EXPORT_SYMBOL_GPL(cpu_pm_register_notifier); * * Remove a driver from the CPU PM notifier list. * - * This function may sleep, and has the same return conditions as - * raw_notifier_chain_unregister. + * This function has the same return conditions as raw_notifier_chain_unregister. */ int cpu_pm_unregister_notifier(struct notifier_block *nb) { - return atomic_notifier_chain_unregister(&cpu_pm_notifier_chain, nb); + unsigned long flags; + int ret; + + raw_spin_lock_irqsave(&cpu_pm_notifier.lock, flags); + ret = raw_notifier_chain_unregister(&cpu_pm_notifier.chain, nb); + raw_spin_unlock_irqrestore(&cpu_pm_notifier.lock, flags); + return ret; } EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier); -- 2.30.2