trace.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
  3. #undef TRACE_SYSTEM
  4. #define TRACE_SYSTEM cxl
  5. #if !defined(_CXL_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
  6. #define _CXL_EVENTS_H
  7. #include <linux/tracepoint.h>
  8. #include <linux/pci.h>
  9. #include <linux/unaligned.h>
  10. #include <cxl.h>
  11. #include <cxlmem.h>
  12. #include "core.h"
  13. #define CXL_RAS_UC_CACHE_DATA_PARITY BIT(0)
  14. #define CXL_RAS_UC_CACHE_ADDR_PARITY BIT(1)
  15. #define CXL_RAS_UC_CACHE_BE_PARITY BIT(2)
  16. #define CXL_RAS_UC_CACHE_DATA_ECC BIT(3)
  17. #define CXL_RAS_UC_MEM_DATA_PARITY BIT(4)
  18. #define CXL_RAS_UC_MEM_ADDR_PARITY BIT(5)
  19. #define CXL_RAS_UC_MEM_BE_PARITY BIT(6)
  20. #define CXL_RAS_UC_MEM_DATA_ECC BIT(7)
  21. #define CXL_RAS_UC_REINIT_THRESH BIT(8)
  22. #define CXL_RAS_UC_RSVD_ENCODE BIT(9)
  23. #define CXL_RAS_UC_POISON BIT(10)
  24. #define CXL_RAS_UC_RECV_OVERFLOW BIT(11)
  25. #define CXL_RAS_UC_INTERNAL_ERR BIT(14)
  26. #define CXL_RAS_UC_IDE_TX_ERR BIT(15)
  27. #define CXL_RAS_UC_IDE_RX_ERR BIT(16)
  28. #define show_uc_errs(status) __print_flags(status, " | ", \
  29. { CXL_RAS_UC_CACHE_DATA_PARITY, "Cache Data Parity Error" }, \
  30. { CXL_RAS_UC_CACHE_ADDR_PARITY, "Cache Address Parity Error" }, \
  31. { CXL_RAS_UC_CACHE_BE_PARITY, "Cache Byte Enable Parity Error" }, \
  32. { CXL_RAS_UC_CACHE_DATA_ECC, "Cache Data ECC Error" }, \
  33. { CXL_RAS_UC_MEM_DATA_PARITY, "Memory Data Parity Error" }, \
  34. { CXL_RAS_UC_MEM_ADDR_PARITY, "Memory Address Parity Error" }, \
  35. { CXL_RAS_UC_MEM_BE_PARITY, "Memory Byte Enable Parity Error" }, \
  36. { CXL_RAS_UC_MEM_DATA_ECC, "Memory Data ECC Error" }, \
  37. { CXL_RAS_UC_REINIT_THRESH, "REINIT Threshold Hit" }, \
  38. { CXL_RAS_UC_RSVD_ENCODE, "Received Unrecognized Encoding" }, \
  39. { CXL_RAS_UC_POISON, "Received Poison From Peer" }, \
  40. { CXL_RAS_UC_RECV_OVERFLOW, "Receiver Overflow" }, \
  41. { CXL_RAS_UC_INTERNAL_ERR, "Component Specific Error" }, \
  42. { CXL_RAS_UC_IDE_TX_ERR, "IDE Tx Error" }, \
  43. { CXL_RAS_UC_IDE_RX_ERR, "IDE Rx Error" } \
  44. )
  45. TRACE_EVENT(cxl_aer_uncorrectable_error,
  46. TP_PROTO(const struct cxl_memdev *cxlmd, u32 status, u32 fe, u32 *hl),
  47. TP_ARGS(cxlmd, status, fe, hl),
  48. TP_STRUCT__entry(
  49. __string(memdev, dev_name(&cxlmd->dev))
  50. __string(host, dev_name(cxlmd->dev.parent))
  51. __field(u64, serial)
  52. __field(u32, status)
  53. __field(u32, first_error)
  54. __array(u32, header_log, CXL_HEADERLOG_SIZE_U32)
  55. ),
  56. TP_fast_assign(
  57. __assign_str(memdev);
  58. __assign_str(host);
  59. __entry->serial = cxlmd->cxlds->serial;
  60. __entry->status = status;
  61. __entry->first_error = fe;
  62. /*
  63. * Embed the 512B headerlog data for user app retrieval and
  64. * parsing, but no need to print this in the trace buffer.
  65. */
  66. memcpy(__entry->header_log, hl, CXL_HEADERLOG_SIZE);
  67. ),
  68. TP_printk("memdev=%s host=%s serial=%lld: status: '%s' first_error: '%s'",
  69. __get_str(memdev), __get_str(host), __entry->serial,
  70. show_uc_errs(__entry->status),
  71. show_uc_errs(__entry->first_error)
  72. )
  73. );
  74. #define CXL_RAS_CE_CACHE_DATA_ECC BIT(0)
  75. #define CXL_RAS_CE_MEM_DATA_ECC BIT(1)
  76. #define CXL_RAS_CE_CRC_THRESH BIT(2)
  77. #define CLX_RAS_CE_RETRY_THRESH BIT(3)
  78. #define CXL_RAS_CE_CACHE_POISON BIT(4)
  79. #define CXL_RAS_CE_MEM_POISON BIT(5)
  80. #define CXL_RAS_CE_PHYS_LAYER_ERR BIT(6)
  81. #define show_ce_errs(status) __print_flags(status, " | ", \
  82. { CXL_RAS_CE_CACHE_DATA_ECC, "Cache Data ECC Error" }, \
  83. { CXL_RAS_CE_MEM_DATA_ECC, "Memory Data ECC Error" }, \
  84. { CXL_RAS_CE_CRC_THRESH, "CRC Threshold Hit" }, \
  85. { CLX_RAS_CE_RETRY_THRESH, "Retry Threshold" }, \
  86. { CXL_RAS_CE_CACHE_POISON, "Received Cache Poison From Peer" }, \
  87. { CXL_RAS_CE_MEM_POISON, "Received Memory Poison From Peer" }, \
  88. { CXL_RAS_CE_PHYS_LAYER_ERR, "Received Error From Physical Layer" } \
  89. )
  90. TRACE_EVENT(cxl_aer_correctable_error,
  91. TP_PROTO(const struct cxl_memdev *cxlmd, u32 status),
  92. TP_ARGS(cxlmd, status),
  93. TP_STRUCT__entry(
  94. __string(memdev, dev_name(&cxlmd->dev))
  95. __string(host, dev_name(cxlmd->dev.parent))
  96. __field(u64, serial)
  97. __field(u32, status)
  98. ),
  99. TP_fast_assign(
  100. __assign_str(memdev);
  101. __assign_str(host);
  102. __entry->serial = cxlmd->cxlds->serial;
  103. __entry->status = status;
  104. ),
  105. TP_printk("memdev=%s host=%s serial=%lld: status: '%s'",
  106. __get_str(memdev), __get_str(host), __entry->serial,
  107. show_ce_errs(__entry->status)
  108. )
  109. );
  110. #define cxl_event_log_type_str(type) \
  111. __print_symbolic(type, \
  112. { CXL_EVENT_TYPE_INFO, "Informational" }, \
  113. { CXL_EVENT_TYPE_WARN, "Warning" }, \
  114. { CXL_EVENT_TYPE_FAIL, "Failure" }, \
  115. { CXL_EVENT_TYPE_FATAL, "Fatal" })
  116. TRACE_EVENT(cxl_overflow,
  117. TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
  118. struct cxl_get_event_payload *payload),
  119. TP_ARGS(cxlmd, log, payload),
  120. TP_STRUCT__entry(
  121. __string(memdev, dev_name(&cxlmd->dev))
  122. __string(host, dev_name(cxlmd->dev.parent))
  123. __field(int, log)
  124. __field(u64, serial)
  125. __field(u64, first_ts)
  126. __field(u64, last_ts)
  127. __field(u16, count)
  128. ),
  129. TP_fast_assign(
  130. __assign_str(memdev);
  131. __assign_str(host);
  132. __entry->serial = cxlmd->cxlds->serial;
  133. __entry->log = log;
  134. __entry->count = le16_to_cpu(payload->overflow_err_count);
  135. __entry->first_ts = le64_to_cpu(payload->first_overflow_timestamp);
  136. __entry->last_ts = le64_to_cpu(payload->last_overflow_timestamp);
  137. ),
  138. TP_printk("memdev=%s host=%s serial=%lld: log=%s : %u records from %llu to %llu",
  139. __get_str(memdev), __get_str(host), __entry->serial,
  140. cxl_event_log_type_str(__entry->log), __entry->count,
  141. __entry->first_ts, __entry->last_ts)
  142. );
  143. /*
  144. * Common Event Record Format
  145. * CXL 3.0 section 8.2.9.2.1; Table 8-42
  146. */
  147. #define CXL_EVENT_RECORD_FLAG_PERMANENT BIT(2)
  148. #define CXL_EVENT_RECORD_FLAG_MAINT_NEEDED BIT(3)
  149. #define CXL_EVENT_RECORD_FLAG_PERF_DEGRADED BIT(4)
  150. #define CXL_EVENT_RECORD_FLAG_HW_REPLACE BIT(5)
  151. #define show_hdr_flags(flags) __print_flags(flags, " | ", \
  152. { CXL_EVENT_RECORD_FLAG_PERMANENT, "PERMANENT_CONDITION" }, \
  153. { CXL_EVENT_RECORD_FLAG_MAINT_NEEDED, "MAINTENANCE_NEEDED" }, \
  154. { CXL_EVENT_RECORD_FLAG_PERF_DEGRADED, "PERFORMANCE_DEGRADED" }, \
  155. { CXL_EVENT_RECORD_FLAG_HW_REPLACE, "HARDWARE_REPLACEMENT_NEEDED" } \
  156. )
  157. /*
  158. * Define macros for the common header of each CXL event.
  159. *
  160. * Tracepoints using these macros must do 3 things:
  161. *
  162. * 1) Add CXL_EVT_TP_entry to TP_STRUCT__entry
  163. * 2) Use CXL_EVT_TP_fast_assign within TP_fast_assign;
  164. * pass the dev, log, and CXL event header
  165. * NOTE: The uuid must be assigned by the specific trace event
  166. * 3) Use CXL_EVT_TP_printk() instead of TP_printk()
  167. *
  168. * See the generic_event tracepoint as an example.
  169. */
  170. #define CXL_EVT_TP_entry \
  171. __string(memdev, dev_name(&cxlmd->dev)) \
  172. __string(host, dev_name(cxlmd->dev.parent)) \
  173. __field(int, log) \
  174. __field_struct(uuid_t, hdr_uuid) \
  175. __field(u64, serial) \
  176. __field(u32, hdr_flags) \
  177. __field(u16, hdr_handle) \
  178. __field(u16, hdr_related_handle) \
  179. __field(u64, hdr_timestamp) \
  180. __field(u8, hdr_length) \
  181. __field(u8, hdr_maint_op_class)
  182. #define CXL_EVT_TP_fast_assign(cxlmd, l, hdr) \
  183. __assign_str(memdev); \
  184. __assign_str(host); \
  185. __entry->log = (l); \
  186. __entry->serial = (cxlmd)->cxlds->serial; \
  187. __entry->hdr_length = (hdr).length; \
  188. __entry->hdr_flags = get_unaligned_le24((hdr).flags); \
  189. __entry->hdr_handle = le16_to_cpu((hdr).handle); \
  190. __entry->hdr_related_handle = le16_to_cpu((hdr).related_handle); \
  191. __entry->hdr_timestamp = le64_to_cpu((hdr).timestamp); \
  192. __entry->hdr_maint_op_class = (hdr).maint_op_class
  193. #define CXL_EVT_TP_printk(fmt, ...) \
  194. TP_printk("memdev=%s host=%s serial=%lld log=%s : time=%llu uuid=%pUb " \
  195. "len=%d flags='%s' handle=%x related_handle=%x " \
  196. "maint_op_class=%u : " fmt, \
  197. __get_str(memdev), __get_str(host), __entry->serial, \
  198. cxl_event_log_type_str(__entry->log), \
  199. __entry->hdr_timestamp, &__entry->hdr_uuid, __entry->hdr_length,\
  200. show_hdr_flags(__entry->hdr_flags), __entry->hdr_handle, \
  201. __entry->hdr_related_handle, __entry->hdr_maint_op_class, \
  202. ##__VA_ARGS__)
  203. TRACE_EVENT(cxl_generic_event,
  204. TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
  205. const uuid_t *uuid, struct cxl_event_generic *gen_rec),
  206. TP_ARGS(cxlmd, log, uuid, gen_rec),
  207. TP_STRUCT__entry(
  208. CXL_EVT_TP_entry
  209. __array(u8, data, CXL_EVENT_RECORD_DATA_LENGTH)
  210. ),
  211. TP_fast_assign(
  212. CXL_EVT_TP_fast_assign(cxlmd, log, gen_rec->hdr);
  213. memcpy(&__entry->hdr_uuid, uuid, sizeof(uuid_t));
  214. memcpy(__entry->data, gen_rec->data, CXL_EVENT_RECORD_DATA_LENGTH);
  215. ),
  216. CXL_EVT_TP_printk("%s",
  217. __print_hex(__entry->data, CXL_EVENT_RECORD_DATA_LENGTH))
  218. );
  219. /*
  220. * Physical Address field masks
  221. *
  222. * General Media Event Record
  223. * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
  224. *
  225. * DRAM Event Record
  226. * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
  227. */
  228. #define CXL_DPA_FLAGS_MASK GENMASK(1, 0)
  229. #define CXL_DPA_MASK GENMASK_ULL(63, 6)
  230. #define CXL_DPA_VOLATILE BIT(0)
  231. #define CXL_DPA_NOT_REPAIRABLE BIT(1)
  232. #define show_dpa_flags(flags) __print_flags(flags, "|", \
  233. { CXL_DPA_VOLATILE, "VOLATILE" }, \
  234. { CXL_DPA_NOT_REPAIRABLE, "NOT_REPAIRABLE" } \
  235. )
  236. /*
  237. * General Media Event Record - GMER
  238. * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
  239. */
  240. #define CXL_GMER_EVT_DESC_UNCORECTABLE_EVENT BIT(0)
  241. #define CXL_GMER_EVT_DESC_THRESHOLD_EVENT BIT(1)
  242. #define CXL_GMER_EVT_DESC_POISON_LIST_OVERFLOW BIT(2)
  243. #define show_event_desc_flags(flags) __print_flags(flags, "|", \
  244. { CXL_GMER_EVT_DESC_UNCORECTABLE_EVENT, "UNCORRECTABLE_EVENT" }, \
  245. { CXL_GMER_EVT_DESC_THRESHOLD_EVENT, "THRESHOLD_EVENT" }, \
  246. { CXL_GMER_EVT_DESC_POISON_LIST_OVERFLOW, "POISON_LIST_OVERFLOW" } \
  247. )
  248. #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR 0x00
  249. #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR 0x01
  250. #define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x02
  251. #define show_gmer_mem_event_type(type) __print_symbolic(type, \
  252. { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \
  253. { CXL_GMER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \
  254. { CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \
  255. )
  256. #define CXL_GMER_TRANS_UNKNOWN 0x00
  257. #define CXL_GMER_TRANS_HOST_READ 0x01
  258. #define CXL_GMER_TRANS_HOST_WRITE 0x02
  259. #define CXL_GMER_TRANS_HOST_SCAN_MEDIA 0x03
  260. #define CXL_GMER_TRANS_HOST_INJECT_POISON 0x04
  261. #define CXL_GMER_TRANS_INTERNAL_MEDIA_SCRUB 0x05
  262. #define CXL_GMER_TRANS_INTERNAL_MEDIA_MANAGEMENT 0x06
  263. #define show_trans_type(type) __print_symbolic(type, \
  264. { CXL_GMER_TRANS_UNKNOWN, "Unknown" }, \
  265. { CXL_GMER_TRANS_HOST_READ, "Host Read" }, \
  266. { CXL_GMER_TRANS_HOST_WRITE, "Host Write" }, \
  267. { CXL_GMER_TRANS_HOST_SCAN_MEDIA, "Host Scan Media" }, \
  268. { CXL_GMER_TRANS_HOST_INJECT_POISON, "Host Inject Poison" }, \
  269. { CXL_GMER_TRANS_INTERNAL_MEDIA_SCRUB, "Internal Media Scrub" }, \
  270. { CXL_GMER_TRANS_INTERNAL_MEDIA_MANAGEMENT, "Internal Media Management" } \
  271. )
  272. #define CXL_GMER_VALID_CHANNEL BIT(0)
  273. #define CXL_GMER_VALID_RANK BIT(1)
  274. #define CXL_GMER_VALID_DEVICE BIT(2)
  275. #define CXL_GMER_VALID_COMPONENT BIT(3)
  276. #define show_valid_flags(flags) __print_flags(flags, "|", \
  277. { CXL_GMER_VALID_CHANNEL, "CHANNEL" }, \
  278. { CXL_GMER_VALID_RANK, "RANK" }, \
  279. { CXL_GMER_VALID_DEVICE, "DEVICE" }, \
  280. { CXL_GMER_VALID_COMPONENT, "COMPONENT" } \
  281. )
  282. TRACE_EVENT(cxl_general_media,
  283. TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
  284. struct cxl_region *cxlr, u64 hpa, struct cxl_event_gen_media *rec),
  285. TP_ARGS(cxlmd, log, cxlr, hpa, rec),
  286. TP_STRUCT__entry(
  287. CXL_EVT_TP_entry
  288. /* General Media */
  289. __field(u64, dpa)
  290. __field(u8, descriptor)
  291. __field(u8, type)
  292. __field(u8, transaction_type)
  293. __field(u8, channel)
  294. __field(u32, device)
  295. __array(u8, comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE)
  296. /* Following are out of order to pack trace record */
  297. __field(u64, hpa)
  298. __field_struct(uuid_t, region_uuid)
  299. __field(u16, validity_flags)
  300. __field(u8, rank)
  301. __field(u8, dpa_flags)
  302. __string(region_name, cxlr ? dev_name(&cxlr->dev) : "")
  303. ),
  304. TP_fast_assign(
  305. CXL_EVT_TP_fast_assign(cxlmd, log, rec->media_hdr.hdr);
  306. __entry->hdr_uuid = CXL_EVENT_GEN_MEDIA_UUID;
  307. /* General Media */
  308. __entry->dpa = le64_to_cpu(rec->media_hdr.phys_addr);
  309. __entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK;
  310. /* Mask after flags have been parsed */
  311. __entry->dpa &= CXL_DPA_MASK;
  312. __entry->descriptor = rec->media_hdr.descriptor;
  313. __entry->type = rec->media_hdr.type;
  314. __entry->transaction_type = rec->media_hdr.transaction_type;
  315. __entry->channel = rec->media_hdr.channel;
  316. __entry->rank = rec->media_hdr.rank;
  317. __entry->device = get_unaligned_le24(rec->device);
  318. memcpy(__entry->comp_id, &rec->component_id,
  319. CXL_EVENT_GEN_MED_COMP_ID_SIZE);
  320. __entry->validity_flags = get_unaligned_le16(&rec->media_hdr.validity_flags);
  321. __entry->hpa = hpa;
  322. if (cxlr) {
  323. __assign_str(region_name);
  324. uuid_copy(&__entry->region_uuid, &cxlr->params.uuid);
  325. } else {
  326. __assign_str(region_name);
  327. uuid_copy(&__entry->region_uuid, &uuid_null);
  328. }
  329. ),
  330. CXL_EVT_TP_printk("dpa=%llx dpa_flags='%s' " \
  331. "descriptor='%s' type='%s' transaction_type='%s' channel=%u rank=%u " \
  332. "device=%x comp_id=%s validity_flags='%s' " \
  333. "hpa=%llx region=%s region_uuid=%pUb",
  334. __entry->dpa, show_dpa_flags(__entry->dpa_flags),
  335. show_event_desc_flags(__entry->descriptor),
  336. show_gmer_mem_event_type(__entry->type),
  337. show_trans_type(__entry->transaction_type),
  338. __entry->channel, __entry->rank, __entry->device,
  339. __print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE),
  340. show_valid_flags(__entry->validity_flags),
  341. __entry->hpa, __get_str(region_name), &__entry->region_uuid
  342. )
  343. );
  344. /*
  345. * DRAM Event Record - DER
  346. *
  347. * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
  348. */
  349. /*
  350. * DRAM Event Record defines many fields the same as the General Media Event
  351. * Record. Reuse those definitions as appropriate.
  352. */
  353. #define CXL_DER_MEM_EVT_TYPE_ECC_ERROR 0x00
  354. #define CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR 0x01
  355. #define CXL_DER_MEM_EVT_TYPE_INV_ADDR 0x02
  356. #define CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x03
  357. #define show_dram_mem_event_type(type) __print_symbolic(type, \
  358. { CXL_DER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \
  359. { CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR, "Scrub Media ECC Error" }, \
  360. { CXL_DER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \
  361. { CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \
  362. )
  363. #define CXL_DER_VALID_CHANNEL BIT(0)
  364. #define CXL_DER_VALID_RANK BIT(1)
  365. #define CXL_DER_VALID_NIBBLE BIT(2)
  366. #define CXL_DER_VALID_BANK_GROUP BIT(3)
  367. #define CXL_DER_VALID_BANK BIT(4)
  368. #define CXL_DER_VALID_ROW BIT(5)
  369. #define CXL_DER_VALID_COLUMN BIT(6)
  370. #define CXL_DER_VALID_CORRECTION_MASK BIT(7)
  371. #define show_dram_valid_flags(flags) __print_flags(flags, "|", \
  372. { CXL_DER_VALID_CHANNEL, "CHANNEL" }, \
  373. { CXL_DER_VALID_RANK, "RANK" }, \
  374. { CXL_DER_VALID_NIBBLE, "NIBBLE" }, \
  375. { CXL_DER_VALID_BANK_GROUP, "BANK GROUP" }, \
  376. { CXL_DER_VALID_BANK, "BANK" }, \
  377. { CXL_DER_VALID_ROW, "ROW" }, \
  378. { CXL_DER_VALID_COLUMN, "COLUMN" }, \
  379. { CXL_DER_VALID_CORRECTION_MASK, "CORRECTION MASK" } \
  380. )
  381. TRACE_EVENT(cxl_dram,
  382. TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
  383. struct cxl_region *cxlr, u64 hpa, struct cxl_event_dram *rec),
  384. TP_ARGS(cxlmd, log, cxlr, hpa, rec),
  385. TP_STRUCT__entry(
  386. CXL_EVT_TP_entry
  387. /* DRAM */
  388. __field(u64, dpa)
  389. __field(u8, descriptor)
  390. __field(u8, type)
  391. __field(u8, transaction_type)
  392. __field(u8, channel)
  393. __field(u16, validity_flags)
  394. __field(u16, column) /* Out of order to pack trace record */
  395. __field(u32, nibble_mask)
  396. __field(u32, row)
  397. __array(u8, cor_mask, CXL_EVENT_DER_CORRECTION_MASK_SIZE)
  398. __field(u64, hpa)
  399. __field_struct(uuid_t, region_uuid)
  400. __field(u8, rank) /* Out of order to pack trace record */
  401. __field(u8, bank_group) /* Out of order to pack trace record */
  402. __field(u8, bank) /* Out of order to pack trace record */
  403. __field(u8, dpa_flags) /* Out of order to pack trace record */
  404. __string(region_name, cxlr ? dev_name(&cxlr->dev) : "")
  405. ),
  406. TP_fast_assign(
  407. CXL_EVT_TP_fast_assign(cxlmd, log, rec->media_hdr.hdr);
  408. __entry->hdr_uuid = CXL_EVENT_DRAM_UUID;
  409. /* DRAM */
  410. __entry->dpa = le64_to_cpu(rec->media_hdr.phys_addr);
  411. __entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK;
  412. __entry->dpa &= CXL_DPA_MASK;
  413. __entry->descriptor = rec->media_hdr.descriptor;
  414. __entry->type = rec->media_hdr.type;
  415. __entry->transaction_type = rec->media_hdr.transaction_type;
  416. __entry->validity_flags = get_unaligned_le16(rec->media_hdr.validity_flags);
  417. __entry->channel = rec->media_hdr.channel;
  418. __entry->rank = rec->media_hdr.rank;
  419. __entry->nibble_mask = get_unaligned_le24(rec->nibble_mask);
  420. __entry->bank_group = rec->bank_group;
  421. __entry->bank = rec->bank;
  422. __entry->row = get_unaligned_le24(rec->row);
  423. __entry->column = get_unaligned_le16(rec->column);
  424. memcpy(__entry->cor_mask, &rec->correction_mask,
  425. CXL_EVENT_DER_CORRECTION_MASK_SIZE);
  426. __entry->hpa = hpa;
  427. if (cxlr) {
  428. __assign_str(region_name);
  429. uuid_copy(&__entry->region_uuid, &cxlr->params.uuid);
  430. } else {
  431. __assign_str(region_name);
  432. uuid_copy(&__entry->region_uuid, &uuid_null);
  433. }
  434. ),
  435. CXL_EVT_TP_printk("dpa=%llx dpa_flags='%s' descriptor='%s' type='%s' " \
  436. "transaction_type='%s' channel=%u rank=%u nibble_mask=%x " \
  437. "bank_group=%u bank=%u row=%u column=%u cor_mask=%s " \
  438. "validity_flags='%s' " \
  439. "hpa=%llx region=%s region_uuid=%pUb",
  440. __entry->dpa, show_dpa_flags(__entry->dpa_flags),
  441. show_event_desc_flags(__entry->descriptor),
  442. show_dram_mem_event_type(__entry->type),
  443. show_trans_type(__entry->transaction_type),
  444. __entry->channel, __entry->rank, __entry->nibble_mask,
  445. __entry->bank_group, __entry->bank,
  446. __entry->row, __entry->column,
  447. __print_hex(__entry->cor_mask, CXL_EVENT_DER_CORRECTION_MASK_SIZE),
  448. show_dram_valid_flags(__entry->validity_flags),
  449. __entry->hpa, __get_str(region_name), &__entry->region_uuid
  450. )
  451. );
  452. /*
  453. * Memory Module Event Record - MMER
  454. *
  455. * CXL res 3.0 section 8.2.9.2.1.3; Table 8-45
  456. */
  457. #define CXL_MMER_HEALTH_STATUS_CHANGE 0x00
  458. #define CXL_MMER_MEDIA_STATUS_CHANGE 0x01
  459. #define CXL_MMER_LIFE_USED_CHANGE 0x02
  460. #define CXL_MMER_TEMP_CHANGE 0x03
  461. #define CXL_MMER_DATA_PATH_ERROR 0x04
  462. #define CXL_MMER_LSA_ERROR 0x05
  463. #define show_dev_evt_type(type) __print_symbolic(type, \
  464. { CXL_MMER_HEALTH_STATUS_CHANGE, "Health Status Change" }, \
  465. { CXL_MMER_MEDIA_STATUS_CHANGE, "Media Status Change" }, \
  466. { CXL_MMER_LIFE_USED_CHANGE, "Life Used Change" }, \
  467. { CXL_MMER_TEMP_CHANGE, "Temperature Change" }, \
  468. { CXL_MMER_DATA_PATH_ERROR, "Data Path Error" }, \
  469. { CXL_MMER_LSA_ERROR, "LSA Error" } \
  470. )
  471. /*
  472. * Device Health Information - DHI
  473. *
  474. * CXL res 3.0 section 8.2.9.8.3.1; Table 8-100
  475. */
  476. #define CXL_DHI_HS_MAINTENANCE_NEEDED BIT(0)
  477. #define CXL_DHI_HS_PERFORMANCE_DEGRADED BIT(1)
  478. #define CXL_DHI_HS_HW_REPLACEMENT_NEEDED BIT(2)
  479. #define show_health_status_flags(flags) __print_flags(flags, "|", \
  480. { CXL_DHI_HS_MAINTENANCE_NEEDED, "MAINTENANCE_NEEDED" }, \
  481. { CXL_DHI_HS_PERFORMANCE_DEGRADED, "PERFORMANCE_DEGRADED" }, \
  482. { CXL_DHI_HS_HW_REPLACEMENT_NEEDED, "REPLACEMENT_NEEDED" } \
  483. )
  484. #define CXL_DHI_MS_NORMAL 0x00
  485. #define CXL_DHI_MS_NOT_READY 0x01
  486. #define CXL_DHI_MS_WRITE_PERSISTENCY_LOST 0x02
  487. #define CXL_DHI_MS_ALL_DATA_LOST 0x03
  488. #define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_POWER_LOSS 0x04
  489. #define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_SHUTDOWN 0x05
  490. #define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_IMMINENT 0x06
  491. #define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_POWER_LOSS 0x07
  492. #define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_SHUTDOWN 0x08
  493. #define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_IMMINENT 0x09
  494. #define show_media_status(ms) __print_symbolic(ms, \
  495. { CXL_DHI_MS_NORMAL, \
  496. "Normal" }, \
  497. { CXL_DHI_MS_NOT_READY, \
  498. "Not Ready" }, \
  499. { CXL_DHI_MS_WRITE_PERSISTENCY_LOST, \
  500. "Write Persistency Lost" }, \
  501. { CXL_DHI_MS_ALL_DATA_LOST, \
  502. "All Data Lost" }, \
  503. { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_POWER_LOSS, \
  504. "Write Persistency Loss in the Event of Power Loss" }, \
  505. { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_SHUTDOWN, \
  506. "Write Persistency Loss in Event of Shutdown" }, \
  507. { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_IMMINENT, \
  508. "Write Persistency Loss Imminent" }, \
  509. { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_POWER_LOSS, \
  510. "All Data Loss in Event of Power Loss" }, \
  511. { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_SHUTDOWN, \
  512. "All Data loss in the Event of Shutdown" }, \
  513. { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_IMMINENT, \
  514. "All Data Loss Imminent" } \
  515. )
  516. #define CXL_DHI_AS_NORMAL 0x0
  517. #define CXL_DHI_AS_WARNING 0x1
  518. #define CXL_DHI_AS_CRITICAL 0x2
  519. #define show_two_bit_status(as) __print_symbolic(as, \
  520. { CXL_DHI_AS_NORMAL, "Normal" }, \
  521. { CXL_DHI_AS_WARNING, "Warning" }, \
  522. { CXL_DHI_AS_CRITICAL, "Critical" } \
  523. )
  524. #define show_one_bit_status(as) __print_symbolic(as, \
  525. { CXL_DHI_AS_NORMAL, "Normal" }, \
  526. { CXL_DHI_AS_WARNING, "Warning" } \
  527. )
  528. #define CXL_DHI_AS_LIFE_USED(as) (as & 0x3)
  529. #define CXL_DHI_AS_DEV_TEMP(as) ((as & 0xC) >> 2)
  530. #define CXL_DHI_AS_COR_VOL_ERR_CNT(as) ((as & 0x10) >> 4)
  531. #define CXL_DHI_AS_COR_PER_ERR_CNT(as) ((as & 0x20) >> 5)
  532. TRACE_EVENT(cxl_memory_module,
  533. TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
  534. struct cxl_event_mem_module *rec),
  535. TP_ARGS(cxlmd, log, rec),
  536. TP_STRUCT__entry(
  537. CXL_EVT_TP_entry
  538. /* Memory Module Event */
  539. __field(u8, event_type)
  540. /* Device Health Info */
  541. __field(u8, health_status)
  542. __field(u8, media_status)
  543. __field(u8, life_used)
  544. __field(u32, dirty_shutdown_cnt)
  545. __field(u32, cor_vol_err_cnt)
  546. __field(u32, cor_per_err_cnt)
  547. __field(s16, device_temp)
  548. __field(u8, add_status)
  549. ),
  550. TP_fast_assign(
  551. CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
  552. __entry->hdr_uuid = CXL_EVENT_MEM_MODULE_UUID;
  553. /* Memory Module Event */
  554. __entry->event_type = rec->event_type;
  555. /* Device Health Info */
  556. __entry->health_status = rec->info.health_status;
  557. __entry->media_status = rec->info.media_status;
  558. __entry->life_used = rec->info.life_used;
  559. __entry->dirty_shutdown_cnt = get_unaligned_le32(rec->info.dirty_shutdown_cnt);
  560. __entry->cor_vol_err_cnt = get_unaligned_le32(rec->info.cor_vol_err_cnt);
  561. __entry->cor_per_err_cnt = get_unaligned_le32(rec->info.cor_per_err_cnt);
  562. __entry->device_temp = get_unaligned_le16(rec->info.device_temp);
  563. __entry->add_status = rec->info.add_status;
  564. ),
  565. CXL_EVT_TP_printk("event_type='%s' health_status='%s' media_status='%s' " \
  566. "as_life_used=%s as_dev_temp=%s as_cor_vol_err_cnt=%s " \
  567. "as_cor_per_err_cnt=%s life_used=%u device_temp=%d " \
  568. "dirty_shutdown_cnt=%u cor_vol_err_cnt=%u cor_per_err_cnt=%u",
  569. show_dev_evt_type(__entry->event_type),
  570. show_health_status_flags(__entry->health_status),
  571. show_media_status(__entry->media_status),
  572. show_two_bit_status(CXL_DHI_AS_LIFE_USED(__entry->add_status)),
  573. show_two_bit_status(CXL_DHI_AS_DEV_TEMP(__entry->add_status)),
  574. show_one_bit_status(CXL_DHI_AS_COR_VOL_ERR_CNT(__entry->add_status)),
  575. show_one_bit_status(CXL_DHI_AS_COR_PER_ERR_CNT(__entry->add_status)),
  576. __entry->life_used, __entry->device_temp,
  577. __entry->dirty_shutdown_cnt, __entry->cor_vol_err_cnt,
  578. __entry->cor_per_err_cnt
  579. )
  580. );
  581. #define show_poison_trace_type(type) \
  582. __print_symbolic(type, \
  583. { CXL_POISON_TRACE_LIST, "List" }, \
  584. { CXL_POISON_TRACE_INJECT, "Inject" }, \
  585. { CXL_POISON_TRACE_CLEAR, "Clear" })
  586. #define __show_poison_source(source) \
  587. __print_symbolic(source, \
  588. { CXL_POISON_SOURCE_UNKNOWN, "Unknown" }, \
  589. { CXL_POISON_SOURCE_EXTERNAL, "External" }, \
  590. { CXL_POISON_SOURCE_INTERNAL, "Internal" }, \
  591. { CXL_POISON_SOURCE_INJECTED, "Injected" }, \
  592. { CXL_POISON_SOURCE_VENDOR, "Vendor" })
  593. #define show_poison_source(source) \
  594. (((source > CXL_POISON_SOURCE_INJECTED) && \
  595. (source != CXL_POISON_SOURCE_VENDOR)) ? "Reserved" \
  596. : __show_poison_source(source))
  597. #define show_poison_flags(flags) \
  598. __print_flags(flags, "|", \
  599. { CXL_POISON_FLAG_MORE, "More" }, \
  600. { CXL_POISON_FLAG_OVERFLOW, "Overflow" }, \
  601. { CXL_POISON_FLAG_SCANNING, "Scanning" })
  602. #define __cxl_poison_addr(record) \
  603. (le64_to_cpu(record->address))
  604. #define cxl_poison_record_dpa(record) \
  605. (__cxl_poison_addr(record) & CXL_POISON_START_MASK)
  606. #define cxl_poison_record_source(record) \
  607. (__cxl_poison_addr(record) & CXL_POISON_SOURCE_MASK)
  608. #define cxl_poison_record_dpa_length(record) \
  609. (le32_to_cpu(record->length) * CXL_POISON_LEN_MULT)
  610. #define cxl_poison_overflow(flags, time) \
  611. (flags & CXL_POISON_FLAG_OVERFLOW ? le64_to_cpu(time) : 0)
  612. TRACE_EVENT(cxl_poison,
  613. TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *cxlr,
  614. const struct cxl_poison_record *record, u8 flags,
  615. __le64 overflow_ts, enum cxl_poison_trace_type trace_type),
  616. TP_ARGS(cxlmd, cxlr, record, flags, overflow_ts, trace_type),
  617. TP_STRUCT__entry(
  618. __string(memdev, dev_name(&cxlmd->dev))
  619. __string(host, dev_name(cxlmd->dev.parent))
  620. __field(u64, serial)
  621. __field(u8, trace_type)
  622. __string(region, cxlr ? dev_name(&cxlr->dev) : "")
  623. __field(u64, overflow_ts)
  624. __field(u64, hpa)
  625. __field(u64, dpa)
  626. __field(u32, dpa_length)
  627. __array(char, uuid, 16)
  628. __field(u8, source)
  629. __field(u8, flags)
  630. ),
  631. TP_fast_assign(
  632. __assign_str(memdev);
  633. __assign_str(host);
  634. __entry->serial = cxlmd->cxlds->serial;
  635. __entry->overflow_ts = cxl_poison_overflow(flags, overflow_ts);
  636. __entry->dpa = cxl_poison_record_dpa(record);
  637. __entry->dpa_length = cxl_poison_record_dpa_length(record);
  638. __entry->source = cxl_poison_record_source(record);
  639. __entry->trace_type = trace_type;
  640. __entry->flags = flags;
  641. if (cxlr) {
  642. __assign_str(region);
  643. memcpy(__entry->uuid, &cxlr->params.uuid, 16);
  644. __entry->hpa = cxl_dpa_to_hpa(cxlr, cxlmd,
  645. __entry->dpa);
  646. } else {
  647. __assign_str(region);
  648. memset(__entry->uuid, 0, 16);
  649. __entry->hpa = ULLONG_MAX;
  650. }
  651. ),
  652. TP_printk("memdev=%s host=%s serial=%lld trace_type=%s region=%s " \
  653. "region_uuid=%pU hpa=0x%llx dpa=0x%llx dpa_length=0x%x " \
  654. "source=%s flags=%s overflow_time=%llu",
  655. __get_str(memdev),
  656. __get_str(host),
  657. __entry->serial,
  658. show_poison_trace_type(__entry->trace_type),
  659. __get_str(region),
  660. __entry->uuid,
  661. __entry->hpa,
  662. __entry->dpa,
  663. __entry->dpa_length,
  664. show_poison_source(__entry->source),
  665. show_poison_flags(__entry->flags),
  666. __entry->overflow_ts
  667. )
  668. );
  669. #endif /* _CXL_EVENTS_H */
  670. #define TRACE_INCLUDE_FILE trace
  671. #include <trace/define_trace.h>