linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] irq: Resolve that mask_irq/unmask_irq may not be called in pairs
@ 2023-12-07  1:40 xiongxin
  2023-12-08 13:52 ` Thomas Gleixner
  0 siblings, 1 reply; 13+ messages in thread
From: xiongxin @ 2023-12-07  1:40 UTC (permalink / raw)
  To: tglx, jikos, benjamin.tissoires; +Cc: linux-input, xiongxin, stable, Riwen Lu

When an interrupt controller uses a function such as handle_level_irq()
as an interrupt handler and the controller implements the irq_disable()
callback, the following scenario will appear in the i2c-hid driver in
the sleep scenario:

in the sleep flow, while the user is still triggering the i2c-hid
interrupt, we get the following function call:

  handle_level_irq()
    -> mask_ack_irq()
      -> mask_irq()
				i2c_hid_core_suspend()
				  -> disable_irq()
				    -> __irq_disable()
				      -> irq_state_set_disabled()
				      -> irq_state_set_masked()

  irq_thread_fn()
    -> irq_finalize_oneshot()
      -> if (!desc->threads_oneshot && !irqd_irq_disabled() &&
	     irqd_irq_masked())
      	 	unmask_threaded_irq()
		  -> unmask_irq()

That is, when __irq_disable() is called between mask_irq() and
irq_finalize_oneshot(), the code in irq_finalize_oneshot() will cause
the !irqd_irq_disabled() fails to enter the unmask_irq() branch, which
causes mask_irq/unmask_irq to be called unpaired and the i2c-hid
interrupt to be masked.

Since mask_irq/unmask_irq and irq_disabled() belong to two different
hardware registers or policies, the !irqd_irq_disabled() assertion may
not be used to determine whether unmask_irq() needs to be called.

Cc: stable@vger.kernel.org
Signed-off-by: xiongxin <xiongxin@kylinos.cn>
Signed-off-by: Riwen Lu <luriwen@kylinos.cn>

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1782f90cd8c6..9160fc9170b3 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1120,8 +1120,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
 
 	desc->threads_oneshot &= ~action->thread_mask;
 
-	if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
-	    irqd_irq_masked(&desc->irq_data))
+	if (!desc->threads_oneshot && irqd_irq_masked(&desc->irq_data))
 		unmask_threaded_irq(desc);
 
 out_unlock:
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-12-15  2:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-07  1:40 [PATCH] irq: Resolve that mask_irq/unmask_irq may not be called in pairs xiongxin
2023-12-08 13:52 ` Thomas Gleixner
2023-12-11  3:10   ` xiongxin
2023-12-12 15:17     ` Thomas Gleixner
2023-12-13  2:29       ` xiongxin
2023-12-13 14:59         ` Thomas Gleixner
2023-12-14  1:54           ` xiongxin
2023-12-14 10:06             ` Serge Semin
2023-12-14 16:11               ` Andy Shevchenko
2023-12-15  2:18                 ` xiongxin
2023-12-14 10:13             ` Thomas Gleixner
2023-12-12 16:57     ` Jiri Kosina
     [not found]     ` <1702429454313015.485.seg@mailgw>
2023-12-13  2:35       ` xiongxin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).