From 5e2411ae8071612396cd25017e29f9ce0662a5ff Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Tue, 2 Nov 2021 13:29:01 -0700 Subject: cxl/memdev: Change cxl_mem to a more descriptive name The 'struct cxl_mem' object actually represents the state of a CXL device within the driver. Comments indicating that 'struct cxl_mem' is a device itself are incorrect. It is data layered on top of a CXL Memory Expander class device. Rename it 'struct cxl_dev_state'. The 'struct' cxl_memdev' structure represents a Linux CXL memory device object, and it uses services and information provided by 'struct cxl_dev_state'. Update the structure name, function names, and the kdocs to reflect the real uses of this structure. Some helper functions that were previously prefixed "cxl_mem_" are renamed to just "cxl_". Acked-by: Ben Widawsky Signed-off-by: Ira Weiny Link: https://lore.kernel.org/r/20211102202901.3675568-3-ira.weiny@intel.com Signed-off-by: Dan Williams --- tools/testing/cxl/test/mem.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'tools/testing') diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 12a8437a9ca0..555faa4a57f7 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -54,7 +54,7 @@ static int mock_gsl(struct cxl_mbox_cmd *cmd) return 0; } -static int mock_get_log(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) +static int mock_get_log(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_log *gl = cmd->payload_in; u32 offset = le32_to_cpu(gl->offset); @@ -64,7 +64,7 @@ static int mock_get_log(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) if (cmd->size_in < sizeof(*gl)) return -EINVAL; - if (length > cxlm->payload_size) + if (length > cxlds->payload_size) return -EINVAL; if (offset + length > sizeof(mock_cel)) return -EINVAL; @@ -78,9 +78,9 @@ static int mock_get_log(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) return 0; } -static int mock_id(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) +static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { - struct platform_device *pdev = to_platform_device(cxlm->dev); + struct platform_device *pdev = to_platform_device(cxlds->dev); struct cxl_mbox_identify id = { .fw_revision = { "mock fw v1 " }, .lsa_size = cpu_to_le32(LSA_SIZE), @@ -120,10 +120,10 @@ static int mock_id(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) return 0; } -static int mock_get_lsa(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) +static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in; - void *lsa = dev_get_drvdata(cxlm->dev); + void *lsa = dev_get_drvdata(cxlds->dev); u32 offset, length; if (sizeof(*get_lsa) > cmd->size_in) @@ -139,10 +139,10 @@ static int mock_get_lsa(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) return 0; } -static int mock_set_lsa(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) +static int mock_set_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct cxl_mbox_set_lsa *set_lsa = cmd->payload_in; - void *lsa = dev_get_drvdata(cxlm->dev); + void *lsa = dev_get_drvdata(cxlds->dev); u32 offset, length; if (sizeof(*set_lsa) > cmd->size_in) @@ -156,9 +156,9 @@ static int mock_set_lsa(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) return 0; } -static int cxl_mock_mbox_send(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) +static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { - struct device *dev = cxlm->dev; + struct device *dev = cxlds->dev; int rc = -EIO; switch (cmd->opcode) { @@ -166,16 +166,16 @@ static int cxl_mock_mbox_send(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd) rc = mock_gsl(cmd); break; case CXL_MBOX_OP_GET_LOG: - rc = mock_get_log(cxlm, cmd); + rc = mock_get_log(cxlds, cmd); break; case CXL_MBOX_OP_IDENTIFY: - rc = mock_id(cxlm, cmd); + rc = mock_id(cxlds, cmd); break; case CXL_MBOX_OP_GET_LSA: - rc = mock_get_lsa(cxlm, cmd); + rc = mock_get_lsa(cxlds, cmd); break; case CXL_MBOX_OP_SET_LSA: - rc = mock_set_lsa(cxlm, cmd); + rc = mock_set_lsa(cxlds, cmd); break; default: break; @@ -196,7 +196,7 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cxl_memdev *cxlmd; - struct cxl_mem *cxlm; + struct cxl_dev_state *cxlds; void *lsa; int rc; @@ -208,30 +208,30 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) return rc; dev_set_drvdata(dev, lsa); - cxlm = cxl_mem_create(dev); - if (IS_ERR(cxlm)) - return PTR_ERR(cxlm); + cxlds = cxl_dev_state_create(dev); + if (IS_ERR(cxlds)) + return PTR_ERR(cxlds); - cxlm->mbox_send = cxl_mock_mbox_send; - cxlm->payload_size = SZ_4K; + cxlds->mbox_send = cxl_mock_mbox_send; + cxlds->payload_size = SZ_4K; - rc = cxl_mem_enumerate_cmds(cxlm); + rc = cxl_enumerate_cmds(cxlds); if (rc) return rc; - rc = cxl_mem_identify(cxlm); + rc = cxl_dev_state_identify(cxlds); if (rc) return rc; - rc = cxl_mem_create_range_info(cxlm); + rc = cxl_mem_create_range_info(cxlds); if (rc) return rc; - cxlmd = devm_cxl_add_memdev(cxlm); + cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); - if (range_len(&cxlm->pmem_range) && IS_ENABLED(CONFIG_CXL_PMEM)) + if (range_len(&cxlds->pmem_range) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(dev, cxlmd); return 0; -- cgit v1.2.3 From 09eac2ca988a866225a174212765f77c85702206 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Sun, 17 Oct 2021 23:12:51 -0600 Subject: tools/testing/cxl: add mock output for the GET_HEALTH_INFO command Add mocked health information for cxl_test memdevs. This allows cxl-cli's 'list' command to display the canned health_info fields. Cc: Dan Williams Reviewed-by: Jonathan Cameron Signed-off-by: Vishal Verma Link: https://lore.kernel.org/r/20211018051251.2289112-1-vishal.l.verma@intel.com Signed-off-by: Dan Williams --- tools/testing/cxl/test/mem.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'tools/testing') diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 555faa4a57f7..8c2086c4caef 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -28,8 +28,24 @@ static struct cxl_cel_entry mock_cel[] = { .opcode = cpu_to_le16(CXL_MBOX_OP_SET_LSA), .effect = cpu_to_le16(EFFECT(1) | EFFECT(2)), }, + { + .opcode = cpu_to_le16(CXL_MBOX_OP_GET_HEALTH_INFO), + .effect = cpu_to_le16(0), + }, }; +/* See CXL 2.0 Table 181 Get Health Info Output Payload */ +struct cxl_mbox_health_info { + u8 health_status; + u8 media_status; + u8 ext_status; + u8 life_used; + __le16 temperature; + __le32 dirty_shutdowns; + __le32 volatile_errors; + __le32 pmem_errors; +} __packed; + static struct { struct cxl_mbox_get_supported_logs gsl; struct cxl_gsl_entry entry; @@ -156,6 +172,36 @@ static int mock_set_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) return 0; } +static int mock_health_info(struct cxl_dev_state *cxlds, + struct cxl_mbox_cmd *cmd) +{ + struct cxl_mbox_health_info health_info = { + /* set flags for maint needed, perf degraded, hw replacement */ + .health_status = 0x7, + /* set media status to "All Data Lost" */ + .media_status = 0x3, + /* + * set ext_status flags for: + * ext_life_used: normal, + * ext_temperature: critical, + * ext_corrected_volatile: warning, + * ext_corrected_persistent: normal, + */ + .ext_status = 0x18, + .life_used = 15, + .temperature = cpu_to_le16(25), + .dirty_shutdowns = cpu_to_le32(10), + .volatile_errors = cpu_to_le32(20), + .pmem_errors = cpu_to_le32(30), + }; + + if (cmd->size_out < sizeof(health_info)) + return -EINVAL; + + memcpy(cmd->payload_out, &health_info, sizeof(health_info)); + return 0; +} + static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) { struct device *dev = cxlds->dev; @@ -177,6 +223,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd * case CXL_MBOX_OP_SET_LSA: rc = mock_set_lsa(cxlds, cmd); break; + case CXL_MBOX_OP_GET_HEALTH_INFO: + rc = mock_health_info(cxlds, cmd); + break; default: break; } -- cgit v1.2.3 From 814dff9ae234d70003b8733a637fec621c90f0bc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2021 12:51:53 -0700 Subject: cxl/test: Mock acpi_table_parse_cedt() Now that cxl_acpi has been converted to use the core ACPI CEDT sub-table parser, update cxl_test to inject CFMWS and CHBS data directly into cxl_acpi's handlers. Cc: Alison Schofield Acked-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/163553711363.2509508.17428994087868269952.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/cxl/acpi.c | 2 ++ tools/testing/cxl/Kbuild | 3 +- tools/testing/cxl/test/cxl.c | 68 +++++++++++++++++++++++++++++-------------- tools/testing/cxl/test/mock.c | 30 ++++++------------- tools/testing/cxl/test/mock.h | 6 ++-- 5 files changed, 61 insertions(+), 48 deletions(-) (limited to 'tools/testing') diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 7820082a2746..91e4072e7649 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -283,6 +283,7 @@ static int add_host_bridge_uport(struct device *match, void *arg) } struct cxl_chbs_context { + struct device *dev; unsigned long long uid; resource_size_t chbcr; }; @@ -327,6 +328,7 @@ static int add_host_bridge_dport(struct device *match, void *arg) } ctx = (struct cxl_chbs_context) { + .dev = host, .uid = uid, }; acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, cxl_get_chbcr, &ctx); diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild index 86deba8308a1..1acdf2fc31c5 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +ldflags-y += --wrap=acpi_table_parse_cedt ldflags-y += --wrap=is_acpi_device_node -ldflags-y += --wrap=acpi_get_table -ldflags-y += --wrap=acpi_put_table ldflags-y += --wrap=acpi_evaluate_integer ldflags-y += --wrap=acpi_pci_find_root ldflags-y += --wrap=pci_walk_bus diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c index cb32f9e27d5d..736d99006fb7 100644 --- a/tools/testing/cxl/test/cxl.c +++ b/tools/testing/cxl/test/cxl.c @@ -182,6 +182,13 @@ static struct { }, }; +struct acpi_cedt_cfmws *mock_cfmws[4] = { + [0] = &mock_cedt.cfmws0.cfmws, + [1] = &mock_cedt.cfmws1.cfmws, + [2] = &mock_cedt.cfmws2.cfmws, + [3] = &mock_cedt.cfmws3.cfmws, +}; + struct cxl_mock_res { struct list_head list; struct range range; @@ -232,12 +239,6 @@ static struct cxl_mock_res *alloc_mock_res(resource_size_t size) static int populate_cedt(void) { - struct acpi_cedt_cfmws *cfmws[4] = { - [0] = &mock_cedt.cfmws0.cfmws, - [1] = &mock_cedt.cfmws1.cfmws, - [2] = &mock_cedt.cfmws2.cfmws, - [3] = &mock_cedt.cfmws3.cfmws, - }; struct cxl_mock_res *res; int i; @@ -257,8 +258,8 @@ static int populate_cedt(void) chbs->length = size; } - for (i = 0; i < ARRAY_SIZE(cfmws); i++) { - struct acpi_cedt_cfmws *window = cfmws[i]; + for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) { + struct acpi_cedt_cfmws *window = mock_cfmws[i]; res = alloc_mock_res(window->window_size); if (!res) @@ -269,21 +270,44 @@ static int populate_cedt(void) return 0; } -static acpi_status mock_acpi_get_table(char *signature, u32 instance, - struct acpi_table_header **out_table) +/* + * WARNING, this hack assumes the format of 'struct + * cxl_cfmws_context' and 'struct cxl_chbs_context' share the property that + * the first struct member is the device being probed by the cxl_acpi + * driver. + */ +struct cxl_cedt_context { + struct device *dev; +}; + +static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id, + acpi_tbl_entry_handler_arg handler_arg, + void *arg) { - if (instance < U32_MAX || strcmp(signature, ACPI_SIG_CEDT) != 0) - return acpi_get_table(signature, instance, out_table); + struct cxl_cedt_context *ctx = arg; + struct device *dev = ctx->dev; + union acpi_subtable_headers *h; + unsigned long end; + int i; - *out_table = (struct acpi_table_header *) &mock_cedt; - return AE_OK; -} + if (dev != &cxl_acpi->dev) + return acpi_table_parse_cedt(id, handler_arg, arg); -static void mock_acpi_put_table(struct acpi_table_header *table) -{ - if (table == (struct acpi_table_header *) &mock_cedt) - return; - acpi_put_table(table); + if (id == ACPI_CEDT_TYPE_CHBS) + for (i = 0; i < ARRAY_SIZE(mock_cedt.chbs); i++) { + h = (union acpi_subtable_headers *)&mock_cedt.chbs[i]; + end = (unsigned long)&mock_cedt.chbs[i + 1]; + handler_arg(h, arg, end); + } + + if (id == ACPI_CEDT_TYPE_CFMWS) + for (i = 0; i < ARRAY_SIZE(mock_cfmws); i++) { + h = (union acpi_subtable_headers *) mock_cfmws[i]; + end = (unsigned long) h + mock_cfmws[i]->header.length; + handler_arg(h, arg, end); + } + + return 0; } static bool is_mock_bridge(struct device *dev) @@ -388,8 +412,7 @@ static struct cxl_mock_ops cxl_mock_ops = { .is_mock_port = is_mock_port, .is_mock_dev = is_mock_dev, .mock_port = mock_cxl_root_port, - .acpi_get_table = mock_acpi_get_table, - .acpi_put_table = mock_acpi_put_table, + .acpi_table_parse_cedt = mock_acpi_table_parse_cedt, .acpi_evaluate_integer = mock_acpi_evaluate_integer, .acpi_pci_find_root = mock_acpi_pci_find_root, .list = LIST_HEAD_INIT(cxl_mock_ops.list), @@ -574,3 +597,4 @@ static __exit void cxl_test_exit(void) module_init(cxl_test_init); module_exit(cxl_test_exit); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(ACPI); diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c index b8c108abcf07..17408f892df4 100644 --- a/tools/testing/cxl/test/mock.c +++ b/tools/testing/cxl/test/mock.c @@ -58,36 +58,23 @@ bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode) } EXPORT_SYMBOL(__wrap_is_acpi_device_node); -acpi_status __wrap_acpi_get_table(char *signature, u32 instance, - struct acpi_table_header **out_table) +int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id, + acpi_tbl_entry_handler_arg handler_arg, + void *arg) { - int index; + int index, rc; struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); - acpi_status status; if (ops) - status = ops->acpi_get_table(signature, instance, out_table); + rc = ops->acpi_table_parse_cedt(id, handler_arg, arg); else - status = acpi_get_table(signature, instance, out_table); + rc = acpi_table_parse_cedt(id, handler_arg, arg); put_cxl_mock_ops(index); - return status; -} -EXPORT_SYMBOL(__wrap_acpi_get_table); - -void __wrap_acpi_put_table(struct acpi_table_header *table) -{ - int index; - struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); - - if (ops) - ops->acpi_put_table(table); - else - acpi_put_table(table); - put_cxl_mock_ops(index); + return rc; } -EXPORT_SYMBOL(__wrap_acpi_put_table); +EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI); acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle, acpi_string pathname, @@ -169,3 +156,4 @@ __wrap_nvdimm_bus_register(struct device *dev, EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(ACPI); diff --git a/tools/testing/cxl/test/mock.h b/tools/testing/cxl/test/mock.h index 805a94cb3fbe..15ed0fd877e4 100644 --- a/tools/testing/cxl/test/mock.h +++ b/tools/testing/cxl/test/mock.h @@ -6,9 +6,9 @@ struct cxl_mock_ops { struct list_head list; bool (*is_mock_adev)(struct acpi_device *dev); - acpi_status (*acpi_get_table)(char *signature, u32 instance, - struct acpi_table_header **out_table); - void (*acpi_put_table)(struct acpi_table_header *table); + int (*acpi_table_parse_cedt)(enum acpi_cedt_type id, + acpi_tbl_entry_handler_arg handler_arg, + void *arg); bool (*is_mock_bridge)(struct device *dev); acpi_status (*acpi_evaluate_integer)(acpi_handle handle, acpi_string pathname, -- cgit v1.2.3