From 39611e83a28c880881f4927d7bb2f5ea4ddf4526 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Jun 2018 20:08:54 -0700 Subject: tools/testing/nvdimm: Make DSM failure code injection an override In order to emulate the behavior of the NVDIMM_FAMILY_INTEL DSMs nfit_test needs the ability to execute the DSM and then override the return code. Split the current return code injection from get_dimm() and apply at after the function has executed to override the return status. Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit.c | 49 ++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index e2926f72a821..353a32ed96bc 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -884,6 +884,16 @@ static int nd_intel_test_cmd_set_lss_status(struct nfit_test *t, return 0; } +static int override_return_code(int dimm, unsigned int func, int rc) +{ + if ((1 << func) & dimm_fail_cmd_flags[dimm]) { + if (dimm_fail_cmd_code[dimm]) + return dimm_fail_cmd_code[dimm]; + return -EIO; + } + return rc; +} + static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func) { int i; @@ -894,13 +904,6 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func) break; if (i >= ARRAY_SIZE(handle)) return -ENXIO; - - if ((1 << func) & dimm_fail_cmd_flags[i]) { - if (dimm_fail_cmd_code[i]) - return dimm_fail_cmd_code[i]; - return -EIO; - } - return i; } @@ -939,48 +942,59 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, switch (func) { case ND_INTEL_ENABLE_LSS_STATUS: - return nd_intel_test_cmd_set_lss_status(t, + rc = nd_intel_test_cmd_set_lss_status(t, buf, buf_len); + break; case ND_INTEL_FW_GET_INFO: - return nd_intel_test_get_fw_info(t, buf, + rc = nd_intel_test_get_fw_info(t, buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_FW_START_UPDATE: - return nd_intel_test_start_update(t, buf, + rc = nd_intel_test_start_update(t, buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_FW_SEND_DATA: - return nd_intel_test_send_data(t, buf, + rc = nd_intel_test_send_data(t, buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_FW_FINISH_UPDATE: - return nd_intel_test_finish_fw(t, buf, + rc = nd_intel_test_finish_fw(t, buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_FW_FINISH_QUERY: - return nd_intel_test_finish_query(t, buf, + rc = nd_intel_test_finish_query(t, buf, buf_len, i - t->dcr_idx); + break; case ND_INTEL_SMART: - return nfit_test_cmd_smart(buf, buf_len, + rc = nfit_test_cmd_smart(buf, buf_len, &t->smart[i - t->dcr_idx]); + break; case ND_INTEL_SMART_THRESHOLD: - return nfit_test_cmd_smart_threshold(buf, + rc = nfit_test_cmd_smart_threshold(buf, buf_len, &t->smart_threshold[i - t->dcr_idx]); + break; case ND_INTEL_SMART_SET_THRESHOLD: - return nfit_test_cmd_smart_set_threshold(buf, + rc = nfit_test_cmd_smart_set_threshold(buf, buf_len, &t->smart_threshold[i - t->dcr_idx], &t->smart[i - t->dcr_idx], &t->pdev.dev, t->dimm_dev[i]); + break; case ND_INTEL_SMART_INJECT: - return nfit_test_cmd_smart_inject(buf, + rc = nfit_test_cmd_smart_inject(buf, buf_len, &t->smart_threshold[i - t->dcr_idx], &t->smart[i - t->dcr_idx], &t->pdev.dev, t->dimm_dev[i]); + break; default: return -ENOTTY; } + return override_return_code(i, func, rc); } if (!test_bit(cmd, &cmd_mask) @@ -1006,6 +1020,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, default: return -ENOTTY; } + return override_return_code(i, func, rc); } else { struct ars_state *ars_state = &t->ars_state; struct nd_cmd_pkg *call_pkg = buf; -- cgit v1.2.3 From e5d772fbe7685aae0dff99f3b54158a0ec32155e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Jun 2018 14:31:18 -0700 Subject: tools/testing/nvdimm: Fix support for emulating controller temperature In addition to populating the value the payload also needs to set the "controller temperature valid" flag. Fixes: cdd77d3e1930 ("nfit, libnvdimm: deprecate the generic SMART ioctl") Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 353a32ed96bc..a012ab765083 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -1323,7 +1323,8 @@ static void smart_init(struct nfit_test *t) | ND_INTEL_SMART_ALARM_VALID | ND_INTEL_SMART_USED_VALID | ND_INTEL_SMART_SHUTDOWN_VALID - | ND_INTEL_SMART_MTEMP_VALID, + | ND_INTEL_SMART_MTEMP_VALID + | ND_INTEL_SMART_CTEMP_VALID, .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH, .media_temperature = 23 * 16, .ctrl_temperature = 25 * 16, -- cgit v1.2.3 From 45df5d3dc0c7289c1e67afe6d2ba806ad5174314 Mon Sep 17 00:00:00 2001 From: Huaisheng Ye Date: Mon, 30 Jul 2018 15:15:45 +0800 Subject: tools/testing/nvdimm: kaddr and pfn can be NULL to ->direct_access() The mock / test version of pmem_direct_access() needs to check the validity of pointers kaddr and pfn for NULL assignment. If anyone equals to NULL, it doesn't need to calculate the value. If pointer equals to NULL, that is to say callers may have no need for kaddr or pfn, so this patch is prepared for allowing them to pass in NULL instead of having to pass in a local pointer or variable that they then just throw away. Suggested-by: Dan Williams Signed-off-by: Huaisheng Ye Reviewed-by: Ross Zwisler Signed-off-by: Dave Jiang --- tools/testing/nvdimm/pmem-dax.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/pmem-dax.c b/tools/testing/nvdimm/pmem-dax.c index b53596ad601b..2e7fd8227969 100644 --- a/tools/testing/nvdimm/pmem-dax.c +++ b/tools/testing/nvdimm/pmem-dax.c @@ -31,17 +31,21 @@ long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff, if (get_nfit_res(pmem->phys_addr + offset)) { struct page *page; - *kaddr = pmem->virt_addr + offset; + if (kaddr) + *kaddr = pmem->virt_addr + offset; page = vmalloc_to_page(pmem->virt_addr + offset); - *pfn = page_to_pfn_t(page); + if (pfn) + *pfn = page_to_pfn_t(page); pr_debug_ratelimited("%s: pmem: %p pgoff: %#lx pfn: %#lx\n", __func__, pmem, pgoff, page_to_pfn(page)); return 1; } - *kaddr = pmem->virt_addr + offset; - *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags); + if (kaddr) + *kaddr = pmem->virt_addr + offset; + if (pfn) + *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags); /* * If badblocks are present, limit known good range to the -- cgit v1.2.3 From b4d4702f30e09ed1311e560334eb25fc2015c8ce Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Mon, 30 Jul 2018 16:11:34 -0600 Subject: tools/testing/nvdimm: improve emulation of smart injection The emulation for smart injection commands for nfit neglected to check the smart field validity flags before injecting to that field. This is required as a way to distinguish un-injection vs. leave-alone. The emulation was also missing support for un-injection entirely. To add this support, first, fix the above flags check. Second, use the 'enable' field in the injection command to determine injection vs un-injection. Third, move the smart initialization struct to be a global static structure for the nfit_test module. Reference this to get the smart 'defaults' when un-injecting a smart field. Signed-off-by: Vishal Verma Signed-off-by: Dave Jiang --- tools/testing/nvdimm/test/nfit.c | 78 ++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index a012ab765083..cffc2c5a778d 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -142,6 +142,28 @@ static u32 handle[] = { static unsigned long dimm_fail_cmd_flags[NUM_DCR]; static int dimm_fail_cmd_code[NUM_DCR]; +static const struct nd_intel_smart smart_def = { + .flags = ND_INTEL_SMART_HEALTH_VALID + | ND_INTEL_SMART_SPARES_VALID + | ND_INTEL_SMART_ALARM_VALID + | ND_INTEL_SMART_USED_VALID + | ND_INTEL_SMART_SHUTDOWN_VALID + | ND_INTEL_SMART_MTEMP_VALID + | ND_INTEL_SMART_CTEMP_VALID, + .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH, + .media_temperature = 23 * 16, + .ctrl_temperature = 25 * 16, + .pmic_temperature = 40 * 16, + .spares = 75, + .alarm_flags = ND_INTEL_SMART_SPARE_TRIP + | ND_INTEL_SMART_TEMP_TRIP, + .ait_status = 1, + .life_used = 5, + .shutdown_state = 0, + .vendor_size = 0, + .shutdown_count = 100, +}; + struct nfit_test_fw { enum intel_fw_update_state state; u32 context; @@ -752,15 +774,30 @@ static int nfit_test_cmd_smart_inject( if (buf_len != sizeof(*inj)) return -EINVAL; - if (inj->mtemp_enable) - smart->media_temperature = inj->media_temperature; - if (inj->spare_enable) - smart->spares = inj->spares; - if (inj->fatal_enable) - smart->health = ND_INTEL_SMART_FATAL_HEALTH; - if (inj->unsafe_shutdown_enable) { - smart->shutdown_state = 1; - smart->shutdown_count++; + if (inj->flags & ND_INTEL_SMART_INJECT_MTEMP) { + if (inj->mtemp_enable) + smart->media_temperature = inj->media_temperature; + else + smart->media_temperature = smart_def.media_temperature; + } + if (inj->flags & ND_INTEL_SMART_INJECT_SPARE) { + if (inj->spare_enable) + smart->spares = inj->spares; + else + smart->spares = smart_def.spares; + } + if (inj->flags & ND_INTEL_SMART_INJECT_FATAL) { + if (inj->fatal_enable) + smart->health = ND_INTEL_SMART_FATAL_HEALTH; + else + smart->health = ND_INTEL_SMART_NON_CRITICAL_HEALTH; + } + if (inj->flags & ND_INTEL_SMART_INJECT_SHUTDOWN) { + if (inj->unsafe_shutdown_enable) { + smart->shutdown_state = 1; + smart->shutdown_count++; + } else + smart->shutdown_state = 0; } inj->status = 0; smart_notify(bus_dev, dimm_dev, smart, thresh); @@ -1317,30 +1354,9 @@ static void smart_init(struct nfit_test *t) .ctrl_temperature = 30 * 16, .spares = 5, }; - const struct nd_intel_smart smart_data = { - .flags = ND_INTEL_SMART_HEALTH_VALID - | ND_INTEL_SMART_SPARES_VALID - | ND_INTEL_SMART_ALARM_VALID - | ND_INTEL_SMART_USED_VALID - | ND_INTEL_SMART_SHUTDOWN_VALID - | ND_INTEL_SMART_MTEMP_VALID - | ND_INTEL_SMART_CTEMP_VALID, - .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH, - .media_temperature = 23 * 16, - .ctrl_temperature = 25 * 16, - .pmic_temperature = 40 * 16, - .spares = 75, - .alarm_flags = ND_INTEL_SMART_SPARE_TRIP - | ND_INTEL_SMART_TEMP_TRIP, - .ait_status = 1, - .life_used = 5, - .shutdown_state = 0, - .vendor_size = 0, - .shutdown_count = 100, - }; for (i = 0; i < t->num_dcr; i++) { - memcpy(&t->smart[i], &smart_data, sizeof(smart_data)); + memcpy(&t->smart[i], &smart_def, sizeof(smart_def)); memcpy(&t->smart_threshold[i], &smart_t_data, sizeof(smart_t_data)); } -- cgit v1.2.3