summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/eeh_sysfs.c
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-07-24 10:25:01 +0800
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-07-24 14:18:49 +1000
commitab55d2187da27414f78056810713c92f9a4350c2 (patch)
tree49df4aa27f4e6b946ef1c7e892478502a9d7bee6 /arch/powerpc/kernel/eeh_sysfs.c
parent91150af3adf67463c4ca7d72d4fe1a84da37792c (diff)
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.c16
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;
}