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

cxl/pci: Move tracepoint definitions to drivers/cxl/core/

CXL is using tracepoints for reporting RAS capability register payloads
for AER events, and has plans to use tracepoints for the output payload
of Get Poison List and Get Event Records commands. For organization
purposes it would be nice to keep those all under a single + local CXL
trace system. This also organization also potentially helps in the
future when CXL drivers expand beyond generic memory expanders, however
that would also entail a move away from the expander-specific
cxl_dev_state context, save that for later.

Note that the powerpc-specific drivers/misc/cxl/ also defines a 'cxl'
trace system, however, it is unlikely that a single platform will ever
load both drivers simultaneously.

Cc: Steven Rostedt <rostedt@goodmis.org>
Tested-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/167051869176.436579.9728373544811641087.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

+131 -118
+3
drivers/cxl/core/Makefile
··· 3 3 obj-$(CONFIG_CXL_SUSPEND) += suspend.o 4 4 5 5 ccflags-y += -I$(srctree)/drivers/cxl 6 + CFLAGS_trace.o = -DTRACE_INCLUDE_PATH=. -I$(src) 7 + 6 8 cxl_core-y := port.o 7 9 cxl_core-y += pmem.o 8 10 cxl_core-y += regs.o ··· 12 10 cxl_core-y += mbox.o 13 11 cxl_core-y += pci.o 14 12 cxl_core-y += hdm.o 13 + cxl_core-$(CONFIG_TRACING) += trace.o 15 14 cxl_core-$(CONFIG_CXL_REGION) += region.o
+112
drivers/cxl/core/pci.c
··· 9 9 #include <cxlmem.h> 10 10 #include <cxl.h> 11 11 #include "core.h" 12 + #include "trace.h" 12 13 13 14 /** 14 15 * DOC: cxl core pci ··· 623 622 } 624 623 } 625 624 EXPORT_SYMBOL_NS_GPL(read_cdat_data, CXL); 625 + 626 + void cxl_cor_error_detected(struct pci_dev *pdev) 627 + { 628 + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); 629 + struct cxl_memdev *cxlmd = cxlds->cxlmd; 630 + struct device *dev = &cxlmd->dev; 631 + void __iomem *addr; 632 + u32 status; 633 + 634 + if (!cxlds->regs.ras) 635 + return; 636 + 637 + addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_STATUS_OFFSET; 638 + status = readl(addr); 639 + if (status & CXL_RAS_CORRECTABLE_STATUS_MASK) { 640 + writel(status & CXL_RAS_CORRECTABLE_STATUS_MASK, addr); 641 + trace_cxl_aer_correctable_error(dev, status); 642 + } 643 + } 644 + EXPORT_SYMBOL_NS_GPL(cxl_cor_error_detected, CXL); 645 + 646 + /* CXL spec rev3.0 8.2.4.16.1 */ 647 + static void header_log_copy(struct cxl_dev_state *cxlds, u32 *log) 648 + { 649 + void __iomem *addr; 650 + u32 *log_addr; 651 + int i, log_u32_size = CXL_HEADERLOG_SIZE / sizeof(u32); 652 + 653 + addr = cxlds->regs.ras + CXL_RAS_HEADER_LOG_OFFSET; 654 + log_addr = log; 655 + 656 + for (i = 0; i < log_u32_size; i++) { 657 + *log_addr = readl(addr); 658 + log_addr++; 659 + addr += sizeof(u32); 660 + } 661 + } 662 + 663 + /* 664 + * Log the state of the RAS status registers and prepare them to log the 665 + * next error status. Return 1 if reset needed. 666 + */ 667 + static bool cxl_report_and_clear(struct cxl_dev_state *cxlds) 668 + { 669 + struct cxl_memdev *cxlmd = cxlds->cxlmd; 670 + struct device *dev = &cxlmd->dev; 671 + u32 hl[CXL_HEADERLOG_SIZE_U32]; 672 + void __iomem *addr; 673 + u32 status; 674 + u32 fe; 675 + 676 + if (!cxlds->regs.ras) 677 + return false; 678 + 679 + addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_STATUS_OFFSET; 680 + status = readl(addr); 681 + if (!(status & CXL_RAS_UNCORRECTABLE_STATUS_MASK)) 682 + return false; 683 + 684 + /* If multiple errors, log header points to first error from ctrl reg */ 685 + if (hweight32(status) > 1) { 686 + addr = cxlds->regs.ras + CXL_RAS_CAP_CONTROL_OFFSET; 687 + fe = BIT(FIELD_GET(CXL_RAS_CAP_CONTROL_FE_MASK, readl(addr))); 688 + } else { 689 + fe = status; 690 + } 691 + 692 + header_log_copy(cxlds, hl); 693 + trace_cxl_aer_uncorrectable_error(dev, status, fe, hl); 694 + writel(status & CXL_RAS_UNCORRECTABLE_STATUS_MASK, addr); 695 + 696 + return true; 697 + } 698 + 699 + pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, 700 + pci_channel_state_t state) 701 + { 702 + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); 703 + struct cxl_memdev *cxlmd = cxlds->cxlmd; 704 + struct device *dev = &cxlmd->dev; 705 + bool ue; 706 + 707 + /* 708 + * A frozen channel indicates an impending reset which is fatal to 709 + * CXL.mem operation, and will likely crash the system. On the off 710 + * chance the situation is recoverable dump the status of the RAS 711 + * capability registers and bounce the active state of the memdev. 712 + */ 713 + ue = cxl_report_and_clear(cxlds); 714 + 715 + switch (state) { 716 + case pci_channel_io_normal: 717 + if (ue) { 718 + device_release_driver(dev); 719 + return PCI_ERS_RESULT_NEED_RESET; 720 + } 721 + return PCI_ERS_RESULT_CAN_RECOVER; 722 + case pci_channel_io_frozen: 723 + dev_warn(&pdev->dev, 724 + "%s: frozen state error detected, disable CXL.mem\n", 725 + dev_name(dev)); 726 + device_release_driver(dev); 727 + return PCI_ERS_RESULT_NEED_RESET; 728 + case pci_channel_io_perm_failure: 729 + dev_warn(&pdev->dev, 730 + "failure state error detected, request disconnect\n"); 731 + return PCI_ERS_RESULT_DISCONNECT; 732 + } 733 + return PCI_ERS_RESULT_NEED_RESET; 734 + } 735 + EXPORT_SYMBOL_NS_GPL(cxl_error_detected, CXL);
+5
drivers/cxl/core/trace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 3 + 4 + #define CREATE_TRACE_POINTS 5 + #include "trace.h"
+2
drivers/cxl/cxl.h
··· 140 140 #define CXL_RAS_CAP_CONTROL_FE_MASK GENMASK(5, 0) 141 141 #define CXL_RAS_HEADER_LOG_OFFSET 0x18 142 142 #define CXL_RAS_CAPABILITY_LENGTH 0x58 143 + #define CXL_HEADERLOG_SIZE SZ_512 144 + #define CXL_HEADERLOG_SIZE_U32 SZ_512 / sizeof(u32) 143 145 144 146 /* CXL 2.0 8.2.8.1 Device Capabilities Array Register */ 145 147 #define CXLDEV_CAP_ARRAY_OFFSET 0x0
+3
drivers/cxl/cxlpci.h
··· 66 66 struct cxl_dev_state; 67 67 int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm); 68 68 void read_cdat_data(struct cxl_port *port); 69 + void cxl_cor_error_detected(struct pci_dev *pdev); 70 + pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, 71 + pci_channel_state_t state); 69 72 #endif /* __CXL_PCI_H__ */
-111
drivers/cxl/pci.c
··· 14 14 #include "cxlmem.h" 15 15 #include "cxlpci.h" 16 16 #include "cxl.h" 17 - #define CREATE_TRACE_POINTS 18 - #include <trace/events/cxl.h> 19 17 20 18 /** 21 19 * DOC: cxl pci ··· 512 514 }; 513 515 MODULE_DEVICE_TABLE(pci, cxl_mem_pci_tbl); 514 516 515 - /* CXL spec rev3.0 8.2.4.16.1 */ 516 - static void header_log_copy(struct cxl_dev_state *cxlds, u32 *log) 517 - { 518 - void __iomem *addr; 519 - u32 *log_addr; 520 - int i, log_u32_size = CXL_HEADERLOG_SIZE / sizeof(u32); 521 - 522 - addr = cxlds->regs.ras + CXL_RAS_HEADER_LOG_OFFSET; 523 - log_addr = log; 524 - 525 - for (i = 0; i < log_u32_size; i++) { 526 - *log_addr = readl(addr); 527 - log_addr++; 528 - addr += sizeof(u32); 529 - } 530 - } 531 - 532 - /* 533 - * Log the state of the RAS status registers and prepare them to log the 534 - * next error status. Return 1 if reset needed. 535 - */ 536 - static bool cxl_report_and_clear(struct cxl_dev_state *cxlds) 537 - { 538 - struct cxl_memdev *cxlmd = cxlds->cxlmd; 539 - struct device *dev = &cxlmd->dev; 540 - u32 hl[CXL_HEADERLOG_SIZE_U32]; 541 - void __iomem *addr; 542 - u32 status; 543 - u32 fe; 544 - 545 - if (!cxlds->regs.ras) 546 - return false; 547 - 548 - addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_STATUS_OFFSET; 549 - status = readl(addr); 550 - if (!(status & CXL_RAS_UNCORRECTABLE_STATUS_MASK)) 551 - return false; 552 - 553 - /* If multiple errors, log header points to first error from ctrl reg */ 554 - if (hweight32(status) > 1) { 555 - addr = cxlds->regs.ras + CXL_RAS_CAP_CONTROL_OFFSET; 556 - fe = BIT(FIELD_GET(CXL_RAS_CAP_CONTROL_FE_MASK, readl(addr))); 557 - } else { 558 - fe = status; 559 - } 560 - 561 - header_log_copy(cxlds, hl); 562 - trace_cxl_aer_uncorrectable_error(dev, status, fe, hl); 563 - writel(status & CXL_RAS_UNCORRECTABLE_STATUS_MASK, addr); 564 - 565 - return true; 566 - } 567 - 568 - static pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, 569 - pci_channel_state_t state) 570 - { 571 - struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); 572 - struct cxl_memdev *cxlmd = cxlds->cxlmd; 573 - struct device *dev = &cxlmd->dev; 574 - bool ue; 575 - 576 - /* 577 - * A frozen channel indicates an impending reset which is fatal to 578 - * CXL.mem operation, and will likely crash the system. On the off 579 - * chance the situation is recoverable dump the status of the RAS 580 - * capability registers and bounce the active state of the memdev. 581 - */ 582 - ue = cxl_report_and_clear(cxlds); 583 - 584 - switch (state) { 585 - case pci_channel_io_normal: 586 - if (ue) { 587 - device_release_driver(dev); 588 - return PCI_ERS_RESULT_NEED_RESET; 589 - } 590 - return PCI_ERS_RESULT_CAN_RECOVER; 591 - case pci_channel_io_frozen: 592 - dev_warn(&pdev->dev, 593 - "%s: frozen state error detected, disable CXL.mem\n", 594 - dev_name(dev)); 595 - device_release_driver(dev); 596 - return PCI_ERS_RESULT_NEED_RESET; 597 - case pci_channel_io_perm_failure: 598 - dev_warn(&pdev->dev, 599 - "failure state error detected, request disconnect\n"); 600 - return PCI_ERS_RESULT_DISCONNECT; 601 - } 602 - return PCI_ERS_RESULT_NEED_RESET; 603 - } 604 - 605 517 static pci_ers_result_t cxl_slot_reset(struct pci_dev *pdev) 606 518 { 607 519 struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); ··· 534 626 535 627 dev_info(&pdev->dev, "%s: error resume %s\n", dev_name(dev), 536 628 dev->driver ? "successful" : "failed"); 537 - } 538 - 539 - static void cxl_cor_error_detected(struct pci_dev *pdev) 540 - { 541 - struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); 542 - struct cxl_memdev *cxlmd = cxlds->cxlmd; 543 - struct device *dev = &cxlmd->dev; 544 - void __iomem *addr; 545 - u32 status; 546 - 547 - if (!cxlds->regs.ras) 548 - return; 549 - 550 - addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_STATUS_OFFSET; 551 - status = readl(addr); 552 - if (status & CXL_RAS_CORRECTABLE_STATUS_MASK) { 553 - writel(status & CXL_RAS_CORRECTABLE_STATUS_MASK, addr); 554 - trace_cxl_aer_correctable_error(dev, status); 555 - } 556 629 } 557 630 558 631 static const struct pci_error_handlers cxl_error_handlers = {
+4 -7
include/trace/events/cxl.h drivers/cxl/core/trace.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 2 3 #undef TRACE_SYSTEM 3 4 #define TRACE_SYSTEM cxl 4 5 5 6 #if !defined(_CXL_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) 6 7 #define _CXL_EVENTS_H 7 8 9 + #include <cxl.h> 8 10 #include <linux/tracepoint.h> 9 - 10 - #define CXL_HEADERLOG_SIZE SZ_512 11 - #define CXL_HEADERLOG_SIZE_U32 SZ_512 / sizeof(u32) 12 11 13 12 #define CXL_RAS_UC_CACHE_DATA_PARITY BIT(0) 14 13 #define CXL_RAS_UC_CACHE_ADDR_PARITY BIT(1) ··· 105 106 106 107 #endif /* _CXL_EVENTS_H */ 107 108 108 - /* This part must be outside protection */ 109 - #undef TRACE_INCLUDE_FILE 110 - #define TRACE_INCLUDE_FILE cxl 109 + #define TRACE_INCLUDE_FILE trace 111 110 #include <trace/define_trace.h>
+2
tools/testing/cxl/Kbuild
··· 17 17 CXL_CORE_SRC := $(DRIVERS)/cxl/core 18 18 ccflags-y := -I$(srctree)/drivers/cxl/ 19 19 ccflags-y += -D__mock=__weak 20 + ccflags-y += -DTRACE_INCLUDE_PATH=$(CXL_CORE_SRC) -I$(srctree)/drivers/cxl/core/ 20 21 21 22 obj-m += cxl_acpi.o 22 23 ··· 50 49 cxl_core-y += $(CXL_CORE_SRC)/mbox.o 51 50 cxl_core-y += $(CXL_CORE_SRC)/pci.o 52 51 cxl_core-y += $(CXL_CORE_SRC)/hdm.o 52 + cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o 53 53 cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o 54 54 cxl_core-y += config_check.o 55 55