This allow us to collect AER events via generic tracing framework like mce_record event. Signed-off-by: Hidetoshi Seto <seto.hidetoshi@xxxxxxxxxxxxxx> --- drivers/pci/pcie/aer/aerdrv_core.c | 10 +++++- include/trace/events/pcie_aer.h | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletions(-) create mode 100644 include/trace/events/pcie_aer.h diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 09e61ca..8c1de83 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -25,6 +25,9 @@ #include <linux/delay.h> #include "aerdrv.h" +#define CREATE_TRACE_POINTS +#include <trace/events/pcie_aer.h> + static int forceload; static int nosourceid; module_param(forceload, bool, 0); @@ -652,6 +655,8 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) int pos, temp; info->status = 0; + info->mask = 0; + info->first_error = 0; info->tlp_header_valid = 0; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); @@ -708,8 +713,11 @@ static inline void aer_process_err_devices(struct pcie_device *p_device, /* Report all before handle them, not to lost records by reset etc. */ for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) { - if (get_device_error_info(e_info->dev[i], e_info)) + if (get_device_error_info(e_info->dev[i], e_info)) { aer_print_error(e_info->dev[i], e_info); + /* Emit the trace record */ + trace_aer_record(e_info->dev[i], e_info); + } } /* diff --git a/include/trace/events/pcie_aer.h b/include/trace/events/pcie_aer.h new file mode 100644 index 0000000..d1d6497 --- /dev/null +++ b/include/trace/events/pcie_aer.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM pcie_aer + +#if !defined(_TRACE_PCIE_AER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PCIE_AER_H + +#include <linux/tracepoint.h> + +#define aer_severity_string \ + { AER_CORRECTABLE, "ERR_COR" }, \ + { AER_NONFATAL, "ERR_NONFATAL" }, \ + { AER_FATAL, "ERR_FATAL" } + +#define aer_form_header(ent, dw0) \ +do { \ + char *c = (unsigned char *)dw0; \ + sprintf(ent, "%02x%02x%02x%02x %02x%02x%02x%02x " \ + "%02x%02x%02x%02x %02x%02x%02x%02x", \ + *(c + 3), *(c + 2), *(c + 1), *c, \ + *(c + 7), *(c + 6), *(c + 5), *(c + 4), \ + *(c + 11), *(c + 10), *(c + 9), *(c + 8), \ + *(c + 15), *(c + 14), *(c + 13), *(c + 12)); \ +} while (0) + + +TRACE_EVENT(aer_record, + + TP_PROTO(struct pci_dev *pdev, struct aer_err_info *e_info), + + TP_ARGS(pdev, e_info), + + TP_STRUCT__entry( + __field( u32, status ) + __field( u32, mask ) + __field( u8, severity ) + __field( u8, fep ) + __field( bool, hdr_valid ) + __string( dstr, dev_driver_string(&pdev->dev) ) + __string( name, dev_name(&pdev->dev) ) + __dynamic_array(char, hdr, (e_info->tlp_header_valid ? 40 : 0)) + ), + + TP_fast_assign( + __entry->status = e_info->status; + __entry->mask = e_info->mask; + __entry->severity = e_info->severity; + __entry->fep = e_info->first_error; + __entry->hdr_valid = e_info->tlp_header_valid; + + __assign_str(dstr, dev_driver_string(&pdev->dev)); + __assign_str(name, dev_name(&pdev->dev)); + + if (e_info->tlp_header_valid) + aer_form_header(__get_str(hdr), &e_info->tlp.dw0); + ), + + TP_printk("%s %s: %s status/mask=%08xh/%08xh fep=%d, header=%s", + __get_str(dstr), __get_str(name), + __print_symbolic(__entry->severity, aer_severity_string), + __entry->status, __entry->mask, __entry->fep, + __entry->hdr_valid ? __get_str(hdr) : "<not available>" + ) +); + +#endif /* _TRACE_PCIE_AER_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html