Blob Blame History Raw
commit 3ff0e97a1bc3059bfbcc1d864c5d4ff5f8d3c2b9
Author: Neil Horman <nhorman@tuxdriver.com>
Date:   Tue Jan 3 10:17:21 2012 -0500

    msi: fix imbalanced refcount of msi irq sysfs objects
    
    This warning was recently reported to me:
    
    ------------[ cut here ]------------
    WARNING: at lib/kobject.c:595 kobject_put+0x50/0x60()
    Hardware name: VMware Virtual Platform
    kobject: '(null)' (ffff880027b0df40): is not initialized, yet kobject_put() is
    being called.
    Modules linked in: vmxnet3(+) vmw_balloon i2c_piix4 i2c_core shpchp raid10
    vmw_pvscsi
    Pid: 630, comm: modprobe Tainted: G        W   3.1.6-1.fc16.x86_64 #1
    Call Trace:
     [<ffffffff8106b73f>] warn_slowpath_common+0x7f/0xc0
     [<ffffffff8106b836>] warn_slowpath_fmt+0x46/0x50
     [<ffffffff810da293>] ? free_desc+0x63/0x70
     [<ffffffff812a9aa0>] kobject_put+0x50/0x60
     [<ffffffff812e4c25>] free_msi_irqs+0xd5/0x120
     [<ffffffff812e524c>] pci_enable_msi_block+0x24c/0x2c0
     [<ffffffffa017c273>] vmxnet3_alloc_intr_resources+0x173/0x240 [vmxnet3]
     [<ffffffffa0182e94>] vmxnet3_probe_device+0x615/0x834 [vmxnet3]
     [<ffffffff812d141c>] local_pci_probe+0x5c/0xd0
     [<ffffffff812d2cb9>] pci_device_probe+0x109/0x130
     [<ffffffff8138ba2c>] driver_probe_device+0x9c/0x2b0
     [<ffffffff8138bceb>] __driver_attach+0xab/0xb0
     [<ffffffff8138bc40>] ? driver_probe_device+0x2b0/0x2b0
     [<ffffffff8138bc40>] ? driver_probe_device+0x2b0/0x2b0
     [<ffffffff8138a8ac>] bus_for_each_dev+0x5c/0x90
     [<ffffffff8138b63e>] driver_attach+0x1e/0x20
     [<ffffffff8138b240>] bus_add_driver+0x1b0/0x2a0
     [<ffffffffa0188000>] ? 0xffffffffa0187fff
     [<ffffffff8138c246>] driver_register+0x76/0x140
     [<ffffffff815ca414>] ? printk+0x51/0x53
     [<ffffffffa0188000>] ? 0xffffffffa0187fff
     [<ffffffff812d2996>] __pci_register_driver+0x56/0xd0
     [<ffffffffa018803a>] vmxnet3_init_module+0x3a/0x3c [vmxnet3]
     [<ffffffff81002042>] do_one_initcall+0x42/0x180
     [<ffffffff810aad71>] sys_init_module+0x91/0x200
     [<ffffffff815dccc2>] system_call_fastpath+0x16/0x1b
    ---[ end trace 44593438a59a9558 ]---
    Using INTx interrupt, #Rx queues: 1.
    
    It occurs when populate_msi_sysfs fails, which in turn causes free_msi_irqs to
    be called.  Because populate_msi_sysfs fails, we never registered any of the
    msi irq sysfs objects, but free_msi_irqs still calls kobject_del and kobject_put
    on each of them, which gets flagged in the above stack trace.
    
    The fix is pretty straightforward.  We can key of the parent pointer in the
    kobject.  It is only set if the kobject_init_and_add succededs in
    populate_msi_sysfs.  If anything fails there, each kobject has its parent reset
    to NULL
    
    Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
    CC: Jesse Barnes <jbarnes@virtuousgeek.org>
    CC: Bjorn Helgaas <bhelgaas@google.com>
    CC: Greg Kroah-Hartman <gregkh@suse.de>
    CC: linux-pci@vger.kernel.org

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 337e16a..82de95e 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -323,8 +323,18 @@ static void free_msi_irqs(struct pci_dev *dev)
 			if (list_is_last(&entry->list, &dev->msi_list))
 				iounmap(entry->mask_base);
 		}
-		kobject_del(&entry->kobj);
-		kobject_put(&entry->kobj);
+
+		/*
+		 * Its possible that we get into this path
+		 * When populate_msi_sysfs fails, which means the entries
+		 * were not registered with sysfs.  In that case don't
+		 * unregister them.
+		 */
+		if (entry->kobj.parent) {
+			kobject_del(&entry->kobj);
+			kobject_put(&entry->kobj);
+		}
+
 		list_del(&entry->list);
 		kfree(entry);
 	}