From nobody Mon Oct 6 17:06:51 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1DAE1DE2C9 for ; Fri, 18 Jul 2025 18:54:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864850; cv=none; b=TzNI0oR9MQx4hiGnNWJ2jKF5VHGN2W0hab2oJ0Hs92nEOObQeggCdLWpWIt2BPCgyg091CAjWtV+EZ3GmLPMz/vYZnCwUnhqof8iwxLrb5a+yAPqKB3Ounj6XoB78O8USlwoYLaoBufQ5W4BQJS4nRHdJRRVKcUnV5eVxT7n7lo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864850; c=relaxed/simple; bh=P567dXRg/KvLhRUo8mwesE1SeWcW+KTYDp7PzEbqHB8=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=lELF06lOYUO88bsQ3p7ID5ZAYZzjfml6ti5qMZ8DNwNwvTpuZzKSsdaMbmLtk9G+Q0yNTiQQT3Hj7QZCQ6Bzhhut1DR03Vdfzo0Ede6UQ5KZVCqRHlCNZX6Y2OgmN6Q6Ehsl1BL3HsmcF/TJU01/QVl0W6RlOaMmXm/0xZNX+Us= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=19PzVTwK; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=kgaDAbJ0; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="19PzVTwK"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="kgaDAbJ0" Message-ID: <20250718185311.884314473@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752864847; 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=4dZC4L57CDX8HABgPtgp5Q7NV2PV+BaAUb3Jv/YjGBI=; b=19PzVTwKfTc1HCU7ASgUsFGhOKfrqAYZKPa79LO5dj5reCBdcPhySBMsD7Ur7pr3lT96Hz eV+lo/d99SQVp3ItEJ5KQZO1Uuxq27pJ5TaD6OVsseasgxZZTzAU+2c8IkZpENFL+j1/c+ 9o+50vievgUA08vjS0mPdgcE8Nf96e2vCjcyx/prDw5WbF0VQZ/9FWn6/qp2MZVXCVGfOV GhD3m+CAQMxD+vZrRNATjFnGYGr0m0MCaGM/9bIU6FDT9yqfXyKn+QfozOAOqxRMK/rQ4e UdH0ncaW9p6z/cuSlRKrbHdHypNHKVDdecFOqVfa+m0PgsqpSaI9mH1HwtT0HQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752864847; 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=4dZC4L57CDX8HABgPtgp5Q7NV2PV+BaAUb3Jv/YjGBI=; b=kgaDAbJ0keEZs71r28Go7V5G03uUSwnwSY+UyaA16DlxNG4MshUruEu9+Y7nt4zPd7DSml e7lSwLTwJnktHLAQ== From: Thomas Gleixner To: LKML Cc: Liangyan , Yicong Shen , Jiri Slaby Subject: [patch 1/4] genirq: Remove pointless local variable References: <20250718184935.232983339@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 18 Jul 2025 20:54:06 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The variable is only used at one place, which can simply take the constant as function argument. Signed-off-by: Thomas Gleixner Tested-by: Liangyan --- kernel/irq/chip.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -458,13 +458,11 @@ static bool irq_check_poll(struct irq_de =20 static bool irq_can_handle_pm(struct irq_desc *desc) { - unsigned int mask =3D IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARMED; - /* * If the interrupt is not in progress and is not an armed * wakeup interrupt, proceed. */ - if (!irqd_has_set(&desc->irq_data, mask)) + if (!irqd_has_set(&desc->irq_data, IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARME= D)) return true; =20 /* From nobody Mon Oct 6 17:06:51 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E6502E8DE6 for ; Fri, 18 Jul 2025 18:54:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864852; cv=none; b=FW5vHmX/ABDQc9BgOwXaumaup7PiAJW6T/FU9wX1iCrCt8QhBZNENCB56g/JFJoK7kCI3rPVPjSsjT2lC0OiHPPGOC+fx9Fxae8eo/03obNBE6VmYUPox1yVmm/91tstGGizNV1igE0cbwgdDXHw8rNdIQU6aFWopzFTxgtA5wU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864852; c=relaxed/simple; bh=JkFlwcgj279Syc1L8u/Q6lujZojZqd9U5fxEhAXzlR8=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=nPdsvCDySozo9ZTJ1Lwued1lMCb1zShPnXE/CDg16tXR2N8Wu79mWTVhVWNB0HSDcECvzAosuN2+Gu7EDyF1U6THxEFgG0t4Zs7HFOrOcebrmMLszyrBloD8oaUfuM/hiNfokaHFUnGrjILumJtx7Dfj89o7Wxa3gGFssfc9GiY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=PxUaad60; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=rdZnScR4; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="PxUaad60"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="rdZnScR4" Message-ID: <20250718185311.948555026@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752864849; 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=vTV7mchOKPGOAvrE1FkrHv3nOnwG2HV4Y7IDBFMVTO8=; b=PxUaad60nrUz2WBQu7IsG9xMMSw80JJLUbyW/xjjXoiwMR1LlXZLt6FWkFeoGFa4vSGvnk j+d/0QF2MUHKKrsD3capvGoDv9nvy7xyiJI0haBGMyYesn8V7nz8uDAXmO5Bbh8Yi6vMoY bV2TtbcB19Pp9SP0Ck+pBPJ3JLR9NJV+57VhyyNwu1PGXKrlZkhCVKZv/cHcFn2CPVRf82 9CvqksrnknaPr4/H4prf8vcLVcXkF1YPn3pFkhnJEg+9uObtOHEvYB9X+QVoyoSN0En5fw /a6KrGO/QCEyd4MngKlVHGpPbw7+KpUsIFFGvPCi2bSd1LyHHjON7jZqVb1Gdg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752864849; 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=vTV7mchOKPGOAvrE1FkrHv3nOnwG2HV4Y7IDBFMVTO8=; b=rdZnScR49CTruDGp1GnyveLwXW+wYXh28GCJ1smCI0NvnQ0apJvJhZ0C40Grf3/8sFjBID fM7F5Vat3/3m6ODQ== From: Thomas Gleixner To: LKML Cc: Liangyan , Yicong Shen , Jiri Slaby Subject: [patch 2/4] genirq: Move irq_wait_for_poll() to call site References: <20250718184935.232983339@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 18 Jul 2025 20:54:08 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move it to the call site so that the waiting for the INPROGRESS flag can be reused by an upcoming mitigation for a potential live lock in the edge type handler. No functional change. Signed-off-by: Thomas Gleixner Reviewed-by: Jiri Slaby Tested-by: Liangyan --- kernel/irq/chip.c | 29 +++++++++++++++++++++-------- kernel/irq/internals.h | 2 +- kernel/irq/spurious.c | 37 +------------------------------------ 3 files changed, 23 insertions(+), 45 deletions(-) --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -449,11 +449,19 @@ void unmask_threaded_irq(struct irq_desc unmask_irq(desc); } =20 -static bool irq_check_poll(struct irq_desc *desc) +/* Busy wait until INPROGRESS is cleared */ +static bool irq_wait_on_inprogress(struct irq_desc *desc) { - if (!(desc->istate & IRQS_POLL_INPROGRESS)) - return false; - return irq_wait_for_poll(desc); + if (IS_ENABLED(CONFIG_SMP)) { + do { + raw_spin_unlock(&desc->lock); + while (irqd_irq_inprogress(&desc->irq_data)) + cpu_relax(); + raw_spin_lock(&desc->lock); + } while (irqd_irq_inprogress(&desc->irq_data)); + } + /* Might have been disabled in meantime */ + return !irqd_irq_disabled(&desc->irq_data) && desc->action; } =20 static bool irq_can_handle_pm(struct irq_desc *desc) @@ -473,10 +481,15 @@ static bool irq_can_handle_pm(struct irq if (irq_pm_check_wakeup(desc)) return false; =20 - /* - * Handle a potential concurrent poll on a different core. - */ - return irq_check_poll(desc); + /* Check whether the interrupt is polled on another CPU */ + if (unlikely(desc->istate & IRQS_POLL_INPROGRESS)) { + if (WARN_ONCE(irq_poll_cpu =3D=3D smp_processor_id(), + "irq poll in progress on cpu %d for irq %d\n", + smp_processor_id(), desc->irq_data.irq)) + return false; + return irq_wait_on_inprogress(desc); + } + return false; } =20 static inline bool irq_can_handle_actions(struct irq_desc *desc) --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -20,6 +20,7 @@ #define istate core_internal_state__do_not_mess_with_it =20 extern bool noirqdebug; +extern int irq_poll_cpu; =20 extern struct irqaction chained_action; =20 @@ -112,7 +113,6 @@ irqreturn_t handle_irq_event(struct irq_ int check_irq_resend(struct irq_desc *desc, bool inject); void clear_irq_resend(struct irq_desc *desc); void irq_resend_init(struct irq_desc *desc); -bool irq_wait_for_poll(struct irq_desc *desc); void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action); =20 void wake_threads_waitq(struct irq_desc *desc); --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -19,45 +19,10 @@ static int irqfixup __read_mostly; #define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10) static void poll_spurious_irqs(struct timer_list *unused); static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs); -static int irq_poll_cpu; +int irq_poll_cpu; static atomic_t irq_poll_active; =20 /* - * We wait here for a poller to finish. - * - * If the poll runs on this CPU, then we yell loudly and return - * false. That will leave the interrupt line disabled in the worst - * case, but it should never happen. - * - * We wait until the poller is done and then recheck disabled and - * action (about to be disabled). Only if it's still active, we return - * true and let the handler run. - */ -bool irq_wait_for_poll(struct irq_desc *desc) -{ - lockdep_assert_held(&desc->lock); - - if (WARN_ONCE(irq_poll_cpu =3D=3D smp_processor_id(), - "irq poll in progress on cpu %d for irq %d\n", - smp_processor_id(), desc->irq_data.irq)) - return false; - -#ifdef CONFIG_SMP - do { - raw_spin_unlock(&desc->lock); - while (irqd_irq_inprogress(&desc->irq_data)) - cpu_relax(); - raw_spin_lock(&desc->lock); - } while (irqd_irq_inprogress(&desc->irq_data)); - /* Might have been disabled in meantime */ - return !irqd_irq_disabled(&desc->irq_data) && desc->action; -#else - return false; -#endif -} - - -/* * Recovery handler for misrouted interrupts. */ static bool try_one_irq(struct irq_desc *desc, bool force) From nobody Mon Oct 6 17:06:51 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94A902E8E18 for ; Fri, 18 Jul 2025 18:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864855; cv=none; b=im8piSIvqShXzf+qBISskIBglCaU70H9IhSaS9j26yJw9YfkVAI692+VG2t6/Bfzk/+R+y0RYbZZsyU6d2AoSPoiTeSM7nxyIwPXoCKnWkb3wWY0wEtURRZXnNcNny5K8fAbzKKWbv2gu6hJackmvDcheuQbKPzlzUdAQTsxQ28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864855; c=relaxed/simple; bh=2fKUlqcKzOMteLiS9jM/alObVnn4pd9v6yZCJlV7+eE=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=O+ItsNRZD1SlBkCBV06ld+Lc++wjhVrlmyWAqwVd0J8yRSj579GiJXHwWEo62Atsv5YfWk/PnVfaMOJGBdwxbuXGmL1mj3isbHXfr5jBtFbhiZbkPr7fyygqQNyNzXnUqBACVBWs7C8kkOnoHZ4n8aYhF8Ov0UBfPOxmOGBFrC8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=l9z3Lp+T; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=L1njCx6D; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="l9z3Lp+T"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="L1njCx6D" Message-ID: <20250718185312.012392426@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752864851; 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=62YA7+LLFBCjUV35wEq9c6t9DDEhYaWuSwUN6QyYWC0=; b=l9z3Lp+TYFOp7Ew3Wx0/KKUSTOxH9RYU+Esr/yOS1MrPYxDMGDGPe0Mii5JQSVRjZ/tXwB Thxq/lnig0fo0Vuws855gn7GCvh7GWeGilgeuPwvxfqJ/iy92jxhbDBOQsPDYk/9l8evH2 FYyHtur04JWYUhuCHj9qyAXfq49qg/1GlL6Toj5OgOqf+TyPcnilZEXXmeugW/c9377QIe O9bDi/0WjvsSZ0UETt3M9g8IMksUgyWeSs04JbV6Dv3V52VcXTbYZAtVLyRud8BfwT9til BoRKLKT7j7UwV38XhiPaYRLPlCZWhXUbh9zk1++31BKKdpaRKaNjX1O3InMu3g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752864851; 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=62YA7+LLFBCjUV35wEq9c6t9DDEhYaWuSwUN6QyYWC0=; b=L1njCx6DLQvlCU+G/Eh3ktOAzca8GuAOzpmrqq58fVtiUbIZ3m7hmRTOVXI0gNerRoxXiD hMAnQ3xUcLyiz8Cg== From: Thomas Gleixner To: LKML Cc: Liangyan , Yicong Shen , Jiri Slaby Subject: [patch 3/4] genirq: Split up irq_pm_check_wakeup() References: <20250718184935.232983339@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 18 Jul 2025 20:54:10 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Let the calling code check for the IRQD_WAKEUP_ARMED flag to prepare for a live lock mitigation in the edge type handler. No functional change. Signed-off-by: Thomas Gleixner Tested-by: Liangyan --- kernel/irq/chip.c | 4 +++- kernel/irq/internals.h | 4 ++-- kernel/irq/pm.c | 16 ++++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -478,8 +478,10 @@ static bool irq_can_handle_pm(struct irq * and suspended, disable it and notify the pm core about the * event. */ - if (irq_pm_check_wakeup(desc)) + if (unlikely(irqd_has_set(irqd, IRQD_WAKEUP_ARMED))) { + irq_pm_handle_wakeup(desc); return false; + } =20 /* Check whether the interrupt is polled on another CPU */ if (unlikely(desc->istate & IRQS_POLL_INPROGRESS)) { --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -277,11 +277,11 @@ static inline bool irq_is_nmi(struct irq } =20 #ifdef CONFIG_PM_SLEEP -bool irq_pm_check_wakeup(struct irq_desc *desc); +void irq_pm_handle_wakeup(struct irq_desc *desc); void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action= ); void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action); #else -static inline bool irq_pm_check_wakeup(struct irq_desc *desc) { return fal= se; } +static inline void irq_pm_handle_wakeup(struct irq_desc *desc) { } static inline void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action) { } static inline void --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -13,17 +13,13 @@ =20 #include "internals.h" =20 -bool irq_pm_check_wakeup(struct irq_desc *desc) +void irq_pm_handle_wakeup(struct irq_desc *desc) { - if (irqd_is_wakeup_armed(&desc->irq_data)) { - irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED); - desc->istate |=3D IRQS_SUSPENDED | IRQS_PENDING; - desc->depth++; - irq_disable(desc); - pm_system_irq_wakeup(irq_desc_get_irq(desc)); - return true; - } - return false; + irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED); + desc->istate |=3D IRQS_SUSPENDED | IRQS_PENDING; + desc->depth++; + irq_disable(desc); + pm_system_irq_wakeup(irq_desc_get_irq(desc)); } =20 /* From nobody Mon Oct 6 17:06:51 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 990DF2E92BE for ; Fri, 18 Jul 2025 18:54:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864856; cv=none; b=m+yDe5zLmKPKM5vUq8NdHps7Q0Hz19t+cnh9cqigbBLb1Nw4dC9+76TqQ6i3Jzl4PIqGrFMl+nJCBjHfGFA6IqW9A/7He87TuBIgmoNgNcoY7Xe1OWle3RVv/7XoHDTPsv936EkmSDC18Qpz9NDpBsotbUqsKkQGbRObBByJOeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752864856; c=relaxed/simple; bh=JhaLq7EtVnvmLRiDgpWvSg/8I9R2kuRMq2Qr5Aa677U=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=D+4LsKgUocpWbQVvyjCZ0WDiYyfBS/sjvM9hgL3C51lmB4W3OaWxhSGL4Vnhr2pcQ/ECZN3Cxb7TBPFHUgGot8CF68qNgQnphTuwPzyyPvVj4hHTRMJfWyDJNitHK4ZwLCPS3UeDgsQEEuudR5T0fR4LBahlJg24H9gnZUfEK0M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=cqYYLwk3; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=yIU+PHDe; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="cqYYLwk3"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="yIU+PHDe" Message-ID: <20250718185312.076515034@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752864853; 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=hYxI10KY8qBh1psNMaH8hIt4/i563oOZ80VHzpgsya8=; b=cqYYLwk3IDIfTlCEXQN7ROipNRBLd4NBdA80H4zb/QOHqgR4TA89yoTuqIDMUr6wyHqYFO VTV88p5kU0w9C4Iiv+Q5jiDG73qAT9QM69gZhOXMhfo72FesUi9Hjuw/zrvL+ruNaXZLyx PbFXu37NXpUpSt6EUy5Nx5K3v94lvKdytTJ/XnPxCA/kSlhgokH48/rPkgfyX9J1kBA347 E7nxkWeiifZu7OqWNInTHPqlMzhGMOkyHeNDYI0f/qIfVfM10mmK0Yp5sOtVR4o483n8KU jddw2aajk6VHrWn3nvqaT94/P/hkGq80rXjM3ypIA582aM8eqqpUj2kJPsCdfg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752864853; 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=hYxI10KY8qBh1psNMaH8hIt4/i563oOZ80VHzpgsya8=; b=yIU+PHDehE+jHZrNzIJtaCvLvrMk7lOwsuWNWPbsoqwLqTgGlVkwuDmn+0iZxqwm3U28ga py7C+pLquXvE4vAg== From: Thomas Gleixner To: LKML Cc: Liangyan , Yicong Shen , Jiri Slaby Subject: [patch 4/4] genirq: Prevent migration live lock in handle_edge_irq() References: <20250718184935.232983339@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 18 Jul 2025 20:54:12 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Yicon reported and Liangyan debugged a live lock in handle_edge_irq() related to interrupt migration. If the interrupt affinity is moved to a new target CPU and the interrupt is currently handled on the previous target CPU for edge type interrupts the handler might get stuck on the previous target: CPU 0 (previous target) CPU 1 (new target) handle_edge_irq() repeat: handle_event() handle_edge_irq() if (INPROGESS) { set(PENDING); mask(); return; } if (PENDING) { clear(PENDING); unmask(); goto repeat; } The migration in software never completes and CPU0 continues to handle the pending events forever. This happens when the device raises interrupts with a high rate and always before handle_event() completes and before the CPU0 handler can clear INPROGRESS so that CPU1 sets the PENDING flag over and over. This has been observed in virtual machines. Prevent this by checking whether the CPU which observes the INPROGRESS flag is the new affinity target. If that's the case, do not set the PENDING flag and wait for the INPROGRESS flag to be cleared instead, so that the new interrupt is handled on the new target CPU and the previous CPU is released from the action. This is restricted to the edge type handler and only utilized on systems, which use single CPU targets for interrupt affinity. Reported-by: Yicong Shen Reported-by: Liangyan Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250701163558.2588435-1-liangyan.peng@by= tedance.com Reviewed-by: Jiri Slaby Tested-by: Liangyan --- kernel/irq/chip.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -466,11 +466,14 @@ static bool irq_wait_on_inprogress(struc =20 static bool irq_can_handle_pm(struct irq_desc *desc) { + struct irq_data *irqd =3D &desc->irq_data; + const struct cpumask *aff; + /* * If the interrupt is not in progress and is not an armed * wakeup interrupt, proceed. */ - if (!irqd_has_set(&desc->irq_data, IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARME= D)) + if (!irqd_has_set(irqd, IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARMED)) return true; =20 /* @@ -491,7 +494,41 @@ static bool irq_can_handle_pm(struct irq return false; return irq_wait_on_inprogress(desc); } - return false; + + /* The below works only for single target interrupts */ + if (!IS_ENABLED(CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK) || + !irqd_is_single_target(irqd) || desc->handle_irq !=3D handle_edge_irq) + return false; + + /* + * If the interrupt affinity was moved to this CPU and the + * interrupt is currently handled on the previous target CPU, then + * busy wait for INPROGRESS to be cleared. Otherwise for edge type + * interrupts the handler might get stuck on the previous target: + * + * CPU 0 CPU 1 (new target) + * handle_edge_irq() + * repeat: + * handle_event() handle_edge_irq() + * if (INPROGESS) { + * set(PENDING); + * mask(); + * return; + * } + * if (PENDING) { + * clear(PENDING); + * unmask(); + * goto repeat; + * } + * + * This happens when the device raises interrupts with a high rate + * and always before handle_event() completes and the CPU0 handler + * can clear INPROGRESS. This has been observed in virtual machines. + */ + aff =3D irq_data_get_effective_affinity_mask(irqd); + if (cpumask_first(aff) !=3D smp_processor_id()) + return false; + return irq_wait_on_inprogress(desc); } =20 static inline bool irq_can_handle_actions(struct irq_desc *desc)