diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-07-24 04:25:01 +0200 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-07-24 06:18:49 +0200 |
commit | ab55d2187da27414f78056810713c92f9a4350c2 (patch) | |
tree | 49df4aa27f4e6b946ef1c7e892478502a9d7bee6 /arch/powerpc/kernel/eeh_sysfs.c | |
parent | powerpc/eeh: Fix unbalanced enable for IRQ (diff) | |
download | linux-ab55d2187da27414f78056810713c92f9a4350c2.tar.xz linux-ab55d2187da27414f78056810713c92f9a4350c2.zip |
powerpc/eeh: Introdce flag to protect sysfs
The patch introduces flag EEH_DEV_SYSFS to keep track that the sysfs
entries for the corresponding EEH device (then PCI device) has been
added or removed, in order to avoid race condition.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/eeh_sysfs.c')
-rw-r--r-- | arch/powerpc/kernel/eeh_sysfs.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 61e2a1452131..5d753d4f2c75 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c @@ -56,26 +56,40 @@ EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); void eeh_sysfs_add_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); int rc=0; + if (edev && (edev->mode & EEH_DEV_SYSFS)) + return; + rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); if (rc) printk(KERN_WARNING "EEH: Unable to create sysfs entries\n"); + else if (edev) + edev->mode |= EEH_DEV_SYSFS; } void eeh_sysfs_remove_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); + /* * The parent directory might have been removed. We needn't * continue for that case. */ - if (!pdev->dev.kobj.sd) + if (!pdev->dev.kobj.sd) { + if (edev) + edev->mode &= ~EEH_DEV_SYSFS; return; + } device_remove_file(&pdev->dev, &dev_attr_eeh_mode); device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); + + if (edev) + edev->mode &= ~EEH_DEV_SYSFS; } |