diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 08:49:10 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 08:49:10 -0500 |
commit | 7c3c867f8d044c539ab577f2d134054099d0e0bf (patch) | |
tree | fd4a5f153ee69456780b737eb080daa2bb1b827f /drivers/pci/pcie/aer | |
parent | 2a1337599b0b5629d3ff163f803659f658bb4a14 (diff) | |
parent | 2cced2d95961acd318e9395578a60ee424d9db80 (diff) |
Merge tag 'please-pull-aer-trace' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras into perf/core
Use perf/event tracing to report PCI Express advanced errors, by
Tony Luck.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/pci/pcie/aer')
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_errprint.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 3ea51736f18d..5ab14251839d 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -23,6 +23,9 @@ | |||
23 | 23 | ||
24 | #include "aerdrv.h" | 24 | #include "aerdrv.h" |
25 | 25 | ||
26 | #define CREATE_TRACE_POINTS | ||
27 | #include <trace/events/ras.h> | ||
28 | |||
26 | #define AER_AGENT_RECEIVER 0 | 29 | #define AER_AGENT_RECEIVER 0 |
27 | #define AER_AGENT_REQUESTER 1 | 30 | #define AER_AGENT_REQUESTER 1 |
28 | #define AER_AGENT_COMPLETER 2 | 31 | #define AER_AGENT_COMPLETER 2 |
@@ -121,12 +124,11 @@ static const char *aer_agent_string[] = { | |||
121 | "Transmitter ID" | 124 | "Transmitter ID" |
122 | }; | 125 | }; |
123 | 126 | ||
124 | static void __aer_print_error(const char *prefix, | 127 | static void __aer_print_error(struct pci_dev *dev, |
125 | struct aer_err_info *info) | 128 | struct aer_err_info *info) |
126 | { | 129 | { |
127 | int i, status; | 130 | int i, status; |
128 | const char *errmsg = NULL; | 131 | const char *errmsg = NULL; |
129 | |||
130 | status = (info->status & ~info->mask); | 132 | status = (info->status & ~info->mask); |
131 | 133 | ||
132 | for (i = 0; i < 32; i++) { | 134 | for (i = 0; i < 32; i++) { |
@@ -141,26 +143,22 @@ static void __aer_print_error(const char *prefix, | |||
141 | aer_uncorrectable_error_string[i] : NULL; | 143 | aer_uncorrectable_error_string[i] : NULL; |
142 | 144 | ||
143 | if (errmsg) | 145 | if (errmsg) |
144 | printk("%s"" [%2d] %-22s%s\n", prefix, i, errmsg, | 146 | dev_err(&dev->dev, " [%2d] %-22s%s\n", i, errmsg, |
145 | info->first_error == i ? " (First)" : ""); | 147 | info->first_error == i ? " (First)" : ""); |
146 | else | 148 | else |
147 | printk("%s"" [%2d] Unknown Error Bit%s\n", prefix, i, | 149 | dev_err(&dev->dev, " [%2d] Unknown Error Bit%s\n", |
148 | info->first_error == i ? " (First)" : ""); | 150 | i, info->first_error == i ? " (First)" : ""); |
149 | } | 151 | } |
150 | } | 152 | } |
151 | 153 | ||
152 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | 154 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) |
153 | { | 155 | { |
154 | int id = ((dev->bus->number << 8) | dev->devfn); | 156 | int id = ((dev->bus->number << 8) | dev->devfn); |
155 | char prefix[44]; | ||
156 | |||
157 | snprintf(prefix, sizeof(prefix), "%s%s %s: ", | ||
158 | (info->severity == AER_CORRECTABLE) ? KERN_WARNING : KERN_ERR, | ||
159 | dev_driver_string(&dev->dev), dev_name(&dev->dev)); | ||
160 | 157 | ||
161 | if (info->status == 0) { | 158 | if (info->status == 0) { |
162 | printk("%s""PCIe Bus Error: severity=%s, type=Unaccessible, " | 159 | dev_err(&dev->dev, |
163 | "id=%04x(Unregistered Agent ID)\n", prefix, | 160 | "PCIe Bus Error: severity=%s, type=Unaccessible, " |
161 | "id=%04x(Unregistered Agent ID)\n", | ||
164 | aer_error_severity_string[info->severity], id); | 162 | aer_error_severity_string[info->severity], id); |
165 | } else { | 163 | } else { |
166 | int layer, agent; | 164 | int layer, agent; |
@@ -168,22 +166,24 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
168 | layer = AER_GET_LAYER_ERROR(info->severity, info->status); | 166 | layer = AER_GET_LAYER_ERROR(info->severity, info->status); |
169 | agent = AER_GET_AGENT(info->severity, info->status); | 167 | agent = AER_GET_AGENT(info->severity, info->status); |
170 | 168 | ||
171 | printk("%s""PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", | 169 | dev_err(&dev->dev, |
172 | prefix, aer_error_severity_string[info->severity], | 170 | "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", |
171 | aer_error_severity_string[info->severity], | ||
173 | aer_error_layer[layer], id, aer_agent_string[agent]); | 172 | aer_error_layer[layer], id, aer_agent_string[agent]); |
174 | 173 | ||
175 | printk("%s"" device [%04x:%04x] error status/mask=%08x/%08x\n", | 174 | dev_err(&dev->dev, |
176 | prefix, dev->vendor, dev->device, | 175 | " device [%04x:%04x] error status/mask=%08x/%08x\n", |
176 | dev->vendor, dev->device, | ||
177 | info->status, info->mask); | 177 | info->status, info->mask); |
178 | 178 | ||
179 | __aer_print_error(prefix, info); | 179 | __aer_print_error(dev, info); |
180 | 180 | ||
181 | if (info->tlp_header_valid) { | 181 | if (info->tlp_header_valid) { |
182 | unsigned char *tlp = (unsigned char *) &info->tlp; | 182 | unsigned char *tlp = (unsigned char *) &info->tlp; |
183 | printk("%s"" TLP Header:" | 183 | dev_err(&dev->dev, " TLP Header:" |
184 | " %02x%02x%02x%02x %02x%02x%02x%02x" | 184 | " %02x%02x%02x%02x %02x%02x%02x%02x" |
185 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", | 185 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", |
186 | prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, | 186 | *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, |
187 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), | 187 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), |
188 | *(tlp + 11), *(tlp + 10), *(tlp + 9), | 188 | *(tlp + 11), *(tlp + 10), *(tlp + 9), |
189 | *(tlp + 8), *(tlp + 15), *(tlp + 14), | 189 | *(tlp + 8), *(tlp + 15), *(tlp + 14), |
@@ -192,8 +192,11 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | if (info->id && info->error_dev_num > 1 && info->id == id) | 194 | if (info->id && info->error_dev_num > 1 && info->id == id) |
195 | printk("%s"" Error of this Agent(%04x) is reported first\n", | 195 | dev_err(&dev->dev, |
196 | prefix, id); | 196 | " Error of this Agent(%04x) is reported first\n", |
197 | id); | ||
198 | trace_aer_event(dev_name(&dev->dev), (info->status & ~info->mask), | ||
199 | info->severity); | ||
197 | } | 200 | } |
198 | 201 | ||
199 | void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) | 202 | void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) |
@@ -217,7 +220,7 @@ int cper_severity_to_aer(int cper_severity) | |||
217 | } | 220 | } |
218 | EXPORT_SYMBOL_GPL(cper_severity_to_aer); | 221 | EXPORT_SYMBOL_GPL(cper_severity_to_aer); |
219 | 222 | ||
220 | void cper_print_aer(const char *prefix, int cper_severity, | 223 | void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, |
221 | struct aer_capability_regs *aer) | 224 | struct aer_capability_regs *aer) |
222 | { | 225 | { |
223 | int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; | 226 | int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; |
@@ -239,25 +242,27 @@ void cper_print_aer(const char *prefix, int cper_severity, | |||
239 | } | 242 | } |
240 | layer = AER_GET_LAYER_ERROR(aer_severity, status); | 243 | layer = AER_GET_LAYER_ERROR(aer_severity, status); |
241 | agent = AER_GET_AGENT(aer_severity, status); | 244 | agent = AER_GET_AGENT(aer_severity, status); |
242 | printk("%s""aer_status: 0x%08x, aer_mask: 0x%08x\n", | 245 | dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", |
243 | prefix, status, mask); | 246 | status, mask); |
244 | cper_print_bits(prefix, status, status_strs, status_strs_size); | 247 | cper_print_bits(prefix, status, status_strs, status_strs_size); |
245 | printk("%s""aer_layer=%s, aer_agent=%s\n", prefix, | 248 | dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n", |
246 | aer_error_layer[layer], aer_agent_string[agent]); | 249 | aer_error_layer[layer], aer_agent_string[agent]); |
247 | if (aer_severity != AER_CORRECTABLE) | 250 | if (aer_severity != AER_CORRECTABLE) |
248 | printk("%s""aer_uncor_severity: 0x%08x\n", | 251 | dev_err(&dev->dev, "aer_uncor_severity: 0x%08x\n", |
249 | prefix, aer->uncor_severity); | 252 | aer->uncor_severity); |
250 | if (tlp_header_valid) { | 253 | if (tlp_header_valid) { |
251 | const unsigned char *tlp; | 254 | const unsigned char *tlp; |
252 | tlp = (const unsigned char *)&aer->header_log; | 255 | tlp = (const unsigned char *)&aer->header_log; |
253 | printk("%s""aer_tlp_header:" | 256 | dev_err(&dev->dev, "aer_tlp_header:" |
254 | " %02x%02x%02x%02x %02x%02x%02x%02x" | 257 | " %02x%02x%02x%02x %02x%02x%02x%02x" |
255 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", | 258 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", |
256 | prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, | 259 | *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, |
257 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), | 260 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), |
258 | *(tlp + 11), *(tlp + 10), *(tlp + 9), | 261 | *(tlp + 11), *(tlp + 10), *(tlp + 9), |
259 | *(tlp + 8), *(tlp + 15), *(tlp + 14), | 262 | *(tlp + 8), *(tlp + 15), *(tlp + 14), |
260 | *(tlp + 13), *(tlp + 12)); | 263 | *(tlp + 13), *(tlp + 12)); |
261 | } | 264 | } |
265 | trace_aer_event(dev_name(&dev->dev), (status & ~mask), | ||
266 | aer_severity); | ||
262 | } | 267 | } |
263 | #endif | 268 | #endif |