Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp1520955pxb; Thu, 14 Apr 2022 07:57:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz2YarL2miu7ANbV7h7NIini3mhRZWw0Qmr8g/wkunuMkn4+7zlDzhe9WJEha+rJ9fLPuz7 X-Received: by 2002:a17:907:c0c:b0:6d1:8c46:6415 with SMTP id ga12-20020a1709070c0c00b006d18c466415mr2727352ejc.326.1649948242460; Thu, 14 Apr 2022 07:57:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649948242; cv=none; d=google.com; s=arc-20160816; b=gYtjP5ZeEtUXGrp0AfnjhBIKOVT5vkdhl82vEY4IAuQxacBlIWZle63+vjwXoOr78E 3KOpfpxlggK8pr8O7KD3Uk4P8j4UZi771cVvnP+23TWi7fogdo2oRGdGVGb2oh21wAHx y7P7h42+tQCIXWZVMgR0iBtUU3f4dG+gsptUFYUc1q4/wxePeCZdqUlpjc7f+x2q46A0 Cl5Q6YZYLMjuMEgfyXk0cdNPQZtECmH34w9gajV3pfV4DVjuZOBTkOTbMp8v+3B64QEO cVhcMOA4PL5GJQnfx/YAWMv/pPWYCM1JJeyyCREeRPT/VtgQH1AUV5PAHQC6UZqWeQV/ 6Pug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:mime-version:references:subject:cc:to:from :dkim-signature:dkim-signature:message-id; bh=hndER118dmw7kYMFXyYuvsxJ9ycP9/DqyDamURXJ4cA=; b=lBVLq46nNQ7qFim0awfBkbe1bSM81TCjP2ZrxY+yzKGVQVO8bjwfGyt6PCH9EF46rh iIUoaXkITqeWx6g0EhcbNn3c7R0lWg4aqX7JDiEr7BOMTdY1VjnhwbtYW5V33qsjgQ+i fIGeqX8LhRijTm55jC/qAN+bA5XSgLqNROjj5P/1pn/1OnrGyxf7QXqMITRcI01VGSNi 21r8HoyYak5/lLFD7CrwXsiYzc8j6Vvi1Xm5MGfxU89eRWaPD+KyKSgEYofZQS485Nlz ddvrrWdHVl04CJpINWhIoxSVy5ogA6cQzHBMwzaWcU8yR6zL1Yp4XHClxWZ/jzLD6rD5 W9Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=nToUJbUj; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=mLHAnQn7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i15-20020a170906698f00b006e81ff82175si2075247ejr.196.2022.04.14.07.56.52; Thu, 14 Apr 2022 07:57:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=nToUJbUj; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=mLHAnQn7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235780AbiDMNdf (ORCPT + 99 others); Wed, 13 Apr 2022 09:33:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235772AbiDMNd3 (ORCPT ); Wed, 13 Apr 2022 09:33:29 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 260145D5E7 for ; Wed, 13 Apr 2022 06:31:07 -0700 (PDT) Message-ID: <20220413133024.356509586@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1649856665; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=hndER118dmw7kYMFXyYuvsxJ9ycP9/DqyDamURXJ4cA=; b=nToUJbUjDp19tCC34fQsnLD80e9uEBpO6zMUv2CRiM2HdiUcrw6ShlgSs0RR8zYhBtZM7I XoTBDDcW2ZjEI94wQCnCc3V2oksdyEOz6lSaLbQJbRyhPEuuBDsDySfaDJtXA0r+89HD6P 8AHc51vIafk+7BjKQAdtV+lFhwP6BdrkvdEsq8CwdAxgRDEBJWQ5GKIKAZhLyD4hMS0pTP wTcanuYI8LKoYa5yHp6avlOz/TNQ90Z6i1OiMC5HAOWauJONZeirom5YaIBt6Dyyse9Gcj CofXuJjtUlvaUyGI9ljjspjT/7mWAIE/zYYrTNVc3QqhNbmHXsa1nCgIq9ncRA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1649856665; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=hndER118dmw7kYMFXyYuvsxJ9ycP9/DqyDamURXJ4cA=; b=mLHAnQn7pfVUUdyiJeOfFeqs6VtT74Sa7alLmxpMHxKolNUfcSJeQWITHXz1Q3c8Ommqha WD+dTyHgejoZYgCw== From: Thomas Gleixner To: LKML Cc: Christoph Hellwig , Peter Zijlstra , Sebastian Andrzej Siewior Subject: [patch V5 3/3] smp: Make softirq handling RT safe in flush_smp_call_function_queue() References: <20220413132836.099363044@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Wed, 13 Apr 2022 15:31:05 +0200 (CEST) X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sebastian Andrzej Siewior flush_smp_call_function_queue() invokes do_softirq() which is not available on PREEMPT_RT. flush_smp_call_function_queue() is invoked from the idle task and the migration task with preemption or interrupts disabled. So RT kernels cannot process soft interrupts in that context as that has to acquire 'sleeping spinlocks' which is not possible with preemption or interrupts disabled and forbidden from the idle task anyway. The currently known SMP function call which raises a soft interrupt is in the block layer, but this functionality is not enabled on RT kernels due to latency and performance reasons. RT could wake up ksoftirqd unconditionally, but this wants to be avoided if there were soft interrupts pending already when this is invoked in the context of the migration task. The migration task might have preempted a threaded interrupt handler which raised a soft interrupt, but did not reach the local_bh_enable() to process it. The "running" ksoftirqd might prevent the handling in the interrupt thread context which is causing latency issues. Add a new function which handles this case explicitely for RT and falls back to do_softirq() on !RT kernels. In the RT case this warns when one of the flushed SMP function calls raised a soft interrupt so this can be investigated. [ tglx: Moved the RT part out of SMP code ] Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/YgKgL6aPj8aBES6G@linutronix.de --- v4: - Move the RT logic into softirq.c which also avoids the wakeup when softinterrupts are disabled. The enable will handle them anyway. v3: - Only wake ksoftirqd if the softirqs were raised wthin flush_smp_call_function_queue(). - Add a warning in the wake case. v2: Drop an empty line. include/linux/interrupt.h | 9 +++++++++ kernel/smp.c | 5 ++++- kernel/softirq.c | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) --- --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -607,6 +607,15 @@ struct softirq_action asmlinkage void do_softirq(void); asmlinkage void __do_softirq(void); +#ifdef CONFIG_PREEMPT_RT +extern void do_softirq_post_smp_call_flush(unsigned int was_pending); +#else +static inline void do_softirq_post_smp_call_flush(unsigned int unused) +{ + do_softirq(); +} +#endif + extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); extern void __raise_softirq_irqoff(unsigned int nr); --- a/kernel/smp.c +++ b/kernel/smp.c @@ -696,6 +696,7 @@ static void __flush_smp_call_function_qu */ void flush_smp_call_function_queue(void) { + unsigned int was_pending; unsigned long flags; if (llist_empty(this_cpu_ptr(&call_single_queue))) @@ -704,9 +705,11 @@ void flush_smp_call_function_queue(void) cfd_seq_store(this_cpu_ptr(&cfd_seq_local)->idle, CFD_SEQ_NOCPU, smp_processor_id(), CFD_SEQ_IDLE); local_irq_save(flags); + /* Get the already pending soft interrupts for RT enabled kernels */ + was_pending = local_softirq_pending(); __flush_smp_call_function_queue(true); if (local_softirq_pending()) - do_softirq(); + do_softirq_post_smp_call_flush(was_pending); local_irq_restore(flags); } --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -294,6 +294,19 @@ static inline void invoke_softirq(void) wakeup_softirqd(); } +/* + * flush_smp_call_function_queue() can raise a soft interrupt in a function + * call. On RT kernels this is undesired and the only known functionality + * in the block layer which does this is disabled on RT. If soft interrupts + * get raised which haven't been raised before the flush, warn so it can be + * investigated. + */ +void softirq_post_smp_call_flush(unsigned int was_pending) +{ + if (WARN_ON_ONCE(was_pending != local_softirq_pending())) + invoke_softirq(); +} + #else /* CONFIG_PREEMPT_RT */ /*