Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/pci: Add pci_msg debug view to PCI report

Using the newly introduced debug_dump() mechanism add formatted content
of pci_debug_msg_id to the PCI report. The formatting is based on the
existing sprintf format but removes caller pointer and area index and
adds an column header. This will allow the platform to collect this log
data together with hardware errors. This sets the reverse flag such that
the newest log entries get added to the PCI report even if not all debug
log entries fit.

Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Co-developed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Niklas Schnelle and committed by
Alexander Gordeev
4c41a48f dc18c81a

+54 -5
+4
arch/s390/include/asm/debug.h
··· 85 85 int area, debug_entry_t *entry, 86 86 char *out_buf, size_t out_buf_size); 87 87 88 + #define DEBUG_SPRINTF_MAX_ARGS 10 89 + int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 90 + char *out_buf, size_t out_buf_size, 91 + const char *inbuf); 88 92 struct debug_view { 89 93 char name[DEBUG_MAX_NAME_LEN]; 90 94 debug_prolog_proc_t *prolog_proc;
+3 -5
arch/s390/kernel/debug.c
··· 95 95 static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, 96 96 char *out_buf, size_t out_buf_size, 97 97 const char *in_buf); 98 - static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 99 - char *out_buf, size_t out_buf_size, 100 - const char *inbuf); 101 98 static void debug_areas_swap(debug_info_t *a, debug_info_t *b); 102 99 static void debug_events_append(debug_info_t *dest, debug_info_t *src); 103 100 ··· 1682 1685 1683 1686 #define DEBUG_SPRINTF_MAX_ARGS 10 1684 1687 1685 - static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 1686 - char *out_buf, size_t out_buf_size, const char *inbuf) 1688 + int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 1689 + char *out_buf, size_t out_buf_size, const char *inbuf) 1687 1690 { 1688 1691 debug_sprintf_entry_t *curr_event = (debug_sprintf_entry_t *)inbuf; 1689 1692 int num_longs, num_used_args = 0, i, rc = 0; ··· 1720 1723 out: 1721 1724 return rc; 1722 1725 } 1726 + EXPORT_SYMBOL(debug_sprintf_format_fn); 1723 1727 1724 1728 /* 1725 1729 * debug_init:
+47
arch/s390/pci/pci_report.c
··· 15 15 #include <linux/pci.h> 16 16 17 17 #include <asm/sclp.h> 18 + #include <asm/debug.h> 19 + #include <asm/pci_debug.h> 18 20 19 21 #include "pci_report.h" 20 22 ··· 50 48 }; 51 49 } 52 50 51 + static int debug_log_header_fn(debug_info_t *id, struct debug_view *view, 52 + int area, debug_entry_t *entry, char *out_buf, 53 + size_t out_buf_size) 54 + { 55 + unsigned long sec, usec; 56 + unsigned int level; 57 + char *except_str; 58 + int rc = 0; 59 + 60 + level = entry->level; 61 + sec = entry->clock; 62 + usec = do_div(sec, USEC_PER_SEC); 63 + 64 + if (entry->exception) 65 + except_str = "*"; 66 + else 67 + except_str = "-"; 68 + rc += scnprintf(out_buf, out_buf_size, "%011ld:%06lu %1u %1s %04u ", 69 + sec, usec, level, except_str, 70 + entry->cpu); 71 + return rc; 72 + } 73 + 74 + static int debug_prolog_header(debug_info_t *id, struct debug_view *view, 75 + char *out_buf, size_t out_buf_size) 76 + { 77 + return scnprintf(out_buf, out_buf_size, "sec:usec level except cpu msg\n"); 78 + } 79 + 80 + static struct debug_view debug_log_view = { 81 + "pci_msg_log", 82 + &debug_prolog_header, 83 + &debug_log_header_fn, 84 + &debug_sprintf_format_fn, 85 + NULL, 86 + NULL 87 + }; 88 + 53 89 /** 54 90 * zpci_report_status - Report the status of operations on a PCI device 55 91 * @zdev: The PCI device for which to report status ··· 99 59 * Event Data mechanism. Besides the operation and status strings the report 100 60 * also contains additional information about the device deemed useful for 101 61 * debug such as the currently bound device driver, if any, and error state. 62 + * Additionally a string representation of pci_debug_msg_id, or as much as fits, 63 + * is also included. 102 64 * 103 65 * Return: 0 on success an error code < 0 otherwise. 104 66 */ ··· 134 92 buf += scnprintf(buf, end - buf, "state: %s\n", 135 93 (pdev) ? zpci_state_str(pdev->error_state) : "n/a"); 136 94 buf += scnprintf(buf, end - buf, "driver: %s\n", (driver) ? driver->name : "n/a"); 95 + ret = debug_dump(pci_debug_msg_id, &debug_log_view, buf, end - buf, true); 96 + if (ret < 0) 97 + pr_err("Reading PCI debug messages failed with code %d\n", ret); 98 + else 99 + buf += ret; 137 100 138 101 report->header.version = 1; 139 102 report->header.action = SCLP_ERRNOTIFY_AQ_INFO_LOG;