Commit e575f8db authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Introduce struct eeh_stats for EEH

With the original EEH implementation, the EEH global statistics
are maintained by individual global variables. That makes the
code a little hard to maintain.

The patch introduces extra struct eeh_stats for the EEH global
statistics so that it can be maintained in collective fashion.

It's the rework on the corresponding v5 patch. According to
the comments from David Laight, the EEH global statistics have
been changed for a litte bit so that they have fixed-type of
"u64". Also, the format used to print them has been changed to
"%llu" based on David's suggestion. Also, the output format of
EEH global statistics should be kept as intacted according to
Michael's suggestion that there might be tools parsing them.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 54793d0e
...@@ -102,14 +102,22 @@ static DEFINE_RAW_SPINLOCK(confirm_error_lock); ...@@ -102,14 +102,22 @@ static DEFINE_RAW_SPINLOCK(confirm_error_lock);
#define EEH_PCI_REGS_LOG_LEN 4096 #define EEH_PCI_REGS_LOG_LEN 4096
static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN]; static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN];
/* System monitoring statistics */ /*
static unsigned long no_device; * The struct is used to maintain the EEH global statistic
static unsigned long no_dn; * information. Besides, the EEH global statistics will be
static unsigned long no_cfg_addr; * exported to user space through procfs
static unsigned long ignored_check; */
static unsigned long total_mmio_ffs; struct eeh_stats {
static unsigned long false_positives; u64 no_device; /* PCI device not found */
static unsigned long slot_resets; u64 no_dn; /* OF node not found */
u64 no_cfg_addr; /* Config address not found */
u64 ignored_check; /* EEH check skipped */
u64 total_mmio_ffs; /* Total EEH checks */
u64 false_positives; /* Unnecessary EEH checks */
u64 slot_resets; /* PE reset */
};
static struct eeh_stats eeh_stats;
#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) #define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
...@@ -392,13 +400,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -392,13 +400,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
int rc = 0; int rc = 0;
const char *location; const char *location;
total_mmio_ffs++; eeh_stats.total_mmio_ffs++;
if (!eeh_subsystem_enabled) if (!eeh_subsystem_enabled)
return 0; return 0;
if (!dn) { if (!dn) {
no_dn++; eeh_stats.no_dn++;
return 0; return 0;
} }
dn = eeh_find_device_pe(dn); dn = eeh_find_device_pe(dn);
...@@ -407,14 +415,14 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -407,14 +415,14 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
/* Access to IO BARs might get this far and still not want checking. */ /* Access to IO BARs might get this far and still not want checking. */
if (!(edev->mode & EEH_MODE_SUPPORTED) || if (!(edev->mode & EEH_MODE_SUPPORTED) ||
edev->mode & EEH_MODE_NOCHECK) { edev->mode & EEH_MODE_NOCHECK) {
ignored_check++; eeh_stats.ignored_check++;
pr_debug("EEH: Ignored check (%x) for %s %s\n", pr_debug("EEH: Ignored check (%x) for %s %s\n",
edev->mode, eeh_pci_name(dev), dn->full_name); edev->mode, eeh_pci_name(dev), dn->full_name);
return 0; return 0;
} }
if (!edev->config_addr && !edev->pe_config_addr) { if (!edev->config_addr && !edev->pe_config_addr) {
no_cfg_addr++; eeh_stats.no_cfg_addr++;
return 0; return 0;
} }
...@@ -460,13 +468,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -460,13 +468,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
(ret == EEH_STATE_NOT_SUPPORT) || (ret == EEH_STATE_NOT_SUPPORT) ||
(ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) == (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) ==
(EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) { (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) {
false_positives++; eeh_stats.false_positives++;
edev->false_positives ++; edev->false_positives ++;
rc = 0; rc = 0;
goto dn_unlock; goto dn_unlock;
} }
slot_resets++; eeh_stats.slot_resets++;
/* Avoid repeated reports of this failure, including problems /* Avoid repeated reports of this failure, including problems
* with other functions on this device, and functions under * with other functions on this device, and functions under
...@@ -513,7 +521,7 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon ...@@ -513,7 +521,7 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
addr = eeh_token_to_phys((unsigned long __force) token); addr = eeh_token_to_phys((unsigned long __force) token);
dev = pci_addr_cache_get_device(addr); dev = pci_addr_cache_get_device(addr);
if (!dev) { if (!dev) {
no_device++; eeh_stats.no_device++;
return val; return val;
} }
...@@ -1174,21 +1182,24 @@ static int proc_eeh_show(struct seq_file *m, void *v) ...@@ -1174,21 +1182,24 @@ static int proc_eeh_show(struct seq_file *m, void *v)
{ {
if (0 == eeh_subsystem_enabled) { if (0 == eeh_subsystem_enabled) {
seq_printf(m, "EEH Subsystem is globally disabled\n"); seq_printf(m, "EEH Subsystem is globally disabled\n");
seq_printf(m, "eeh_total_mmio_ffs=%ld\n", total_mmio_ffs); seq_printf(m, "eeh_total_mmio_ffs=%llu\n", eeh_stats.total_mmio_ffs);
} else { } else {
seq_printf(m, "EEH Subsystem is enabled\n"); seq_printf(m, "EEH Subsystem is enabled\n");
seq_printf(m, seq_printf(m,
"no device=%ld\n" "no device=%llu\n"
"no device node=%ld\n" "no device node=%llu\n"
"no config address=%ld\n" "no config address=%llu\n"
"check not wanted=%ld\n" "check not wanted=%llu\n"
"eeh_total_mmio_ffs=%ld\n" "eeh_total_mmio_ffs=%llu\n"
"eeh_false_positives=%ld\n" "eeh_false_positives=%llu\n"
"eeh_slot_resets=%ld\n", "eeh_slot_resets=%llu\n",
no_device, no_dn, no_cfg_addr, eeh_stats.no_device,
ignored_check, total_mmio_ffs, eeh_stats.no_dn,
false_positives, eeh_stats.no_cfg_addr,
slot_resets); eeh_stats.ignored_check,
eeh_stats.total_mmio_ffs,
eeh_stats.false_positives,
eeh_stats.slot_resets);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment