Patch "genirq/irqdesc: Don't try to remove non-existing sysfs files" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    genirq/irqdesc: Don't try to remove non-existing sysfs files

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     genirq-irqdesc-don-t-try-to-remove-non-existing-sysf.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 7cd82bcf0363301104766cb4d0e0fbab89d6202c
Author: Yang Yingliang <yangyingliang@xxxxxxxxxx>
Date:   Mon Nov 28 23:16:12 2022 +0800

    genirq/irqdesc: Don't try to remove non-existing sysfs files
    
    [ Upstream commit 9049e1ca41983ab773d7ea244bee86d7835ec9f5 ]
    
    Fault injection tests trigger warnings like this:
    
      kernfs: can not remove 'chip_name', no directory
      WARNING: CPU: 0 PID: 253 at fs/kernfs/dir.c:1616 kernfs_remove_by_name_ns+0xce/0xe0
      RIP: 0010:kernfs_remove_by_name_ns+0xce/0xe0
      Call Trace:
       <TASK>
       remove_files.isra.1+0x3f/0xb0
       sysfs_remove_group+0x68/0xe0
       sysfs_remove_groups+0x41/0x70
       __kobject_del+0x45/0xc0
       kobject_del+0x29/0x40
       free_desc+0x42/0x70
       irq_free_descs+0x5e/0x90
    
    The reason is that the interrupt descriptor sysfs handling does not roll
    back on a failing kobject_add() during allocation. If the descriptor is
    freed later on, kobject_del() is invoked with a not added kobject resulting
    in the above warnings.
    
    A proper rollback in case of a kobject_add() failure would be the straight
    forward solution. But this is not possible due to the way how interrupt
    descriptor sysfs handling works.
    
    Interrupt descriptors are allocated before sysfs becomes available. So the
    sysfs files for the early allocated descriptors are added later in the boot
    process. At this point there can be nothing useful done about a failing
    kobject_add(). For consistency the interrupt descriptor allocation always
    treats kobject_add() failures as non-critical and just emits a warning.
    
    To solve this problem, keep track in the interrupt descriptor whether
    kobject_add() was successful or not and make the invocation of
    kobject_del() conditional on that.
    
    [ tglx: Massage changelog, comments and use a state bit. ]
    
    Fixes: ecb3f394c5db ("genirq: Expose interrupt information through sysfs")
    Signed-off-by: Yang Yingliang <yangyingliang@xxxxxxxxxx>
    Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
    Reviewed-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20221128151612.1786122-1-yangyingliang@xxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index e58342ace11f..f1d83a8b4417 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -52,6 +52,7 @@ enum {
  * IRQS_PENDING			- irq is pending and replayed later
  * IRQS_SUSPENDED		- irq is suspended
  * IRQS_NMI			- irq line is used to deliver NMIs
+ * IRQS_SYSFS			- descriptor has been added to sysfs
  */
 enum {
 	IRQS_AUTODETECT		= 0x00000001,
@@ -64,6 +65,7 @@ enum {
 	IRQS_SUSPENDED		= 0x00000800,
 	IRQS_TIMINGS		= 0x00001000,
 	IRQS_NMI		= 0x00002000,
+	IRQS_SYSFS		= 0x00004000,
 };
 
 #include "debug.h"
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index ca36c6179aa7..9b0914a063f9 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -288,22 +288,25 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc)
 	if (irq_kobj_base) {
 		/*
 		 * Continue even in case of failure as this is nothing
-		 * crucial.
+		 * crucial and failures in the late irq_sysfs_init()
+		 * cannot be rolled back.
 		 */
 		if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
 			pr_warn("Failed to add kobject for irq %d\n", irq);
+		else
+			desc->istate |= IRQS_SYSFS;
 	}
 }
 
 static void irq_sysfs_del(struct irq_desc *desc)
 {
 	/*
-	 * If irq_sysfs_init() has not yet been invoked (early boot), then
-	 * irq_kobj_base is NULL and the descriptor was never added.
-	 * kobject_del() complains about a object with no parent, so make
-	 * it conditional.
+	 * Only invoke kobject_del() when kobject_add() was successfully
+	 * invoked for the descriptor. This covers both early boot, where
+	 * sysfs is not initialized yet, and the case of a failed
+	 * kobject_add() invocation.
 	 */
-	if (irq_kobj_base)
+	if (desc->istate & IRQS_SYSFS)
 		kobject_del(&desc->kobj);
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux