From patchwork Thu Dec 1 00:27:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72DD8C47088 for ; Thu, 1 Dec 2022 00:27:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229669AbiLAA1b (ORCPT ); Wed, 30 Nov 2022 19:27:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229630AbiLAA1a (ORCPT ); Wed, 30 Nov 2022 19:27:30 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C80E5A6FC; Wed, 30 Nov 2022 16:27:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854450; x=1701390450; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jPVREGs4PLxqhrqWqF2Ad6QbSt6TWQhJhSrq1eRjL58=; b=Xsu2AUBn94ks2GT7ASdm1MlBw/P3jz2A7KWHJ1GigRdEEZXJFdKIrp1M tjBdm+djKH2FxO69auAHzLkNKL6tWEIg4oKKc05FPY9S14oj/Hg8UK20v pY1NAUHMgyqpGTtxrWvgYK0+44yhrjbZ3gelv90F1Ja0EjUAYpbSL9t/S +YT537uaeiyUaCycSpIsc6yBYXvLhkNtVJdkztVkNnjWKt9MBghCTK4qC nwN49OzPZApm0lxshsJX/2ngkys0Ru5sa7QHIXl7tndptgjWmxjVN8SBF d7on+pi+kXt6/+AZzbdKZBPsFGfPr9/azK+r4cACn2tC6+hkiBcekyDgD A==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400820" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400820" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:27 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085203" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085203" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:26 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Davidlohr Bueso , Bjorn Helgaas , Jonathan Cameron , Ira Weiny , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 01/11] cxl/pci: Add generic MSI-X/MSI irq support Date: Wed, 30 Nov 2022 16:27:09 -0800 Message-Id: <20221201002719.2596558-2-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Davidlohr Bueso Currently the only CXL features targeted for irq support require their message numbers to be within the first 16 entries. The device may however support less than 16 entries depending on the support it provides. Attempt to allocate these 16 irq vectors. If the device supports less then the PCI infrastructure will allocate that number. Store the number of vectors actually allocated in the device state for later use by individual functions. Upon successful allocation, users can plug in their respective isr at any point thereafter, for example, if the irq setup is not done in the PCI driver, such as the case of the CXL-PMU. Cc: Bjorn Helgaas Cc: Jonathan Cameron Co-developed-by: Ira Weiny Signed-off-by: Ira Weiny Signed-off-by: Davidlohr Bueso Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang --- Changes from V1: Jonathan pci_alloc_irq_vectors() cleans up the vectors automatically use msi_enabled rather than nr_irq_vecs Changes from Ira Remove reviews Allocate up to a static 16 vectors. Change cover letter --- drivers/cxl/cxlmem.h | 3 +++ drivers/cxl/cxlpci.h | 6 ++++++ drivers/cxl/pci.c | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 88e3a8e54b6a..cd35f43fedd4 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { * @info: Cached DVSEC information about the device. * @serial: PCIe Device Serial Number * @doe_mbs: PCI DOE mailbox array + * @msi_enabled: MSI-X/MSI has been enabled * @mbox_send: @dev specific transport for transmitting mailbox commands * * See section 8.2.9.5.2 Capacity Configuration and Label Storage for @@ -247,6 +248,8 @@ struct cxl_dev_state { struct xarray doe_mbs; + bool msi_enabled; + int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); }; diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h index eec597dbe763..b7f4e2f417d3 100644 --- a/drivers/cxl/cxlpci.h +++ b/drivers/cxl/cxlpci.h @@ -53,6 +53,12 @@ #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) +/* + * NOTE: Currently all the functions which are enabled for CXL require their + * vectors to be in the first 16. Use this as the max. + */ +#define CXL_PCI_REQUIRED_VECTORS 16 + /* Register Block Identifier (RBI) */ enum cxl_regloc_type { CXL_REGLOC_RBI_EMPTY = 0, diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index faeb5d9d7a7a..8f86f85d89c7 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -428,6 +428,27 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) } } +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) +{ + struct device *dev = cxlds->dev; + struct pci_dev *pdev = to_pci_dev(dev); + int nvecs; + + /* + * NOTE: pci_alloc_irq_vectors() handles calling pci_free_irq_vectors() + * automatically despite not being called pcim_*. See + * pci_setup_msi_context(). + */ + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, + PCI_IRQ_MSIX | PCI_IRQ_MSI); + if (nvecs < 0) { + dev_dbg(dev, "Failed to alloc irq vectors; use polling instead.\n"); + return; + } + + cxlds->msi_enabled = true; +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct cxl_register_map map; @@ -494,6 +515,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; + cxl_pci_alloc_irq_vectors(cxlds); + cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); From patchwork Thu Dec 1 00:27:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060849 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAA7EC352A1 for ; Thu, 1 Dec 2022 00:27:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229685AbiLAA1c (ORCPT ); Wed, 30 Nov 2022 19:27:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229646AbiLAA1b (ORCPT ); Wed, 30 Nov 2022 19:27:31 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10F9258BC9; Wed, 30 Nov 2022 16:27:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854450; x=1701390450; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/8w1QQaWkm5UKaz/nPkP8abCbTcBgZzGivJwx9ZxWNw=; b=L7vmTABrVRTt5osahu5YS1N11PUZIJR8zYzwPbg/1FG6LHVczTwcXu+E YIyFELnnfWJJJBSReqJyrQ8DWjcvf4b2m4UeHI66EZ5A1ICj+ELAqfQuf 7VJJ8K3lYPCGn/IpWShKmogxzZt7S5vF96+KBoFfWyuR15hhUOjsny9Y3 0taPns/fSGUzFV+49KF4yNOJPzbAztpGzy2qJJxG8/uTUdKYJGg9gcPS4 0eapFHWU+L5/xaj1+8fG4mPdTGtPgtUNbOYtBqVZP/y5KnRXIi2sE7NoD 0Tb+rGwPTDhvt+ue4rEINpmMqJWCj/jpsGLZpgGc64HDFL7mYwCK5wuuC w==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400830" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400830" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:28 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085213" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085213" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:27 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Steven Rostedt , Alison Schofield , Vishal Verma , Ben Widawsky , Jonathan Cameron , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 02/11] cxl/mem: Implement Get Event Records command Date: Wed, 30 Nov 2022 16:27:10 -0800 Message-Id: <20221201002719.2596558-3-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL devices have multiple event logs which can be queried for CXL event records. Devices are required to support the storage of at least one event record in each event log type. Devices track event log overflow by incrementing a counter and tracking the time of the first and last overflow event seen. Software queries events via the Get Event Record mailbox command; CXL rev 3.0 section 8.2.9.2.2. Issue the Get Event Record mailbox command on driver load. Trace each record found with a generic record trace. Trace any overflow conditions. The device can return up to 1MB worth of event records per query. Allocate a shared large buffer to handle the max number of records based on the mailbox payload size. This patch traces a raw event record only and leaves the specific event record types to subsequent patches. Macros are created to use for tracing the common CXL Event header fields. Cc: Steven Rostedt Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron --- Change from V1: Ignore useless More Event Flag defer DCD support Jonathan delete extra blank line Use all caps for flags Jonathan/Dan/Ira Allocate event MB buffer on start up. Alison s/pl_nr/nr_pl Change from RFC v2: Support reading 3 events at once. Reverse Jonathan's suggestion and check for positive number of records. Because the record count may have been returned as something > 3 based on what the device thinks it can send back even though the core Linux mbox processing truncates the data. Alison and Dave Jiang Change header uuid type to uuid_t for better user space processing Smita Check status reg before reading log. Steven Prefix all trace points with 'cxl_' Use static branch _enabled() calls Jonathan s/CXL_EVENT_TYPE_INFO/0 s/{first,last}/{first,last}_ts Remove Reserved field from header Fix header issue for cxl_event_log_type_str() Change from RFC: Remove redundant error message in get event records loop s/EVENT_RECORD_DATA_LENGTH/CXL_EVENT_RECORD_DATA_LENGTH Use hdr_uuid for the header UUID field Use cxl_event_log_type_str() for the trace events Create macros for the header fields and common entries of each event Add reserved buffer output dump Report error if event query fails Remove unused record_cnt variable Steven - reorder overflow record Remove NOTE about checkpatch Jonathan check for exactly 1 record s/v3.0/rev 3.0 Use 3 byte fields for 24bit fields Add 3.0 Maintenance Operation Class Add Dynamic Capacity log type Fix spelling Dave Jiang/Dan/Alison s/cxl-event/cxl trace/events/cxl-events => trace/events/cxl.h s/cxl_event_overflow/overflow s/cxl_event/generic_event --- MAINTAINERS | 1 + drivers/cxl/core/mbox.c | 105 +++++++++++++++++++++++++++++ drivers/cxl/cxl.h | 7 ++ drivers/cxl/cxlmem.h | 72 ++++++++++++++++++++ include/trace/events/cxl.h | 126 +++++++++++++++++++++++++++++++++++ include/uapi/linux/cxl_mem.h | 1 + 6 files changed, 312 insertions(+) create mode 100644 include/trace/events/cxl.h diff --git a/MAINTAINERS b/MAINTAINERS index ca063a504026..4b7c6e3055c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5223,6 +5223,7 @@ M: Dan Williams L: linux-cxl@vger.kernel.org S: Maintained F: drivers/cxl/ +F: include/trace/events/cxl.h F: include/uapi/linux/cxl_mem.h CONEXANT ACCESSRUNNER USB DRIVER diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 16176b9278b4..70b681027a3d 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -7,6 +7,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + #include "core.h" static bool cxl_raw_allow_all; @@ -48,6 +51,7 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { CXL_CMD(RAW, CXL_VARIABLE_PAYLOAD, CXL_VARIABLE_PAYLOAD, 0), #endif CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE), + CXL_CMD(GET_EVENT_RECORD, 1, CXL_VARIABLE_PAYLOAD, 0), CXL_CMD(GET_FW_INFO, 0, 0x50, 0), CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0), CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0), @@ -704,6 +708,106 @@ int cxl_enumerate_cmds(struct cxl_dev_state *cxlds) } EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL); +static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, + enum cxl_event_log_type type) +{ + struct cxl_get_event_payload *payload; + u16 nr_rec; + + mutex_lock(&cxlds->event_buf_lock); + + payload = cxlds->event_buf; + + do { + u8 log_type = type; + int rc; + + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_EVENT_RECORD, + &log_type, sizeof(log_type), + payload, cxlds->payload_size); + if (rc) { + dev_err(cxlds->dev, "Event log '%s': Failed to query event records : %d", + cxl_event_log_type_str(type), rc); + goto unlock_buffer; + } + + nr_rec = le16_to_cpu(payload->record_count); + if (trace_cxl_generic_event_enabled()) { + int i; + + for (i = 0; i < nr_rec; i++) + trace_cxl_generic_event(dev_name(cxlds->dev), + type, + &payload->records[i]); + } + + if (trace_cxl_overflow_enabled() && + (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW)) + trace_cxl_overflow(dev_name(cxlds->dev), type, payload); + + } while (nr_rec); + +unlock_buffer: + mutex_unlock(&cxlds->event_buf_lock); +} + +static void cxl_mem_free_event_buffer(void *data) +{ + struct cxl_dev_state *cxlds = data; + + kvfree(cxlds->event_buf); +} + +/* + * There is a single buffer for reading event logs from the mailbox. All logs + * share this buffer protected by the cxlds->event_buf_lock. + */ +static struct cxl_get_event_payload *alloc_event_buf(struct cxl_dev_state *cxlds) +{ + struct cxl_get_event_payload *buf; + + dev_dbg(cxlds->dev, "Allocating event buffer size %zu\n", + cxlds->payload_size); + + buf = kvmalloc(cxlds->payload_size, GFP_KERNEL); + if (buf && devm_add_action_or_reset(cxlds->dev, + cxl_mem_free_event_buffer, cxlds)) + return NULL; + return buf; +} + +/** + * cxl_mem_get_event_records - Get Event Records from the device + * @cxlds: The device data for the operation + * + * Retrieve all event records available on the device and report them as trace + * events. + * + * See CXL rev 3.0 @8.2.9.2.2 Get Event Records + */ +void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) +{ + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + dev_dbg(cxlds->dev, "Reading event logs: %x\n", status); + + if (!cxlds->event_buf) { + cxlds->event_buf = alloc_event_buf(cxlds); + if (WARN_ON_ONCE(!cxlds->event_buf)) + return; + } + + if (status & CXLDEV_EVENT_STATUS_INFO) + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_INFO); + if (status & CXLDEV_EVENT_STATUS_WARN) + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_WARN); + if (status & CXLDEV_EVENT_STATUS_FAIL) + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_FAIL); + if (status & CXLDEV_EVENT_STATUS_FATAL) + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_FATAL); +} +EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL); + /** * cxl_mem_get_partition_info - Get partition info * @cxlds: The device data for the operation @@ -846,6 +950,7 @@ struct cxl_dev_state *cxl_dev_state_create(struct device *dev) } mutex_init(&cxlds->mbox_mutex); + mutex_init(&cxlds->event_buf_lock); cxlds->dev = dev; return cxlds; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index f680450f0b16..d4baae74cd97 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -132,6 +132,13 @@ static inline int ways_to_cxl(unsigned int ways, u8 *iw) #define CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX 0x3 #define CXLDEV_CAP_CAP_ID_MEMDEV 0x4000 +/* CXL 3.0 8.2.8.3.1 Event Status Register */ +#define CXLDEV_DEV_EVENT_STATUS_OFFSET 0x00 +#define CXLDEV_EVENT_STATUS_INFO BIT(0) +#define CXLDEV_EVENT_STATUS_WARN BIT(1) +#define CXLDEV_EVENT_STATUS_FAIL BIT(2) +#define CXLDEV_EVENT_STATUS_FATAL BIT(3) + /* CXL 2.0 8.2.8.4 Mailbox Registers */ #define CXLDEV_MBOX_CAPS_OFFSET 0x00 #define CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK GENMASK(4, 0) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index cd35f43fedd4..55d57f5a64bc 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -4,6 +4,7 @@ #define __CXL_MEM_H__ #include #include +#include #include "cxl.h" /* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */ @@ -250,12 +251,16 @@ struct cxl_dev_state { bool msi_enabled; + struct cxl_get_event_payload *event_buf; + struct mutex event_buf_lock; + int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); }; enum cxl_opcode { CXL_MBOX_OP_INVALID = 0x0000, CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID, + CXL_MBOX_OP_GET_EVENT_RECORD = 0x0100, CXL_MBOX_OP_GET_FW_INFO = 0x0200, CXL_MBOX_OP_ACTIVATE_FW = 0x0202, CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400, @@ -325,6 +330,72 @@ struct cxl_mbox_identify { u8 qos_telemetry_caps; } __packed; +/* + * Common Event Record Format + * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 + */ +struct cxl_event_record_hdr { + uuid_t id; + u8 length; + u8 flags[3]; + __le16 handle; + __le16 related_handle; + __le64 timestamp; + u8 maint_op_class; + u8 reserved[0xf]; +} __packed; + +#define CXL_EVENT_RECORD_DATA_LENGTH 0x50 +struct cxl_event_record_raw { + struct cxl_event_record_hdr hdr; + u8 data[CXL_EVENT_RECORD_DATA_LENGTH]; +} __packed; + +/* + * Get Event Records output payload + * CXL rev 3.0 section 8.2.9.2.2; Table 8-50 + */ +#define CXL_GET_EVENT_FLAG_OVERFLOW BIT(0) +#define CXL_GET_EVENT_FLAG_MORE_RECORDS BIT(1) +struct cxl_get_event_payload { + u8 flags; + u8 reserved1; + __le16 overflow_err_count; + __le64 first_overflow_timestamp; + __le64 last_overflow_timestamp; + __le16 record_count; + u8 reserved2[0xa]; + struct cxl_event_record_raw records[]; +} __packed; + +/* + * CXL rev 3.0 section 8.2.9.2.2; Table 8-49 + */ +enum cxl_event_log_type { + CXL_EVENT_TYPE_INFO = 0x00, + CXL_EVENT_TYPE_WARN, + CXL_EVENT_TYPE_FAIL, + CXL_EVENT_TYPE_FATAL, + CXL_EVENT_TYPE_MAX +}; + +static inline const char *cxl_event_log_type_str(enum cxl_event_log_type type) +{ + switch (type) { + case CXL_EVENT_TYPE_INFO: + return "Informational"; + case CXL_EVENT_TYPE_WARN: + return "Warning"; + case CXL_EVENT_TYPE_FAIL: + return "Failure"; + case CXL_EVENT_TYPE_FATAL: + return "Fatal"; + default: + break; + } + return ""; +} + struct cxl_mbox_get_partition_info { __le64 active_volatile_cap; __le64 active_persistent_cap; @@ -384,6 +455,7 @@ int cxl_mem_create_range_info(struct cxl_dev_state *cxlds); struct cxl_dev_state *cxl_dev_state_create(struct device *dev); void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); +void cxl_mem_get_event_records(struct cxl_dev_state *cxlds); #ifdef CONFIG_CXL_SUSPEND void cxl_mem_active_inc(void); void cxl_mem_active_dec(void); diff --git a/include/trace/events/cxl.h b/include/trace/events/cxl.h new file mode 100644 index 000000000000..c03a1a894af8 --- /dev/null +++ b/include/trace/events/cxl.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM cxl + +#if !defined(_CXL_TRACE_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _CXL_TRACE_EVENTS_H + +#include +#include +#include + +TRACE_EVENT(cxl_overflow, + + TP_PROTO(const char *dev_name, enum cxl_event_log_type log, + struct cxl_get_event_payload *payload), + + TP_ARGS(dev_name, log, payload), + + TP_STRUCT__entry( + __string(dev_name, dev_name) + __field(int, log) + __field(u64, first_ts) + __field(u64, last_ts) + __field(u16, count) + ), + + TP_fast_assign( + __assign_str(dev_name, dev_name); + __entry->log = log; + __entry->count = le16_to_cpu(payload->overflow_err_count); + __entry->first_ts = le64_to_cpu(payload->first_overflow_timestamp); + __entry->last_ts = le64_to_cpu(payload->last_overflow_timestamp); + ), + + TP_printk("%s: EVENT LOG OVERFLOW log=%s : %u records from %llu to %llu", + __get_str(dev_name), cxl_event_log_type_str(__entry->log), + __entry->count, __entry->first_ts, __entry->last_ts) + +); + +/* + * Common Event Record Format + * CXL 3.0 section 8.2.9.2.1; Table 8-42 + */ +#define CXL_EVENT_RECORD_FLAG_PERMANENT BIT(2) +#define CXL_EVENT_RECORD_FLAG_MAINT_NEEDED BIT(3) +#define CXL_EVENT_RECORD_FLAG_PERF_DEGRADED BIT(4) +#define CXL_EVENT_RECORD_FLAG_HW_REPLACE BIT(5) +#define show_hdr_flags(flags) __print_flags(flags, " | ", \ + { CXL_EVENT_RECORD_FLAG_PERMANENT, "PERMANENT_CONDITION" }, \ + { CXL_EVENT_RECORD_FLAG_MAINT_NEEDED, "MAINTENANCE_NEEDED" }, \ + { CXL_EVENT_RECORD_FLAG_PERF_DEGRADED, "PERFORMANCE_DEGRADED" }, \ + { CXL_EVENT_RECORD_FLAG_HW_REPLACE, "HARDWARE_REPLACEMENT_NEEDED" } \ +) + +/* + * Define macros for the common header of each CXL event. + * + * Tracepoints using these macros must do 3 things: + * + * 1) Add CXL_EVT_TP_entry to TP_STRUCT__entry + * 2) Use CXL_EVT_TP_fast_assign within TP_fast_assign; + * pass the dev_name, log, and CXL event header + * 3) Use CXL_EVT_TP_printk() instead of TP_printk() + * + * See the generic_event tracepoint as an example. + */ +#define CXL_EVT_TP_entry \ + __string(dev_name, dev_name) \ + __field(int, log) \ + __field_struct(uuid_t, hdr_uuid) \ + __field(u32, hdr_flags) \ + __field(u16, hdr_handle) \ + __field(u16, hdr_related_handle) \ + __field(u64, hdr_timestamp) \ + __field(u8, hdr_length) \ + __field(u8, hdr_maint_op_class) + +#define CXL_EVT_TP_fast_assign(dname, l, hdr) \ + __assign_str(dev_name, (dname)); \ + __entry->log = (l); \ + memcpy(&__entry->hdr_uuid, &(hdr).id, sizeof(uuid_t)); \ + __entry->hdr_length = (hdr).length; \ + __entry->hdr_flags = get_unaligned_le24((hdr).flags); \ + __entry->hdr_handle = le16_to_cpu((hdr).handle); \ + __entry->hdr_related_handle = le16_to_cpu((hdr).related_handle); \ + __entry->hdr_timestamp = le64_to_cpu((hdr).timestamp); \ + __entry->hdr_maint_op_class = (hdr).maint_op_class + +#define CXL_EVT_TP_printk(fmt, ...) \ + TP_printk("%s log=%s : time=%llu uuid=%pUb len=%d flags='%s' " \ + "handle=%x related_handle=%x maint_op_class=%u" \ + " : " fmt, \ + __get_str(dev_name), cxl_event_log_type_str(__entry->log), \ + __entry->hdr_timestamp, &__entry->hdr_uuid, __entry->hdr_length,\ + show_hdr_flags(__entry->hdr_flags), __entry->hdr_handle, \ + __entry->hdr_related_handle, __entry->hdr_maint_op_class, \ + ##__VA_ARGS__) + +TRACE_EVENT(cxl_generic_event, + + TP_PROTO(const char *dev_name, enum cxl_event_log_type log, + struct cxl_event_record_raw *rec), + + TP_ARGS(dev_name, log, rec), + + TP_STRUCT__entry( + CXL_EVT_TP_entry + __array(u8, data, CXL_EVENT_RECORD_DATA_LENGTH) + ), + + TP_fast_assign( + CXL_EVT_TP_fast_assign(dev_name, log, rec->hdr); + memcpy(__entry->data, &rec->data, CXL_EVENT_RECORD_DATA_LENGTH); + ), + + CXL_EVT_TP_printk("%s", + __print_hex(__entry->data, CXL_EVENT_RECORD_DATA_LENGTH)) +); + +#endif /* _CXL_TRACE_EVENTS_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE cxl +#include diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h index c71021a2a9ed..70459be5bdd4 100644 --- a/include/uapi/linux/cxl_mem.h +++ b/include/uapi/linux/cxl_mem.h @@ -24,6 +24,7 @@ ___C(IDENTIFY, "Identify Command"), \ ___C(RAW, "Raw device command"), \ ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), \ + ___C(GET_EVENT_RECORD, "Get Event Record"), \ ___C(GET_FW_INFO, "Get FW Info"), \ ___C(GET_PARTITION_INFO, "Get Partition Information"), \ ___C(GET_LSA, "Get Label Storage Area"), \ From patchwork Thu Dec 1 00:27:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060848 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76986C4708E for ; Thu, 1 Dec 2022 00:27:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229612AbiLAA1c (ORCPT ); Wed, 30 Nov 2022 19:27:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229675AbiLAA1b (ORCPT ); Wed, 30 Nov 2022 19:27:31 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3E925803E; Wed, 30 Nov 2022 16:27:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854450; x=1701390450; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jXysWS4Ez9au+rW5fyav+5s0bOnnmJEkvkXUz0fzpXM=; b=R/EhuWUKEnSKvXQKocMczcL0A+n5+j2ZJgOyVaQT5fzMD5ZXsZL6M43E y0Xqo+AdHvWN76Yngz8v6llJqEv2a2EobBclQMRO+S9FZEvTqZ81rGm6y Bzl4y4QWHOqFjLelN4udWKOeNa4NUV9ckTAS14yvXewH/7ivFzrGJhSrH dQDJ8V/FNycw28P5/uEvOhcDydmIpHxpMPqGpqXD/wyRXBxAzR/KOuwvp WM1bkZ0zWT/dfeoLtGqCy+4Cwr7JHvpyeyIdEJ0CzoVwen7qSAGcHKYPb QUpHH+A0HGVm0LKjOxgqA25yRIF8KlGU9v9+h66Oe6aa2cvLIUxL4YyMC g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400840" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400840" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:29 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085218" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085218" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:28 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Jonathan Cameron , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 03/11] cxl/mem: Implement Clear Event Records command Date: Wed, 30 Nov 2022 16:27:11 -0800 Message-Id: <20221201002719.2596558-4-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL rev 3.0 section 8.2.9.2.3 defines the Clear Event Records mailbox command. After an event record is read it needs to be cleared from the event log. Implement cxl_clear_event_record() to clear all record retrieved from the device. Each record is cleared explicitly. A clear all bit is specified but events could arrive between a get and any final clear all operation. This means events would be missed. Therefore each event is cleared specifically. Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron --- Changes from V1: Clear Event Record allows for u8 handles while Get Event Record allows for u16 records to be returned. Based on Jonathan's feedback; allow for all event records to be handled in this clear. Which means a double loop with potentially multiple Clear Event payloads being sent to clear all events sent. Changes from RFC: Jonathan Clean up init of payload and use return code. Also report any error to clear the event. s/v3.0/rev 3.0 --- drivers/cxl/core/mbox.c | 61 +++++++++++++++++++++++++++++++----- drivers/cxl/cxlmem.h | 14 +++++++++ include/uapi/linux/cxl_mem.h | 1 + 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 70b681027a3d..076a3df0ba38 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -52,6 +52,7 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { #endif CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE), CXL_CMD(GET_EVENT_RECORD, 1, CXL_VARIABLE_PAYLOAD, 0), + CXL_CMD(CLEAR_EVENT_RECORD, CXL_VARIABLE_PAYLOAD, 0, 0), CXL_CMD(GET_FW_INFO, 0, 0x50, 0), CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0), CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0), @@ -708,6 +709,42 @@ int cxl_enumerate_cmds(struct cxl_dev_state *cxlds) } EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL); +static int cxl_clear_event_record(struct cxl_dev_state *cxlds, + enum cxl_event_log_type log, + struct cxl_get_event_payload *get_pl, + u16 total) +{ + struct cxl_mbox_clear_event_payload payload = { + .event_log = log, + }; + int cnt; + + /* + * Clear Event Records uses u8 for the handle cnt while Get Event + * Record can return up to 0xffff records. + */ + for (cnt = 0; cnt < total; /* cnt incremented internally */) { + u8 nr_recs = min_t(u8, (total - cnt), + CXL_CLEAR_EVENT_MAX_HANDLES); + int i, rc; + + for (i = 0; i < nr_recs; i++, cnt++) { + payload.handle[i] = get_pl->records[cnt].hdr.handle; + dev_dbg(cxlds->dev, "Event log '%s': Clearning %u\n", + cxl_event_log_type_str(log), + le16_to_cpu(payload.handle[i])); + } + payload.nr_recs = nr_recs; + + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_CLEAR_EVENT_RECORD, + &payload, sizeof(payload), NULL, 0); + if (rc) + return rc; + } + + return 0; +} + static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, enum cxl_event_log_type type) { @@ -732,13 +769,22 @@ static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, } nr_rec = le16_to_cpu(payload->record_count); - if (trace_cxl_generic_event_enabled()) { + if (nr_rec > 0) { int i; - for (i = 0; i < nr_rec; i++) - trace_cxl_generic_event(dev_name(cxlds->dev), - type, - &payload->records[i]); + if (trace_cxl_generic_event_enabled()) { + for (i = 0; i < nr_rec; i++) + trace_cxl_generic_event(dev_name(cxlds->dev), + type, + &payload->records[i]); + } + + rc = cxl_clear_event_record(cxlds, type, payload, nr_rec); + if (rc) { + dev_err(cxlds->dev, "Event log '%s': Failed to clear events : %d", + cxl_event_log_type_str(type), rc); + return; + } } if (trace_cxl_overflow_enabled() && @@ -780,10 +826,11 @@ static struct cxl_get_event_payload *alloc_event_buf(struct cxl_dev_state *cxlds * cxl_mem_get_event_records - Get Event Records from the device * @cxlds: The device data for the operation * - * Retrieve all event records available on the device and report them as trace - * events. + * Retrieve all event records available on the device, report them as trace + * events, and clear them. * * See CXL rev 3.0 @8.2.9.2.2 Get Event Records + * See CXL rev 3.0 @8.2.9.2.3 Clear Event Records */ void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) { diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 55d57f5a64bc..1ae9962c5a06 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -261,6 +261,7 @@ enum cxl_opcode { CXL_MBOX_OP_INVALID = 0x0000, CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID, CXL_MBOX_OP_GET_EVENT_RECORD = 0x0100, + CXL_MBOX_OP_CLEAR_EVENT_RECORD = 0x0101, CXL_MBOX_OP_GET_FW_INFO = 0x0200, CXL_MBOX_OP_ACTIVATE_FW = 0x0202, CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400, @@ -396,6 +397,19 @@ static inline const char *cxl_event_log_type_str(enum cxl_event_log_type type) return ""; } +/* + * Clear Event Records input payload + * CXL rev 3.0 section 8.2.9.2.3; Table 8-51 + */ +#define CXL_CLEAR_EVENT_MAX_HANDLES (0xff) +struct cxl_mbox_clear_event_payload { + u8 event_log; /* enum cxl_event_log_type */ + u8 clear_flags; + u8 nr_recs; + u8 reserved[3]; + __le16 handle[CXL_CLEAR_EVENT_MAX_HANDLES]; +}; + struct cxl_mbox_get_partition_info { __le64 active_volatile_cap; __le64 active_persistent_cap; diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h index 70459be5bdd4..7c1ad8062792 100644 --- a/include/uapi/linux/cxl_mem.h +++ b/include/uapi/linux/cxl_mem.h @@ -25,6 +25,7 @@ ___C(RAW, "Raw device command"), \ ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), \ ___C(GET_EVENT_RECORD, "Get Event Record"), \ + ___C(CLEAR_EVENT_RECORD, "Clear Event Record"), \ ___C(GET_FW_INFO, "Get FW Info"), \ ___C(GET_PARTITION_INFO, "Get Partition Information"), \ ___C(GET_LSA, "Get Label Storage Area"), \ From patchwork Thu Dec 1 00:27:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060850 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1CF7DC352A1 for ; Thu, 1 Dec 2022 00:27:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229775AbiLAA1q (ORCPT ); Wed, 30 Nov 2022 19:27:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229712AbiLAA1e (ORCPT ); Wed, 30 Nov 2022 19:27:34 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 431B310E; Wed, 30 Nov 2022 16:27:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854453; x=1701390453; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QN0FHISioResjhVj/Pv6zoPf18aJjWgu/WCgU6BoeF8=; b=VuK1lyfd5Oyi95mckUYMTyXVe0S1B13uOib6ISqUtlYlMfF0hlKa3Ptt zTXFYyJ78rhdWPry35qHicC+iual+biCa570CHXkB1wPUl+9IiuBeGEdj 7c7nvJMx2AyLWWC+bPBVz2iDObQ58wo8dYDMPrai4qlzDLNeh3dii4uUm UKFpG5YhoSaFkv5hX/NtrlEDbapWPn2SP5NFHGTm0zLQBKHbzp2aDw7cK rFTTnztGW4y9Ed3CDAxFKIDQkfnHbiSi9XK+HP4+F47eFEgSCL7fVZWim p8odTSIggQkJXTifb/zSFr9IagdcTeamcibIukEmu/UA+1ZMdNUgdHsMm g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400853" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400853" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:31 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085225" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085225" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:29 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Davidlohr Bueso , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 04/11] cxl/mem: Clear events on driver load Date: Wed, 30 Nov 2022 16:27:12 -0800 Message-Id: <20221201002719.2596558-5-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny The information contained in the events prior to the driver loading can be queried at any time through other mailbox commands. Ensure a clean slate of events by reading and clearing the events. The events are sent to the trace buffer but it is not anticipated to have anyone listening to it at driver load time. Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Signed-off-by: Ira Weiny --- drivers/cxl/pci.c | 2 ++ tools/testing/cxl/test/mem.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 8f86f85d89c7..11e95a95195a 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -521,6 +521,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); + cxl_mem_get_event_records(cxlds); + if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(&pdev->dev, cxlmd); diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index aa2df3a15051..e2f5445d24ff 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -285,6 +285,8 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); + cxl_mem_get_event_records(cxlds); + if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(dev, cxlmd); From patchwork Thu Dec 1 00:27:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060853 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15BB7C47088 for ; Thu, 1 Dec 2022 00:27:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229782AbiLAA14 (ORCPT ); Wed, 30 Nov 2022 19:27:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229701AbiLAA1q (ORCPT ); Wed, 30 Nov 2022 19:27:46 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EEE11038; Wed, 30 Nov 2022 16:27:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854454; x=1701390454; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=N2Pnv35xaqzly1ZNfOAl5sXRfQfPg0As2QV0Hxxe2ZI=; b=D+7BHsq94Cb+GBwl+1WJRm8Flyeh9zKI9T8jflHm37tU8/CwCbV65Nnf YnbcXcjtmHbaA4eGk/VTMZ3VakgD9+7NsIPFx2I8qJWSKozWxr3dOaEyC LKCaVmz1/mwFNLmHICvhdX+WmxijpzjzlwiTbJ7vBYIRgVXjACc5d1CX2 YZsPTEp7sZXnkBDYYoO1ZJBhIy/u2eCLXG/WCOJOZq7/Tqd8ppmvD9XBm jhb+BuuJ9K9yB2CuHurPhWWNV71a/yU2/+aTwzrvn8O2JoGXOj+V5rcpR k/vi3T9kJVRarKmKkTB4wSDDKpUrmfydhHLOUqeFI9y/fVIjmSBHjb9QV g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400859" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400859" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:31 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085229" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085229" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:30 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Steven Rostedt , Jonathan Cameron , Alison Schofield , Vishal Verma , Ben Widawsky , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 05/11] cxl/mem: Trace General Media Event Record Date: Wed, 30 Nov 2022 16:27:13 -0800 Message-Id: <20221201002719.2596558-6-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL rev 3.0 section 8.2.9.2.1.1 defines the General Media Event Record. Determine if the event read is a general media record and if so trace the record as a General Media Event Record. Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jonathan Cameron Signed-off-by: Ira Weiny Reviewed-by: Dave Jiang --- Changes from V1: Jonathan fix spec references for CXL rev 3.0 Make flags all caps Changes from RFC v2: Output DPA flags as a single field Ensure names of fields match what TP_print outputs Steven prefix TRACE_EVENT with 'cxl_' Jonathan Remove Reserved field Changes from RFC: Add reserved byte array Use common CXL event header record macros Jonathan Use unaligned_le{24,16} for unaligned fields Don't use the inverse of phy addr mask Dave Jiang s/cxl_gen_media_event/general_media s/cxl_evt_gen_media/cxl_event_gen_media --- drivers/cxl/core/mbox.c | 40 ++++++++++-- drivers/cxl/cxlmem.h | 19 ++++++ include/trace/events/cxl.h | 124 +++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 4 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 076a3df0ba38..20191fe55bba 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -709,6 +709,38 @@ int cxl_enumerate_cmds(struct cxl_dev_state *cxlds) } EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL); +/* + * General Media Event Record + * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 + */ +static const uuid_t gen_media_event_uuid = + UUID_INIT(0xfbcd0a77, 0xc260, 0x417f, + 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6); + +static bool cxl_event_tracing_enabled(void) +{ + return trace_cxl_generic_event_enabled() || + trace_cxl_general_media_enabled(); +} + +static void cxl_trace_event_record(const char *dev_name, + enum cxl_event_log_type type, + struct cxl_event_record_raw *record) +{ + uuid_t *id = &record->hdr.id; + + if (uuid_equal(id, &gen_media_event_uuid)) { + struct cxl_event_gen_media *rec = + (struct cxl_event_gen_media *)record; + + trace_cxl_general_media(dev_name, type, rec); + return; + } + + /* For unknown record types print just the header */ + trace_cxl_generic_event(dev_name, type, record); +} + static int cxl_clear_event_record(struct cxl_dev_state *cxlds, enum cxl_event_log_type log, struct cxl_get_event_payload *get_pl, @@ -772,11 +804,11 @@ static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, if (nr_rec > 0) { int i; - if (trace_cxl_generic_event_enabled()) { + if (cxl_event_tracing_enabled()) { for (i = 0; i < nr_rec; i++) - trace_cxl_generic_event(dev_name(cxlds->dev), - type, - &payload->records[i]); + cxl_trace_event_record(dev_name(cxlds->dev), + type, + &payload->records[i]); } rc = cxl_clear_event_record(cxlds, type, payload, nr_rec); diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 1ae9962c5a06..10696debefa8 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -410,6 +410,25 @@ struct cxl_mbox_clear_event_payload { __le16 handle[CXL_CLEAR_EVENT_MAX_HANDLES]; }; +/* + * General Media Event Record + * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 + */ +#define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10 +struct cxl_event_gen_media { + struct cxl_event_record_hdr hdr; + __le64 phys_addr; + u8 descriptor; + u8 type; + u8 transaction_type; + u8 validity_flags[2]; + u8 channel; + u8 rank; + u8 device[3]; + u8 component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; + u8 reserved[0x2e]; +} __packed; + struct cxl_mbox_get_partition_info { __le64 active_volatile_cap; __le64 active_persistent_cap; diff --git a/include/trace/events/cxl.h b/include/trace/events/cxl.h index c03a1a894af8..a4d6bd64e9bc 100644 --- a/include/trace/events/cxl.h +++ b/include/trace/events/cxl.h @@ -118,6 +118,130 @@ TRACE_EVENT(cxl_generic_event, __print_hex(__entry->data, CXL_EVENT_RECORD_DATA_LENGTH)) ); +/* + * Physical Address field masks + * + * General Media Event Record + * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 + * + * DRAM Event Record + * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44 + */ +#define CXL_DPA_FLAGS_MASK 0x3F +#define CXL_DPA_MASK (~CXL_DPA_FLAGS_MASK) + +#define CXL_DPA_VOLATILE BIT(0) +#define CXL_DPA_NOT_REPAIRABLE BIT(1) +#define show_dpa_flags(flags) __print_flags(flags, "|", \ + { CXL_DPA_VOLATILE, "VOLATILE" }, \ + { CXL_DPA_NOT_REPAIRABLE, "NOT_REPAIRABLE" } \ +) + +/* + * General Media Event Record - GMER + * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 + */ +#define CXL_GMER_EVT_DESC_UNCORECTABLE_EVENT BIT(0) +#define CXL_GMER_EVT_DESC_THRESHOLD_EVENT BIT(1) +#define CXL_GMER_EVT_DESC_POISON_LIST_OVERFLOW BIT(2) +#define show_event_desc_flags(flags) __print_flags(flags, "|", \ + { CXL_GMER_EVT_DESC_UNCORECTABLE_EVENT, "UNCORRECTABLE_EVENT" }, \ + { CXL_GMER_EVT_DESC_THRESHOLD_EVENT, "THRESHOLD_EVENT" }, \ + { CXL_GMER_EVT_DESC_POISON_LIST_OVERFLOW, "POISON_LIST_OVERFLOW" } \ +) + +#define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR 0x00 +#define CXL_GMER_MEM_EVT_TYPE_INV_ADDR 0x01 +#define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x02 +#define show_mem_event_type(type) __print_symbolic(type, \ + { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \ + { CXL_GMER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \ + { CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \ +) + +#define CXL_GMER_TRANS_UNKNOWN 0x00 +#define CXL_GMER_TRANS_HOST_READ 0x01 +#define CXL_GMER_TRANS_HOST_WRITE 0x02 +#define CXL_GMER_TRANS_HOST_SCAN_MEDIA 0x03 +#define CXL_GMER_TRANS_HOST_INJECT_POISON 0x04 +#define CXL_GMER_TRANS_INTERNAL_MEDIA_SCRUB 0x05 +#define CXL_GMER_TRANS_INTERNAL_MEDIA_MANAGEMENT 0x06 +#define show_trans_type(type) __print_symbolic(type, \ + { CXL_GMER_TRANS_UNKNOWN, "Unknown" }, \ + { CXL_GMER_TRANS_HOST_READ, "Host Read" }, \ + { CXL_GMER_TRANS_HOST_WRITE, "Host Write" }, \ + { CXL_GMER_TRANS_HOST_SCAN_MEDIA, "Host Scan Media" }, \ + { CXL_GMER_TRANS_HOST_INJECT_POISON, "Host Inject Poison" }, \ + { CXL_GMER_TRANS_INTERNAL_MEDIA_SCRUB, "Internal Media Scrub" }, \ + { CXL_GMER_TRANS_INTERNAL_MEDIA_MANAGEMENT, "Internal Media Management" } \ +) + +#define CXL_GMER_VALID_CHANNEL BIT(0) +#define CXL_GMER_VALID_RANK BIT(1) +#define CXL_GMER_VALID_DEVICE BIT(2) +#define CXL_GMER_VALID_COMPONENT BIT(3) +#define show_valid_flags(flags) __print_flags(flags, "|", \ + { CXL_GMER_VALID_CHANNEL, "CHANNEL" }, \ + { CXL_GMER_VALID_RANK, "RANK" }, \ + { CXL_GMER_VALID_DEVICE, "DEVICE" }, \ + { CXL_GMER_VALID_COMPONENT, "COMPONENT" } \ +) + +TRACE_EVENT(cxl_general_media, + + TP_PROTO(const char *dev_name, enum cxl_event_log_type log, + struct cxl_event_gen_media *rec), + + TP_ARGS(dev_name, log, rec), + + TP_STRUCT__entry( + CXL_EVT_TP_entry + /* General Media */ + __field(u64, dpa) + __field(u8, descriptor) + __field(u8, type) + __field(u8, transaction_type) + __field(u8, channel) + __field(u32, device) + __array(u8, comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE) + __field(u16, validity_flags) + /* Following are out of order to pack trace record */ + __field(u8, rank) + __field(u8, dpa_flags) + ), + + TP_fast_assign( + CXL_EVT_TP_fast_assign(dev_name, log, rec->hdr); + + /* General Media */ + __entry->dpa = le64_to_cpu(rec->phys_addr); + __entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK; + /* Mask after flags have been parsed */ + __entry->dpa &= CXL_DPA_MASK; + __entry->descriptor = rec->descriptor; + __entry->type = rec->type; + __entry->transaction_type = rec->transaction_type; + __entry->channel = rec->channel; + __entry->rank = rec->rank; + __entry->device = get_unaligned_le24(rec->device); + memcpy(__entry->comp_id, &rec->component_id, + CXL_EVENT_GEN_MED_COMP_ID_SIZE); + __entry->validity_flags = get_unaligned_le16(&rec->validity_flags); + ), + + CXL_EVT_TP_printk("dpa=%llx dpa_flags='%s' " \ + "descriptor='%s' type='%s' transaction_type='%s' channel=%u rank=%u " \ + "device=%x comp_id=%s validity_flags='%s'", + __entry->dpa, show_dpa_flags(__entry->dpa_flags), + show_event_desc_flags(__entry->descriptor), + show_mem_event_type(__entry->type), + show_trans_type(__entry->transaction_type), + __entry->channel, __entry->rank, __entry->device, + __print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE), + show_valid_flags(__entry->validity_flags) + ) +); + #endif /* _CXL_TRACE_EVENTS_H */ /* This part must be outside protection */ From patchwork Thu Dec 1 00:27:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060852 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A4D7C352A1 for ; Thu, 1 Dec 2022 00:27:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229693AbiLAA1z (ORCPT ); Wed, 30 Nov 2022 19:27:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229727AbiLAA1q (ORCPT ); Wed, 30 Nov 2022 19:27:46 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DBFEC26C6; Wed, 30 Nov 2022 16:27:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854454; x=1701390454; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6rtpMU6NePXoCN13wwTrW8rHB2GetrlKYvAfEnHAR/E=; b=dK9Dut9h33G4BJ5DK8Jtmt48qpwAYtoW/INntr9R3R1Ksa0r/LVKU7Cu 0MBpnrfslJU3s5fi2RZCKN2hBgZXN7w2ytUiMc7IgPe9ywrtLrMHmBiTK 6FQTqVizsIC8RxBTUAXaTQ7u3NECYvCNTsYIdsv+B64EN/RVlhIGlgAO4 GJLPvxS/Mmsoarhvmu0WpdSXkc/IQL+gd17F13B1wdVU+BZcJeTZRlDDu diLt+viZRGjLL2WFqNg0zgMLICFy66G7d6MiajZHm77c2AtiJlD/kAVxQ i3vNfZZViSuoUTEwUw4ynr2oyyvFyBQQxjnZDE8TVrNvxFTdG4FyM7QeC g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400866" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400866" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:33 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085234" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085234" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:31 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Steven Rostedt , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ben Widawsky , Davidlohr Bueso , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 06/11] cxl/mem: Trace DRAM Event Record Date: Wed, 30 Nov 2022 16:27:14 -0800 Message-Id: <20221201002719.2596558-7-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL rev 3.0 section 8.2.9.2.1.2 defines the DRAM Event Record. Determine if the event read is a DRAM event record and if so trace the record. Reviewed-by: Steven Rostedt (Google) Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Signed-off-by: Ira Weiny Reviewed-by: Dave Jiang --- Changes from RFC v2: Output DPA flags as a separate field. Ensure field names match TP_print output Steven prefix TRACE_EVENT with 'cxl_' Jonathan Formatting fix Remove reserved field Changes from RFC: Add reserved byte data Use new CXL header macros Jonathan Use get_unaligned_le{24,16}() for unaligned fields Use 'else if' Dave Jiang s/cxl_dram_event/dram s/cxl_evt_dram_rec/cxl_event_dram Adjust for new phys addr mask --- drivers/cxl/core/mbox.c | 16 ++++++- drivers/cxl/cxlmem.h | 23 ++++++++++ include/trace/events/cxl.h | 92 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 20191fe55bba..66fc50d89bf4 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -717,10 +717,19 @@ static const uuid_t gen_media_event_uuid = UUID_INIT(0xfbcd0a77, 0xc260, 0x417f, 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6); +/* + * DRAM Event Record + * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44 + */ +static const uuid_t dram_event_uuid = + UUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, + 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24); + static bool cxl_event_tracing_enabled(void) { return trace_cxl_generic_event_enabled() || - trace_cxl_general_media_enabled(); + trace_cxl_general_media_enabled() || + trace_cxl_dram_enabled(); } static void cxl_trace_event_record(const char *dev_name, @@ -735,6 +744,11 @@ static void cxl_trace_event_record(const char *dev_name, trace_cxl_general_media(dev_name, type, rec); return; + } else if (uuid_equal(id, &dram_event_uuid)) { + struct cxl_event_dram *rec = (struct cxl_event_dram *)record; + + trace_cxl_dram(dev_name, type, rec); + return; } /* For unknown record types print just the header */ diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 10696debefa8..f5f63a475478 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -429,6 +429,29 @@ struct cxl_event_gen_media { u8 reserved[0x2e]; } __packed; +/* + * DRAM Event Record - DER + * CXL rev 3.0 section 8.2.9.2.1.2; Table 3-44 + */ +#define CXL_EVENT_DER_CORRECTION_MASK_SIZE 0x20 +struct cxl_event_dram { + struct cxl_event_record_hdr hdr; + __le64 phys_addr; + u8 descriptor; + u8 type; + u8 transaction_type; + u8 validity_flags[2]; + u8 channel; + u8 rank; + u8 nibble_mask[3]; + u8 bank_group; + u8 bank; + u8 row[3]; + u8 column[2]; + u8 correction_mask[CXL_EVENT_DER_CORRECTION_MASK_SIZE]; + u8 reserved[0x17]; +} __packed; + struct cxl_mbox_get_partition_info { __le64 active_volatile_cap; __le64 active_persistent_cap; diff --git a/include/trace/events/cxl.h b/include/trace/events/cxl.h index a4d6bd64e9bc..474390f895d9 100644 --- a/include/trace/events/cxl.h +++ b/include/trace/events/cxl.h @@ -242,6 +242,98 @@ TRACE_EVENT(cxl_general_media, ) ); +/* + * DRAM Event Record - DER + * + * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44 + */ +/* + * DRAM Event Record defines many fields the same as the General Media Event + * Record. Reuse those definitions as appropriate. + */ +#define CXL_DER_VALID_CHANNEL BIT(0) +#define CXL_DER_VALID_RANK BIT(1) +#define CXL_DER_VALID_NIBBLE BIT(2) +#define CXL_DER_VALID_BANK_GROUP BIT(3) +#define CXL_DER_VALID_BANK BIT(4) +#define CXL_DER_VALID_ROW BIT(5) +#define CXL_DER_VALID_COLUMN BIT(6) +#define CXL_DER_VALID_CORRECTION_MASK BIT(7) +#define show_dram_valid_flags(flags) __print_flags(flags, "|", \ + { CXL_DER_VALID_CHANNEL, "CHANNEL" }, \ + { CXL_DER_VALID_RANK, "RANK" }, \ + { CXL_DER_VALID_NIBBLE, "NIBBLE" }, \ + { CXL_DER_VALID_BANK_GROUP, "BANK GROUP" }, \ + { CXL_DER_VALID_BANK, "BANK" }, \ + { CXL_DER_VALID_ROW, "ROW" }, \ + { CXL_DER_VALID_COLUMN, "COLUMN" }, \ + { CXL_DER_VALID_CORRECTION_MASK, "CORRECTION MASK" } \ +) + +TRACE_EVENT(cxl_dram, + + TP_PROTO(const char *dev_name, enum cxl_event_log_type log, + struct cxl_event_dram *rec), + + TP_ARGS(dev_name, log, rec), + + TP_STRUCT__entry( + CXL_EVT_TP_entry + /* DRAM */ + __field(u64, dpa) + __field(u8, descriptor) + __field(u8, type) + __field(u8, transaction_type) + __field(u8, channel) + __field(u16, validity_flags) + __field(u16, column) /* Out of order to pack trace record */ + __field(u32, nibble_mask) + __field(u32, row) + __array(u8, cor_mask, CXL_EVENT_DER_CORRECTION_MASK_SIZE) + __field(u8, rank) /* Out of order to pack trace record */ + __field(u8, bank_group) /* Out of order to pack trace record */ + __field(u8, bank) /* Out of order to pack trace record */ + __field(u8, dpa_flags) /* Out of order to pack trace record */ + ), + + TP_fast_assign( + CXL_EVT_TP_fast_assign(dev_name, log, rec->hdr); + + /* DRAM */ + __entry->dpa = le64_to_cpu(rec->phys_addr); + __entry->dpa_flags = __entry->dpa & CXL_DPA_FLAGS_MASK; + __entry->dpa &= CXL_DPA_MASK; + __entry->descriptor = rec->descriptor; + __entry->type = rec->type; + __entry->transaction_type = rec->transaction_type; + __entry->validity_flags = get_unaligned_le16(rec->validity_flags); + __entry->channel = rec->channel; + __entry->rank = rec->rank; + __entry->nibble_mask = get_unaligned_le24(rec->nibble_mask); + __entry->bank_group = rec->bank_group; + __entry->bank = rec->bank; + __entry->row = get_unaligned_le24(rec->row); + __entry->column = get_unaligned_le16(rec->column); + memcpy(__entry->cor_mask, &rec->correction_mask, + CXL_EVENT_DER_CORRECTION_MASK_SIZE); + ), + + CXL_EVT_TP_printk("dpa=%llx dpa_flags='%s' descriptor='%s' type='%s' " \ + "transaction_type='%s' channel=%u rank=%u nibble_mask=%x " \ + "bank_group=%u bank=%u row=%u column=%u cor_mask=%s " \ + "validity_flags='%s'", + __entry->dpa, show_dpa_flags(__entry->dpa_flags), + show_event_desc_flags(__entry->descriptor), + show_mem_event_type(__entry->type), + show_trans_type(__entry->transaction_type), + __entry->channel, __entry->rank, __entry->nibble_mask, + __entry->bank_group, __entry->bank, + __entry->row, __entry->column, + __print_hex(__entry->cor_mask, CXL_EVENT_DER_CORRECTION_MASK_SIZE), + show_dram_valid_flags(__entry->validity_flags) + ) +); + #endif /* _CXL_TRACE_EVENTS_H */ /* This part must be outside protection */ From patchwork Thu Dec 1 00:27:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060851 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7180C4321E for ; Thu, 1 Dec 2022 00:27:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229812AbiLAA1z (ORCPT ); Wed, 30 Nov 2022 19:27:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46352 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229732AbiLAA1g (ORCPT ); Wed, 30 Nov 2022 19:27:36 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13DBC2AF1; Wed, 30 Nov 2022 16:27:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854455; x=1701390455; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tqrhxjIGHjqYU4cg22xY4nY/OZqFX5qkn3mSSeCtDM0=; b=inCMJ5Flx5QBdJFvxdnWE9WE+SxF+wddZ7N9gh9CNZol9iiZDIblFCBN 0sCoBIl7EBjmq8P2D+CNd8hHWTsQ2S8IhkeIOq52rfv9ZBNixXVmz0QmK SRaXAFiKl5fdCb1bT+OTQ9A9qId+ocKNKq7xSvKfsKsT8NEveRsQQhCXh lVygJ1FPnQC0THbWFQocSv5QQLYzUVAmsMvVXhbV/sX3hIhPeV7L3jtZg OgcItAYg+K96ZdPbRK7HReRWJIaa5wx6jbdc7JkZWrFAElFRg2mkUWz8H ylzmMGSnKa4AVaZR7Zhf1ZSofI6Ow14yDKRBvBbZi39jbaqH4LpkvKz8N g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400872" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400872" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:33 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085238" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085238" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:32 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Steven Rostedt , Alison Schofield , Vishal Verma , Ben Widawsky , Jonathan Cameron , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 07/11] cxl/mem: Trace Memory Module Event Record Date: Wed, 30 Nov 2022 16:27:15 -0800 Message-Id: <20221201002719.2596558-8-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL rev 3.0 section 8.2.9.2.1.3 defines the Memory Module Event Record. Determine if the event read is memory module record and if so trace the record. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang --- Changes from V1: Use all caps for flag fields Changes from RFC v2: Ensure field names match TP_print output Steven prefix TRACE_EVENT with 'cxl_' Jonathan Remove reserved field Define a 1bit and 2 bit status decoder Fix paren alignment Changes from RFC: Clean up spec reference Add reserved data Use new CXL header macros Jonathan Use else if Use get_unaligned_le*() for unaligned fields Dave Jiang s/cxl_mem_mod_event/memory_module s/cxl_evt_mem_mod_rec/cxl_event_mem_module --- drivers/cxl/core/mbox.c | 17 ++++- drivers/cxl/cxlmem.h | 26 +++++++ include/trace/events/cxl.h | 144 +++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 66fc50d89bf4..30840b711381 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -725,11 +725,20 @@ static const uuid_t dram_event_uuid = UUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24); +/* + * Memory Module Event Record + * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 + */ +static const uuid_t mem_mod_event_uuid = + UUID_INIT(0xfe927475, 0xdd59, 0x4339, + 0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74); + static bool cxl_event_tracing_enabled(void) { return trace_cxl_generic_event_enabled() || trace_cxl_general_media_enabled() || - trace_cxl_dram_enabled(); + trace_cxl_dram_enabled() || + trace_cxl_memory_module_enabled(); } static void cxl_trace_event_record(const char *dev_name, @@ -749,6 +758,12 @@ static void cxl_trace_event_record(const char *dev_name, trace_cxl_dram(dev_name, type, rec); return; + } else if (uuid_equal(id, &mem_mod_event_uuid)) { + struct cxl_event_mem_module *rec = + (struct cxl_event_mem_module *)record; + + trace_cxl_memory_module(dev_name, type, rec); + return; } /* For unknown record types print just the header */ diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index f5f63a475478..450b410f29f6 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -452,6 +452,32 @@ struct cxl_event_dram { u8 reserved[0x17]; } __packed; +/* + * Get Health Info Record + * CXL rev 3.0 section 8.2.9.8.3.1; Table 8-100 + */ +struct cxl_get_health_info { + u8 health_status; + u8 media_status; + u8 add_status; + u8 life_used; + u8 device_temp[2]; + u8 dirty_shutdown_cnt[4]; + u8 cor_vol_err_cnt[4]; + u8 cor_per_err_cnt[4]; +} __packed; + +/* + * Memory Module Event Record + * CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45 + */ +struct cxl_event_mem_module { + struct cxl_event_record_hdr hdr; + u8 event_type; + struct cxl_get_health_info info; + u8 reserved[0x3d]; +} __packed; + struct cxl_mbox_get_partition_info { __le64 active_volatile_cap; __le64 active_persistent_cap; diff --git a/include/trace/events/cxl.h b/include/trace/events/cxl.h index 474390f895d9..48786d6c9615 100644 --- a/include/trace/events/cxl.h +++ b/include/trace/events/cxl.h @@ -334,6 +334,150 @@ TRACE_EVENT(cxl_dram, ) ); +/* + * Memory Module Event Record - MMER + * + * CXL res 3.0 section 8.2.9.2.1.3; Table 8-45 + */ +#define CXL_MMER_HEALTH_STATUS_CHANGE 0x00 +#define CXL_MMER_MEDIA_STATUS_CHANGE 0x01 +#define CXL_MMER_LIFE_USED_CHANGE 0x02 +#define CXL_MMER_TEMP_CHANGE 0x03 +#define CXL_MMER_DATA_PATH_ERROR 0x04 +#define CXL_MMER_LAS_ERROR 0x05 +#define show_dev_evt_type(type) __print_symbolic(type, \ + { CXL_MMER_HEALTH_STATUS_CHANGE, "Health Status Change" }, \ + { CXL_MMER_MEDIA_STATUS_CHANGE, "Media Status Change" }, \ + { CXL_MMER_LIFE_USED_CHANGE, "Life Used Change" }, \ + { CXL_MMER_TEMP_CHANGE, "Temperature Change" }, \ + { CXL_MMER_DATA_PATH_ERROR, "Data Path Error" }, \ + { CXL_MMER_LAS_ERROR, "LSA Error" } \ +) + +/* + * Device Health Information - DHI + * + * CXL res 3.0 section 8.2.9.8.3.1; Table 8-100 + */ +#define CXL_DHI_HS_MAINTENANCE_NEEDED BIT(0) +#define CXL_DHI_HS_PERFORMANCE_DEGRADED BIT(1) +#define CXL_DHI_HS_HW_REPLACEMENT_NEEDED BIT(2) +#define show_health_status_flags(flags) __print_flags(flags, "|", \ + { CXL_DHI_HS_MAINTENANCE_NEEDED, "MAINTENANCE_NEEDED" }, \ + { CXL_DHI_HS_PERFORMANCE_DEGRADED, "PERFORMANCE_DEGRADED" }, \ + { CXL_DHI_HS_HW_REPLACEMENT_NEEDED, "REPLACEMENT_NEEDED" } \ +) + +#define CXL_DHI_MS_NORMAL 0x00 +#define CXL_DHI_MS_NOT_READY 0x01 +#define CXL_DHI_MS_WRITE_PERSISTENCY_LOST 0x02 +#define CXL_DHI_MS_ALL_DATA_LOST 0x03 +#define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_POWER_LOSS 0x04 +#define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_SHUTDOWN 0x05 +#define CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_IMMINENT 0x06 +#define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_POWER_LOSS 0x07 +#define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_SHUTDOWN 0x08 +#define CXL_DHI_MS_WRITE_ALL_DATA_LOSS_IMMINENT 0x09 +#define show_media_status(ms) __print_symbolic(ms, \ + { CXL_DHI_MS_NORMAL, \ + "Normal" }, \ + { CXL_DHI_MS_NOT_READY, \ + "Not Ready" }, \ + { CXL_DHI_MS_WRITE_PERSISTENCY_LOST, \ + "Write Persistency Lost" }, \ + { CXL_DHI_MS_ALL_DATA_LOST, \ + "All Data Lost" }, \ + { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_POWER_LOSS, \ + "Write Persistency Loss in the Event of Power Loss" }, \ + { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_EVENT_SHUTDOWN, \ + "Write Persistency Loss in Event of Shutdown" }, \ + { CXL_DHI_MS_WRITE_PERSISTENCY_LOSS_IMMINENT, \ + "Write Persistency Loss Imminent" }, \ + { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_POWER_LOSS, \ + "All Data Loss in Event of Power Loss" }, \ + { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_EVENT_SHUTDOWN, \ + "All Data loss in the Event of Shutdown" }, \ + { CXL_DHI_MS_WRITE_ALL_DATA_LOSS_IMMINENT, \ + "All Data Loss Imminent" } \ +) + +#define CXL_DHI_AS_NORMAL 0x0 +#define CXL_DHI_AS_WARNING 0x1 +#define CXL_DHI_AS_CRITICAL 0x2 +#define show_two_bit_status(as) __print_symbolic(as, \ + { CXL_DHI_AS_NORMAL, "Normal" }, \ + { CXL_DHI_AS_WARNING, "Warning" }, \ + { CXL_DHI_AS_CRITICAL, "Critical" } \ +) +#define show_one_bit_status(as) __print_symbolic(as, \ + { CXL_DHI_AS_NORMAL, "Normal" }, \ + { CXL_DHI_AS_WARNING, "Warning" } \ +) + +#define CXL_DHI_AS_LIFE_USED(as) (as & 0x3) +#define CXL_DHI_AS_DEV_TEMP(as) ((as & 0xC) >> 2) +#define CXL_DHI_AS_COR_VOL_ERR_CNT(as) ((as & 0x10) >> 4) +#define CXL_DHI_AS_COR_PER_ERR_CNT(as) ((as & 0x20) >> 5) + +TRACE_EVENT(cxl_memory_module, + + TP_PROTO(const char *dev_name, enum cxl_event_log_type log, + struct cxl_event_mem_module *rec), + + TP_ARGS(dev_name, log, rec), + + TP_STRUCT__entry( + CXL_EVT_TP_entry + + /* Memory Module Event */ + __field(u8, event_type) + + /* Device Health Info */ + __field(u8, health_status) + __field(u8, media_status) + __field(u8, life_used) + __field(u32, dirty_shutdown_cnt) + __field(u32, cor_vol_err_cnt) + __field(u32, cor_per_err_cnt) + __field(s16, device_temp) + __field(u8, add_status) + ), + + TP_fast_assign( + CXL_EVT_TP_fast_assign(dev_name, log, rec->hdr); + + /* Memory Module Event */ + __entry->event_type = rec->event_type; + + /* Device Health Info */ + __entry->health_status = rec->info.health_status; + __entry->media_status = rec->info.media_status; + __entry->life_used = rec->info.life_used; + __entry->dirty_shutdown_cnt = get_unaligned_le32(rec->info.dirty_shutdown_cnt); + __entry->cor_vol_err_cnt = get_unaligned_le32(rec->info.cor_vol_err_cnt); + __entry->cor_per_err_cnt = get_unaligned_le32(rec->info.cor_per_err_cnt); + __entry->device_temp = get_unaligned_le16(rec->info.device_temp); + __entry->add_status = rec->info.add_status; + ), + + CXL_EVT_TP_printk("event_type='%s' health_status='%s' media_status='%s' " \ + "as_life_used=%s as_dev_temp=%s as_cor_vol_err_cnt=%s " \ + "as_cor_per_err_cnt=%s life_used=%u device_temp=%d " \ + "dirty_shutdown_cnt=%u cor_vol_err_cnt=%u cor_per_err_cnt=%u", + show_dev_evt_type(__entry->event_type), + show_health_status_flags(__entry->health_status), + show_media_status(__entry->media_status), + show_two_bit_status(CXL_DHI_AS_LIFE_USED(__entry->add_status)), + show_two_bit_status(CXL_DHI_AS_DEV_TEMP(__entry->add_status)), + show_one_bit_status(CXL_DHI_AS_COR_VOL_ERR_CNT(__entry->add_status)), + show_one_bit_status(CXL_DHI_AS_COR_PER_ERR_CNT(__entry->add_status)), + __entry->life_used, __entry->device_temp, + __entry->dirty_shutdown_cnt, __entry->cor_vol_err_cnt, + __entry->cor_per_err_cnt + ) +); + + #endif /* _CXL_TRACE_EVENTS_H */ /* This part must be outside protection */ From patchwork Thu Dec 1 00:27:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060855 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0AD5DC4708D for ; Thu, 1 Dec 2022 00:28:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229918AbiLAA16 (ORCPT ); Wed, 30 Nov 2022 19:27:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229805AbiLAA1z (ORCPT ); Wed, 30 Nov 2022 19:27:55 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A8B65FDB; Wed, 30 Nov 2022 16:27:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854457; x=1701390457; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dS7fziOXK4qpwRJCqQ3zRqxIj/8cRjILMGL8c7PQiyM=; b=L3vPnau7TUhX7qecuh/gZWlxwwcyQc3ZIcp1z/MvDv4caid4jHVMrrIH 2vzdIM/q2DdXiQbPrvSI0OKS5Wg74dEQrDaTvBpGATbJlM1eEJ/VBVbTM ewlL9nIO5m+Eb/k4/pi3gK4r1UTnUAzvzLNV7f0cNiO0LsxSNK5Z0nzd4 s95kw04ahyBxqJ+RXjQDm318HKSXwKQyyg9LN1rqkbhN8rAHfXZ3q44Q2 ZFdZek7uGNkxHBXa8cUztCJ+pPsaYd+uzp1vU6Y/KD6htPGSWXBS8Lw8O ioPLVmokuv3WWb7z/m3i6lKKp+8i6W+9/e3cHOjR1NaktjiEQZIBvQLPn g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400878" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400878" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:34 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085241" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085241" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:33 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Jonathan Cameron , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 08/11] cxl/mem: Wire up event interrupts Date: Wed, 30 Nov 2022 16:27:16 -0800 Message-Id: <20221201002719.2596558-9-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny CXL device events are signaled via interrupts. Each event log may have a different interrupt message number. These message numbers are reported in the Get Event Interrupt Policy mailbox command. Add interrupt support for event logs. Interrupts are allocated as shared interrupts. Therefore, all or some event logs can share the same message number. Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron Reviewed-by: Davidlohr Bueso --- Changes from V1: Remove unneeded evt_int_policy from struct cxl_dev_state defer Dynamic Capacity support Dave Jiang s/irq/rc use IRQ_NONE to signal the irq was not for us. Jonathan use msi_enabled rather than nr_irq_vec On failure explicitly set CXL_INT_NONE Add comment for Get Event Interrupt Policy use devm_request_threaded_irq() Use individual handler/thread functions for each of the logs rather than struct cxl_event_irq_id. Changes from RFC v2 Adjust to new irq 16 vector allocation Jonathan Remove CXL_INT_RES Use irq threads to ensure mailbox commands are executed outside irq context Adjust for optional Dynamic Capacity log --- drivers/cxl/core/mbox.c | 44 +++++++++++- drivers/cxl/cxlmem.h | 30 ++++++++ drivers/cxl/pci.c | 130 +++++++++++++++++++++++++++++++++++ include/uapi/linux/cxl_mem.h | 2 + 4 files changed, 204 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 30840b711381..1e00b49d8b06 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -53,6 +53,8 @@ static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE), CXL_CMD(GET_EVENT_RECORD, 1, CXL_VARIABLE_PAYLOAD, 0), CXL_CMD(CLEAR_EVENT_RECORD, CXL_VARIABLE_PAYLOAD, 0, 0), + CXL_CMD(GET_EVT_INT_POLICY, 0, 0x5, 0), + CXL_CMD(SET_EVT_INT_POLICY, 0x5, 0, 0), CXL_CMD(GET_FW_INFO, 0, 0x50, 0), CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0), CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0), @@ -806,8 +808,8 @@ static int cxl_clear_event_record(struct cxl_dev_state *cxlds, return 0; } -static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, - enum cxl_event_log_type type) +void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, + enum cxl_event_log_type type) { struct cxl_get_event_payload *payload; u16 nr_rec; @@ -857,6 +859,7 @@ static void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, unlock_buffer: mutex_unlock(&cxlds->event_buf_lock); } +EXPORT_SYMBOL_NS_GPL(cxl_mem_get_records_log, CXL); static void cxl_mem_free_event_buffer(void *data) { @@ -916,6 +919,43 @@ void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) } EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL); +int cxl_event_config_msgnums(struct cxl_dev_state *cxlds, + struct cxl_event_interrupt_policy *policy) +{ + int rc; + + policy->info_settings = CXL_INT_MSI_MSIX; + policy->warn_settings = CXL_INT_MSI_MSIX; + policy->failure_settings = CXL_INT_MSI_MSIX; + policy->fatal_settings = CXL_INT_MSI_MSIX; + + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_EVT_INT_POLICY, + policy, sizeof(*policy), NULL, 0); + if (rc < 0) { + dev_err(cxlds->dev, "Failed to set event interrupt policy : %d", + rc); + + policy->info_settings = CXL_INT_NONE; + policy->warn_settings = CXL_INT_NONE; + policy->failure_settings = CXL_INT_NONE; + policy->fatal_settings = CXL_INT_NONE; + + return rc; + } + + /* Retrieve interrupt message numbers */ + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_EVT_INT_POLICY, NULL, 0, + policy, sizeof(*policy)); + if (rc < 0) { + dev_err(cxlds->dev, "Failed to get event interrupt policy : %d", + rc); + return rc; + } + + return 0; +} +EXPORT_SYMBOL_NS_GPL(cxl_event_config_msgnums, CXL); + /** * cxl_mem_get_partition_info - Get partition info * @cxlds: The device data for the operation diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 450b410f29f6..2d384b0fc2b3 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -179,6 +179,30 @@ struct cxl_endpoint_dvsec_info { struct range dvsec_range[2]; }; +/** + * Event Interrupt Policy + * + * CXL rev 3.0 section 8.2.9.2.4; Table 8-52 + */ +enum cxl_event_int_mode { + CXL_INT_NONE = 0x00, + CXL_INT_MSI_MSIX = 0x01, + CXL_INT_FW = 0x02 +}; +#define CXL_EVENT_INT_MODE_MASK 0x3 +#define CXL_EVENT_INT_MSGNUM(setting) (((setting) & 0xf0) >> 4) +struct cxl_event_interrupt_policy { + u8 info_settings; + u8 warn_settings; + u8 failure_settings; + u8 fatal_settings; +} __packed; + +static inline bool cxl_evt_int_is_msi(u8 setting) +{ + return CXL_INT_MSI_MSIX == (setting & CXL_EVENT_INT_MODE_MASK); +} + /** * struct cxl_dev_state - The driver device state * @@ -262,6 +286,8 @@ enum cxl_opcode { CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID, CXL_MBOX_OP_GET_EVENT_RECORD = 0x0100, CXL_MBOX_OP_CLEAR_EVENT_RECORD = 0x0101, + CXL_MBOX_OP_GET_EVT_INT_POLICY = 0x0102, + CXL_MBOX_OP_SET_EVT_INT_POLICY = 0x0103, CXL_MBOX_OP_GET_FW_INFO = 0x0200, CXL_MBOX_OP_ACTIVATE_FW = 0x0202, CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400, @@ -537,7 +563,11 @@ int cxl_mem_create_range_info(struct cxl_dev_state *cxlds); struct cxl_dev_state *cxl_dev_state_create(struct device *dev); void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); +void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, + enum cxl_event_log_type type); void cxl_mem_get_event_records(struct cxl_dev_state *cxlds); +int cxl_event_config_msgnums(struct cxl_dev_state *cxlds, + struct cxl_event_interrupt_policy *policy); #ifdef CONFIG_CXL_SUSPEND void cxl_mem_active_inc(void); void cxl_mem_active_dec(void); diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 11e95a95195a..3c0b9199f11a 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -449,6 +449,134 @@ static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) cxlds->msi_enabled = true; } +static irqreturn_t cxl_event_info_thread(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_INFO); + return IRQ_HANDLED; +} + +static irqreturn_t cxl_event_info_handler(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + if (CXLDEV_EVENT_STATUS_INFO & status) + return IRQ_WAKE_THREAD; + return IRQ_NONE; +} + +static irqreturn_t cxl_event_warn_thread(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_WARN); + return IRQ_HANDLED; +} + +static irqreturn_t cxl_event_warn_handler(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + if (CXLDEV_EVENT_STATUS_WARN & status) + return IRQ_WAKE_THREAD; + return IRQ_NONE; +} + +static irqreturn_t cxl_event_failure_thread(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_FAIL); + return IRQ_HANDLED; +} + +static irqreturn_t cxl_event_failure_handler(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + if (CXLDEV_EVENT_STATUS_FAIL & status) + return IRQ_WAKE_THREAD; + return IRQ_NONE; +} + +static irqreturn_t cxl_event_fatal_thread(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + + cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_FATAL); + return IRQ_HANDLED; +} + +static irqreturn_t cxl_event_fatal_handler(int irq, void *id) +{ + struct cxl_dev_state *cxlds = id; + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + if (CXLDEV_EVENT_STATUS_FATAL & status) + return IRQ_WAKE_THREAD; + return IRQ_NONE; +} + +static void cxl_event_irqsetup(struct cxl_dev_state *cxlds) +{ + struct cxl_event_interrupt_policy policy; + struct device *dev = cxlds->dev; + struct pci_dev *pdev = to_pci_dev(dev); + u8 setting; + int rc; + + if (cxl_event_config_msgnums(cxlds, &policy)) + return; + + setting = policy.info_settings; + if (cxl_evt_int_is_msi(setting)) { + rc = devm_request_threaded_irq(dev, + pci_irq_vector(pdev, CXL_EVENT_INT_MSGNUM(setting)), + cxl_event_info_handler, cxl_event_info_thread, + IRQF_SHARED, NULL, cxlds); + if (rc) + dev_err(dev, "Failed to get interrupt for %s event log\n", + cxl_event_log_type_str(CXL_EVENT_TYPE_INFO)); + } + + setting = policy.warn_settings; + if (cxl_evt_int_is_msi(setting)) { + rc = devm_request_threaded_irq(dev, + pci_irq_vector(pdev, CXL_EVENT_INT_MSGNUM(setting)), + cxl_event_warn_handler, cxl_event_warn_thread, + IRQF_SHARED, NULL, cxlds); + if (rc) + dev_err(dev, "Failed to get interrupt for %s event log\n", + cxl_event_log_type_str(CXL_EVENT_TYPE_WARN)); + } + + setting = policy.failure_settings; + if (cxl_evt_int_is_msi(setting)) { + rc = devm_request_threaded_irq(dev, + pci_irq_vector(pdev, CXL_EVENT_INT_MSGNUM(setting)), + cxl_event_failure_handler, cxl_event_failure_thread, + IRQF_SHARED, NULL, cxlds); + if (rc) + dev_err(dev, "Failed to get interrupt for %s event log\n", + cxl_event_log_type_str(CXL_EVENT_TYPE_FAIL)); + } + + setting = policy.fatal_settings; + if (cxl_evt_int_is_msi(setting)) { + rc = devm_request_threaded_irq(dev, + pci_irq_vector(pdev, CXL_EVENT_INT_MSGNUM(setting)), + cxl_event_fatal_handler, cxl_event_fatal_thread, + IRQF_SHARED, NULL, cxlds); + if (rc) + dev_err(dev, "Failed to get interrupt for %s event log\n", + cxl_event_log_type_str(CXL_EVENT_TYPE_FATAL)); + } +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct cxl_register_map map; @@ -516,6 +644,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return rc; cxl_pci_alloc_irq_vectors(cxlds); + if (cxlds->msi_enabled) + cxl_event_irqsetup(cxlds); cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd)) diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h index 7c1ad8062792..a8204802fcca 100644 --- a/include/uapi/linux/cxl_mem.h +++ b/include/uapi/linux/cxl_mem.h @@ -26,6 +26,8 @@ ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), \ ___C(GET_EVENT_RECORD, "Get Event Record"), \ ___C(CLEAR_EVENT_RECORD, "Clear Event Record"), \ + ___C(GET_EVT_INT_POLICY, "Get Event Interrupt Policy"), \ + ___C(SET_EVT_INT_POLICY, "Set Event Interrupt Policy"), \ ___C(GET_FW_INFO, "Get FW Info"), \ ___C(GET_PARTITION_INFO, "Get Partition Information"), \ ___C(GET_LSA, "Get Label Storage Area"), \ From patchwork Thu Dec 1 00:27:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060856 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39410C4321E for ; Thu, 1 Dec 2022 00:28:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229832AbiLAA17 (ORCPT ); Wed, 30 Nov 2022 19:27:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229834AbiLAA1z (ORCPT ); Wed, 30 Nov 2022 19:27:55 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A98D5FEE; Wed, 30 Nov 2022 16:27:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854457; x=1701390457; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=z1Z4TGl1ZiPzwlIfDb30NvVCruCDbsVGGm39QgqOK20=; b=C0kmCj66Hfr139MLALkzrvnyNvd1bUv3VcJRh9xQaBNdLju69VfDGSF0 C7IuBoU3kIHIuhhjRj5BBfHYmy4HOhTNSYKunN4SiNmEqfdD6fMPas+dy 9HaRb3mTPqjkOSt44r4TyZiAc+hewVu8MaZB+m4CEOXmsAnlZEh7E2Xip g9FccNtsXMA1P9IBOEHzEcx1fxVEK+I55V7l/1KnFo3WBF7IYJ7xyvWmv dbnzrnr8hcbECeNqPbKbgJufs/nqreAh6FklZfn0MTRU6mYFEEuomlw5x rpWeu7hBZ3QyZCq66H1fgeIxGmyoue4/yFMX8srhQBF/eD1uDgK5OTI4Q A==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400886" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400886" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:34 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085245" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085245" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:34 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Jonathan Cameron , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 09/11] cxl/test: Add generic mock events Date: Wed, 30 Nov 2022 16:27:17 -0800 Message-Id: <20221201002719.2596558-10-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny Facilitate testing basic Get/Clear Event functionality by creating multiple logs and generic events with made up UUID's. Data is completely made up with data patterns which should be easy to spot in trace output. A single sysfs entry resets the event data and triggers collecting the events for testing. Events are returned one at a time which is within the specification even though it does not exercise the full capabilities of what a device may do. Test traces are easy to obtain with a small script such as this: #!/bin/bash -x devices=`find /sys/devices/platform -name cxl_mem*` # Turn on tracing echo "" > /sys/kernel/tracing/trace echo 1 > /sys/kernel/tracing/events/cxl/enable echo 1 > /sys/kernel/tracing/tracing_on # Generate fake interrupt for device in $devices; do echo 1 > $device/event_trigger done # Turn off tracing and report events echo 0 > /sys/kernel/tracing/tracing_on cat /sys/kernel/tracing/trace Signed-off-by: Ira Weiny --- Changes from v1: Fix up for new structures Jonathan Update based on specification discussion Changes from RFC v2: Adjust to simulate the event status register Changes from RFC: Separate out the event code Adjust for struct changes. Clean up devm_cxl_mock_event_logs() Clean up naming and comments Jonathan Remove dynamic allocation of event logs Clean up comment Remove unneeded xarray Ensure event_trigger sysfs is valid prior to the driver going active. Dan Remove the fill/reset event sysfs as these operations can be done together --- drivers/cxl/core/mbox.c | 33 +++-- drivers/cxl/cxlmem.h | 1 + tools/testing/cxl/test/Kbuild | 2 +- tools/testing/cxl/test/events.c | 242 ++++++++++++++++++++++++++++++++ tools/testing/cxl/test/events.h | 9 ++ tools/testing/cxl/test/mem.c | 35 ++++- 6 files changed, 307 insertions(+), 15 deletions(-) create mode 100644 tools/testing/cxl/test/events.c create mode 100644 tools/testing/cxl/test/events.h diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 1e00b49d8b06..17659b9a0408 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -886,20 +886,9 @@ static struct cxl_get_event_payload *alloc_event_buf(struct cxl_dev_state *cxlds return buf; } -/** - * cxl_mem_get_event_records - Get Event Records from the device - * @cxlds: The device data for the operation - * - * Retrieve all event records available on the device, report them as trace - * events, and clear them. - * - * See CXL rev 3.0 @8.2.9.2.2 Get Event Records - * See CXL rev 3.0 @8.2.9.2.3 Clear Event Records - */ -void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) +/* Direct call for mock testing */ +void __cxl_mem_get_event_records(struct cxl_dev_state *cxlds, u32 status) { - u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); - dev_dbg(cxlds->dev, "Reading event logs: %x\n", status); if (!cxlds->event_buf) { @@ -917,6 +906,24 @@ void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) if (status & CXLDEV_EVENT_STATUS_FATAL) cxl_mem_get_records_log(cxlds, CXL_EVENT_TYPE_FATAL); } +EXPORT_SYMBOL_NS_GPL(__cxl_mem_get_event_records, CXL); + +/** + * cxl_mem_get_event_records - Get Event Records from the device + * @cxlds: The device data for the operation + * + * Retrieve all event records available on the device, report them as trace + * events, and clear them. + * + * See CXL rev 3.0 @8.2.9.2.2 Get Event Records + * See CXL rev 3.0 @8.2.9.2.3 Clear Event Records + */ +void cxl_mem_get_event_records(struct cxl_dev_state *cxlds) +{ + u32 status = readl(cxlds->regs.status + CXLDEV_DEV_EVENT_STATUS_OFFSET); + + __cxl_mem_get_event_records(cxlds, status); +} EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL); int cxl_event_config_msgnums(struct cxl_dev_state *cxlds, diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 2d384b0fc2b3..10e3c1c893f3 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -565,6 +565,7 @@ void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); void cxl_mem_get_records_log(struct cxl_dev_state *cxlds, enum cxl_event_log_type type); +void __cxl_mem_get_event_records(struct cxl_dev_state *cxlds, u32 status); void cxl_mem_get_event_records(struct cxl_dev_state *cxlds); int cxl_event_config_msgnums(struct cxl_dev_state *cxlds, struct cxl_event_interrupt_policy *policy); diff --git a/tools/testing/cxl/test/Kbuild b/tools/testing/cxl/test/Kbuild index 4e59e2c911f6..64b14b83d8d9 100644 --- a/tools/testing/cxl/test/Kbuild +++ b/tools/testing/cxl/test/Kbuild @@ -7,4 +7,4 @@ obj-m += cxl_mock_mem.o cxl_test-y := cxl.o cxl_mock-y := mock.o -cxl_mock_mem-y := mem.o +cxl_mock_mem-y := mem.o events.o diff --git a/tools/testing/cxl/test/events.c b/tools/testing/cxl/test/events.c new file mode 100644 index 000000000000..a3d2ec7cc9fe --- /dev/null +++ b/tools/testing/cxl/test/events.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright(c) 2022 Intel Corporation. All rights reserved. + +#include +#include + +#include "events.h" + +#define CXL_TEST_EVENT_CNT_MAX 15 + +/* Set a number of events to return at a time for simulation. */ +#define CXL_TEST_EVENT_CNT 3 + +struct mock_event_log { + u16 clear_idx; + u16 cur_idx; + u16 nr_events; + struct cxl_event_record_raw *events[CXL_TEST_EVENT_CNT_MAX]; +}; + +struct mock_event_store { + struct cxl_dev_state *cxlds; + struct mock_event_log mock_logs[CXL_EVENT_TYPE_MAX]; + u32 ev_status; +}; + +DEFINE_XARRAY(mock_dev_event_store); + +struct mock_event_log *find_event_log(struct device *dev, int log_type) +{ + struct mock_event_store *mes = xa_load(&mock_dev_event_store, + (unsigned long)dev); + + if (!mes || log_type >= CXL_EVENT_TYPE_MAX) + return NULL; + return &mes->mock_logs[log_type]; +} + +struct cxl_event_record_raw *get_cur_event(struct mock_event_log *log) +{ + return log->events[log->cur_idx]; +} + +void reset_event_log(struct mock_event_log *log) +{ + log->cur_idx = 0; + log->clear_idx = 0; +} + +/* Handle can never be 0 use 1 based indexing for handle */ +u16 get_clear_handle(struct mock_event_log *log) +{ + return log->clear_idx + 1; +} + +/* Handle can never be 0 use 1 based indexing for handle */ +__le16 get_cur_event_handle(struct mock_event_log *log) +{ + u16 cur_handle = log->cur_idx + 1; + + return cpu_to_le16(cur_handle); +} + +static bool log_empty(struct mock_event_log *log) +{ + return log->cur_idx == log->nr_events; +} + +static void event_store_add_event(struct mock_event_store *mes, + enum cxl_event_log_type log_type, + struct cxl_event_record_raw *event) +{ + struct mock_event_log *log; + + if (WARN_ON(log_type >= CXL_EVENT_TYPE_MAX)) + return; + + log = &mes->mock_logs[log_type]; + if (WARN_ON(log->nr_events >= CXL_TEST_EVENT_CNT_MAX)) + return; + + log->events[log->nr_events] = event; + log->nr_events++; +} + +int mock_get_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct cxl_get_event_payload *pl; + struct mock_event_log *log; + u8 log_type; + int i; + + if (cmd->size_in != sizeof(log_type)) + return -EINVAL; + + if (cmd->size_out < struct_size(pl, records, CXL_TEST_EVENT_CNT)) + return -EINVAL; + + log_type = *((u8 *)cmd->payload_in); + if (log_type >= CXL_EVENT_TYPE_MAX) + return -EINVAL; + + memset(cmd->payload_out, 0, cmd->size_out); + + log = find_event_log(cxlds->dev, log_type); + if (!log || log_empty(log)) + return 0; + + pl = cmd->payload_out; + + for (i = 0; i < CXL_TEST_EVENT_CNT && !log_empty(log); i++) { + memcpy(&pl->records[i], get_cur_event(log), sizeof(pl->records[i])); + pl->records[i].hdr.handle = get_cur_event_handle(log); + log->cur_idx++; + } + + pl->record_count = cpu_to_le16(i); + if (!log_empty(log)) + pl->flags |= CXL_GET_EVENT_FLAG_MORE_RECORDS; + + return 0; +} +EXPORT_SYMBOL_GPL(mock_get_event); + +int mock_clear_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +{ + struct cxl_mbox_clear_event_payload *pl = cmd->payload_in; + struct mock_event_log *log; + u8 log_type = pl->event_log; + u16 handle; + int nr; + + if (log_type >= CXL_EVENT_TYPE_MAX) + return -EINVAL; + + log = find_event_log(cxlds->dev, log_type); + if (!log) + return 0; /* No mock data in this log */ + + /* + * This check is technically not invalid per the specification AFAICS. + * (The host could 'guess' handles and clear them in order). + * However, this is not good behavior for the host so test it. + */ + if (log->clear_idx + pl->nr_recs > log->cur_idx) { + dev_err(cxlds->dev, + "Attempting to clear more events than returned!\n"); + return -EINVAL; + } + + /* Check handle order prior to clearing events */ + for (nr = 0, handle = get_clear_handle(log); + nr < pl->nr_recs; + nr++, handle++) { + if (handle != le16_to_cpu(pl->handle[nr])) { + dev_err(cxlds->dev, "Clearing events out of order\n"); + return -EINVAL; + } + } + + /* Clear events */ + log->clear_idx += pl->nr_recs; + return 0; +} +EXPORT_SYMBOL_GPL(mock_clear_event); + +void cxl_mock_event_trigger(struct device *dev) +{ + struct mock_event_store *mes = xa_load(&mock_dev_event_store, + (unsigned long)dev); + int i; + + for (i = CXL_EVENT_TYPE_INFO; i < CXL_EVENT_TYPE_MAX; i++) { + struct mock_event_log *log; + + log = find_event_log(dev, i); + if (log) + reset_event_log(log); + } + + __cxl_mem_get_event_records(mes->cxlds, mes->ev_status); +} +EXPORT_SYMBOL_GPL(cxl_mock_event_trigger); + +struct cxl_event_record_raw maint_needed = { + .hdr = { + .id = UUID_INIT(0xDEADBEEF, 0xCAFE, 0xBABE, + 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0xa5, 0x5a, 0xa5), + .length = sizeof(struct cxl_event_record_raw), + .flags[0] = CXL_EVENT_RECORD_FLAG_MAINT_NEEDED, + /* .handle = Set dynamically */ + .related_handle = cpu_to_le16(0xa5b6), + }, + .data = { 0xDE, 0xAD, 0xBE, 0xEF }, +}; + +struct cxl_event_record_raw hardware_replace = { + .hdr = { + .id = UUID_INIT(0xBABECAFE, 0xBEEF, 0xDEAD, + 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0xa5, 0x5a, 0xa5), + .length = sizeof(struct cxl_event_record_raw), + .flags[0] = CXL_EVENT_RECORD_FLAG_HW_REPLACE, + /* .handle = Set dynamically */ + .related_handle = cpu_to_le16(0xb6a5), + }, + .data = { 0xDE, 0xAD, 0xBE, 0xEF }, +}; + +u32 cxl_mock_add_event_logs(struct cxl_dev_state *cxlds) +{ + struct device *dev = cxlds->dev; + struct mock_event_store *mes; + + mes = devm_kzalloc(dev, sizeof(*mes), GFP_KERNEL); + if (WARN_ON(!mes)) + return 0; + mes->cxlds = cxlds; + + if (xa_insert(&mock_dev_event_store, (unsigned long)dev, mes, + GFP_KERNEL)) { + dev_err(dev, "Event store not available for %s\n", + dev_name(dev)); + return 0; + } + + event_store_add_event(mes, CXL_EVENT_TYPE_INFO, &maint_needed); + mes->ev_status |= CXLDEV_EVENT_STATUS_INFO; + + event_store_add_event(mes, CXL_EVENT_TYPE_FATAL, &hardware_replace); + mes->ev_status |= CXLDEV_EVENT_STATUS_FATAL; + + return mes->ev_status; +} +EXPORT_SYMBOL_GPL(cxl_mock_add_event_logs); + +void cxl_mock_remove_event_logs(struct device *dev) +{ + struct mock_event_store *mes; + + mes = xa_erase(&mock_dev_event_store, (unsigned long)dev); +} +EXPORT_SYMBOL_GPL(cxl_mock_remove_event_logs); diff --git a/tools/testing/cxl/test/events.h b/tools/testing/cxl/test/events.h new file mode 100644 index 000000000000..5bebc6a0a01b --- /dev/null +++ b/tools/testing/cxl/test/events.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +int mock_get_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); +int mock_clear_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); +u32 cxl_mock_add_event_logs(struct cxl_dev_state *cxlds); +void cxl_mock_remove_event_logs(struct device *dev); +void cxl_mock_event_trigger(struct device *dev); diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index e2f5445d24ff..333fa8527a07 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -8,6 +8,7 @@ #include #include #include +#include "events.h" #define LSA_SIZE SZ_128K #define DEV_SIZE SZ_2G @@ -224,6 +225,12 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_GET_PARTITION_INFO: rc = mock_partition_info(cxlds, cmd); break; + case CXL_MBOX_OP_GET_EVENT_RECORD: + rc = mock_get_event(cxlds, cmd); + break; + case CXL_MBOX_OP_CLEAR_EVENT_RECORD: + rc = mock_clear_event(cxlds, cmd); + break; case CXL_MBOX_OP_SET_LSA: rc = mock_set_lsa(cxlds, cmd); break; @@ -245,11 +252,27 @@ static void label_area_release(void *lsa) vfree(lsa); } +static ssize_t event_trigger_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + cxl_mock_event_trigger(dev); + return count; +} +static DEVICE_ATTR_WO(event_trigger); + +static struct attribute *cxl_mock_event_attrs[] = { + &dev_attr_event_trigger.attr, + NULL +}; +ATTRIBUTE_GROUPS(cxl_mock_event); + static int cxl_mock_mem_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cxl_memdev *cxlmd; struct cxl_dev_state *cxlds; + u32 ev_status; void *lsa; int rc; @@ -281,11 +304,13 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) if (rc) return rc; + ev_status = cxl_mock_add_event_logs(cxlds); + cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); - cxl_mem_get_event_records(cxlds); + __cxl_mem_get_event_records(cxlds, ev_status); if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(dev, cxlmd); @@ -293,6 +318,12 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) return 0; } +static int cxl_mock_mem_remove(struct platform_device *pdev) +{ + cxl_mock_remove_event_logs(&pdev->dev); + return 0; +} + static const struct platform_device_id cxl_mock_mem_ids[] = { { .name = "cxl_mem", }, { }, @@ -301,9 +332,11 @@ MODULE_DEVICE_TABLE(platform, cxl_mock_mem_ids); static struct platform_driver cxl_mock_mem_driver = { .probe = cxl_mock_mem_probe, + .remove = cxl_mock_mem_remove, .id_table = cxl_mock_mem_ids, .driver = { .name = KBUILD_MODNAME, + .dev_groups = cxl_mock_event_groups, }, }; From patchwork Thu Dec 1 00:27:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060854 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1137BC4321E for ; Thu, 1 Dec 2022 00:27:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229895AbiLAA15 (ORCPT ); Wed, 30 Nov 2022 19:27:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229804AbiLAA1z (ORCPT ); Wed, 30 Nov 2022 19:27:55 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A93A5FE6; Wed, 30 Nov 2022 16:27:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854457; x=1701390457; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MIt8u5M8Ue6CxDEWxdx1n9xx/jT7kbKrMNIRbSJ2oXA=; b=i8hO6rW2LYuq67wuOJasAhmlX6SDKKU9YGSwxXH10I2knZHRB4F64GEA MOEoLdam9N8/gj4PyFHZDP5poUhB4NeprmukDyQjQ2wqqTh+mswdMRTb2 ps5IH0NUIfr8wN6jvrJMOTdumaBJV+Oe6sNObGF+Asai1m+fMimk1PK5k ugHwJgFlQGC857dfJKEp4cWoQEOoAQoXE+wu+MvJJzKOs3+h9xhuzh9eR rQLExTeU5tWVOcXMecP5S4MEunM1LjAI6X9tGtiTd1wtKdifM3OdTFeaW dJQll3mG7vaSD3QrbLSHwes5j1oAqUCxVTV/eXntG36WEGtgTupwPbawm g==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400892" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400892" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:35 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085248" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085248" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:35 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Jonathan Cameron , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 10/11] cxl/test: Add specific events Date: Wed, 30 Nov 2022 16:27:18 -0800 Message-Id: <20221201002719.2596558-11-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny Each type of event has different trace point outputs. Add mock General Media Event, DRAM event, and Memory Module Event records to the mock list of events returned. Reviewed-by: Jonathan Cameron Signed-off-by: Ira Weiny Reviewed-by: Dave Jiang --- Changes from V1: Jonathan use put_unaligned_le16() fix spacing Changes from RFC: Adjust for struct changes adjust for unaligned fields --- tools/testing/cxl/test/events.c | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tools/testing/cxl/test/events.c b/tools/testing/cxl/test/events.c index a3d2ec7cc9fe..0bcc485e07da 100644 --- a/tools/testing/cxl/test/events.c +++ b/tools/testing/cxl/test/events.c @@ -206,6 +206,66 @@ struct cxl_event_record_raw hardware_replace = { .data = { 0xDE, 0xAD, 0xBE, 0xEF }, }; +struct cxl_event_gen_media gen_media = { + .hdr = { + .id = UUID_INIT(0xfbcd0a77, 0xc260, 0x417f, + 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6), + .length = sizeof(struct cxl_event_gen_media), + .flags[0] = CXL_EVENT_RECORD_FLAG_PERMANENT, + /* .handle = Set dynamically */ + .related_handle = cpu_to_le16(0), + }, + .phys_addr = cpu_to_le64(0x2000), + .descriptor = CXL_GMER_EVT_DESC_UNCORECTABLE_EVENT, + .type = CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR, + .transaction_type = CXL_GMER_TRANS_HOST_WRITE, + /* .validity_flags = */ + .channel = 1, + .rank = 30 +}; + +struct cxl_event_dram dram = { + .hdr = { + .id = UUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, + 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24), + .length = sizeof(struct cxl_event_dram), + .flags[0] = CXL_EVENT_RECORD_FLAG_PERF_DEGRADED, + /* .handle = Set dynamically */ + .related_handle = cpu_to_le16(0), + }, + .phys_addr = cpu_to_le64(0x8000), + .descriptor = CXL_GMER_EVT_DESC_THRESHOLD_EVENT, + .type = CXL_GMER_MEM_EVT_TYPE_INV_ADDR, + .transaction_type = CXL_GMER_TRANS_INTERNAL_MEDIA_SCRUB, + /* .validity_flags = */ + .channel = 1, + .bank_group = 5, + .bank = 2, + .column = {0xDE, 0xAD}, +}; + +struct cxl_event_mem_module mem_module = { + .hdr = { + .id = UUID_INIT(0xfe927475, 0xdd59, 0x4339, + 0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74), + .length = sizeof(struct cxl_event_mem_module), + /* .handle = Set dynamically */ + .related_handle = cpu_to_le16(0), + }, + .event_type = CXL_MMER_TEMP_CHANGE, + .info = { + .health_status = CXL_DHI_HS_PERFORMANCE_DEGRADED, + .media_status = CXL_DHI_MS_ALL_DATA_LOST, + .add_status = (CXL_DHI_AS_CRITICAL << 2) | + (CXL_DHI_AS_WARNING << 4) | + (CXL_DHI_AS_WARNING << 5), + .device_temp = { 0xDE, 0xAD}, + .dirty_shutdown_cnt = { 0xde, 0xad, 0xbe, 0xef }, + .cor_vol_err_cnt = { 0xde, 0xad, 0xbe, 0xef }, + .cor_per_err_cnt = { 0xde, 0xad, 0xbe, 0xef }, + } +}; + u32 cxl_mock_add_event_logs(struct cxl_dev_state *cxlds) { struct device *dev = cxlds->dev; @@ -223,10 +283,23 @@ u32 cxl_mock_add_event_logs(struct cxl_dev_state *cxlds) return 0; } + put_unaligned_le16(CXL_GMER_VALID_CHANNEL | CXL_GMER_VALID_RANK, + &gen_media.validity_flags); + + put_unaligned_le16(CXL_DER_VALID_CHANNEL | CXL_DER_VALID_BANK_GROUP | + CXL_DER_VALID_BANK | CXL_DER_VALID_COLUMN, + &dram.validity_flags); + event_store_add_event(mes, CXL_EVENT_TYPE_INFO, &maint_needed); + event_store_add_event(mes, CXL_EVENT_TYPE_INFO, + (struct cxl_event_record_raw *)&gen_media); + event_store_add_event(mes, CXL_EVENT_TYPE_INFO, + (struct cxl_event_record_raw *)&mem_module); mes->ev_status |= CXLDEV_EVENT_STATUS_INFO; event_store_add_event(mes, CXL_EVENT_TYPE_FATAL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FATAL, + (struct cxl_event_record_raw *)&dram); mes->ev_status |= CXLDEV_EVENT_STATUS_FATAL; return mes->ev_status; From patchwork Thu Dec 1 00:27:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 13060857 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6AD0C4321E for ; Thu, 1 Dec 2022 00:28:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230000AbiLAA2E (ORCPT ); Wed, 30 Nov 2022 19:28:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229800AbiLAA14 (ORCPT ); Wed, 30 Nov 2022 19:27:56 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CC5F12D28; Wed, 30 Nov 2022 16:27:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669854459; x=1701390459; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nJK5EYVQsbsVhEkfDMZIpLJP3ACrgI2e3ZyBYEWndGU=; b=R9cYtbFtU7B3IIKkqT1zZbay+jdMrQYOeK52h8/unGlk21upSyq6Hfl3 BkHEI090Qw9LOT7Seg7LqoLzl+1va7BXqOq0aSW2EXdqpYEiIghQ+oCmn m4NVnzwdWf24TIF3oUx1GTYCjLFWMTJIU2qxN46+xWQL4G5Bat7izbdqx 5K7ss4k7usp5OqjADMRtaJxvCSyiD87tJ6WLbuNj7Ep70HaVcTXGqKCNX sC3BPLYSX8x17Czv1n21jfFKJ5lPJTuE4ur2X6nLn5WdUsUeOp2wOuBe4 UgkNIotbw+pW1Gv7YKr8fh62ZVApm9pP8cAatTcRgLBCReelVv8RU+A98 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="317400898" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="317400898" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:36 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10547"; a="622085255" X-IronPort-AV: E=Sophos;i="5.96,207,1665471600"; d="scan'208";a="622085255" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.251.1.240]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Nov 2022 16:27:36 -0800 From: ira.weiny@intel.com To: Dan Williams Cc: Ira Weiny , Jonathan Cameron , Alison Schofield , Vishal Verma , Ben Widawsky , Steven Rostedt , Davidlohr Bueso , Dave Jiang , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH V2 11/11] cxl/test: Simulate event log overflow Date: Wed, 30 Nov 2022 16:27:19 -0800 Message-Id: <20221201002719.2596558-12-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221201002719.2596558-1-ira.weiny@intel.com> References: <20221201002719.2596558-1-ira.weiny@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Ira Weiny Log overflow is marked by a separate trace message. Simulate a log with lots of messages and flag overflow until it is drained a bit. Reviewed-by: Jonathan Cameron Signed-off-by: Ira Weiny Reviewed-by: Dave Jiang --- Changes from RFC Adjust for new struct changes --- tools/testing/cxl/test/events.c | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tools/testing/cxl/test/events.c b/tools/testing/cxl/test/events.c index 0bcc485e07da..ceabefb526c2 100644 --- a/tools/testing/cxl/test/events.c +++ b/tools/testing/cxl/test/events.c @@ -15,6 +15,8 @@ struct mock_event_log { u16 clear_idx; u16 cur_idx; u16 nr_events; + u16 nr_overflow; + u16 overflow_reset; struct cxl_event_record_raw *events[CXL_TEST_EVENT_CNT_MAX]; }; @@ -45,6 +47,7 @@ void reset_event_log(struct mock_event_log *log) { log->cur_idx = 0; log->clear_idx = 0; + log->nr_overflow = log->overflow_reset; } /* Handle can never be 0 use 1 based indexing for handle */ @@ -76,8 +79,12 @@ static void event_store_add_event(struct mock_event_store *mes, return; log = &mes->mock_logs[log_type]; - if (WARN_ON(log->nr_events >= CXL_TEST_EVENT_CNT_MAX)) + + if ((log->nr_events + 1) > CXL_TEST_EVENT_CNT_MAX) { + log->nr_overflow++; + log->overflow_reset = log->nr_overflow; return; + } log->events[log->nr_events] = event; log->nr_events++; @@ -87,6 +94,7 @@ int mock_get_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_get_event_payload *pl; struct mock_event_log *log; + u16 nr_overflow; u8 log_type; int i; @@ -118,6 +126,21 @@ int mock_get_event(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) if (!log_empty(log)) pl->flags |= CXL_GET_EVENT_FLAG_MORE_RECORDS; + if (log->nr_overflow) { + u64 ns; + + pl->flags |= CXL_GET_EVENT_FLAG_OVERFLOW; + pl->overflow_err_count = cpu_to_le16(nr_overflow); + ns = ktime_get_real_ns(); + ns -= 5000000000; /* 5s ago */ + pl->first_overflow_timestamp = cpu_to_le64(ns); + ns = ktime_get_real_ns(); + ns -= 1000000000; /* 1s ago */ + pl->last_overflow_timestamp = cpu_to_le64(ns); + + log->nr_overflow = 0; + } + return 0; } EXPORT_SYMBOL_GPL(mock_get_event); @@ -297,6 +320,30 @@ u32 cxl_mock_add_event_logs(struct cxl_dev_state *cxlds) (struct cxl_event_record_raw *)&mem_module); mes->ev_status |= CXLDEV_EVENT_STATUS_INFO; + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &maint_needed); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, + (struct cxl_event_record_raw *)&dram); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, + (struct cxl_event_record_raw *)&gen_media); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, + (struct cxl_event_record_raw *)&mem_module); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, + (struct cxl_event_record_raw *)&dram); + /* Overflow this log */ + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + event_store_add_event(mes, CXL_EVENT_TYPE_FAIL, &hardware_replace); + mes->ev_status |= CXLDEV_EVENT_STATUS_FAIL; + event_store_add_event(mes, CXL_EVENT_TYPE_FATAL, &hardware_replace); event_store_add_event(mes, CXL_EVENT_TYPE_FATAL, (struct cxl_event_record_raw *)&dram);