[ndctl PATCH] ndctl: update minimum namespace size
by Dan Williams
The kernel starting with version v4.16 supports a minimum namespace size
as low as PAGE_SIZE. Update the dpa-alloc test to account for the fact
that its 4K allocations may result in the namespace being activated with
its parent region.
Cc: Matthew Wilcox <willy(a)infradead.org>
Reported-by: Cheng-mean Liu <soccerl(a)microsoft.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
ndctl/ndctl.h | 3 ++-
test/dpa-alloc.c | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h
index 4cf373b2a5d4..eb5a9b387b3d 100644
--- a/ndctl/ndctl.h
+++ b/ndctl/ndctl.h
@@ -15,6 +15,7 @@
#include <ccan/array_size/array_size.h>
#include <linux/types.h>
+#include <sys/user.h>
struct nd_cmd_dimm_flags {
__u32 status;
@@ -210,7 +211,7 @@ enum nd_driver_flags {
};
enum {
- ND_MIN_NAMESPACE_SIZE = 0x00400000,
+ ND_MIN_NAMESPACE_SIZE = PAGE_SIZE,
};
enum ars_masks {
diff --git a/test/dpa-alloc.c b/test/dpa-alloc.c
index 7793650699da..8bb7dd7408a1 100644
--- a/test/dpa-alloc.c
+++ b/test/dpa-alloc.c
@@ -232,6 +232,11 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
uuid_unparse(namespaces[i].uuid, uuid_str);
size = ndctl_namespace_get_size(victim);
+ rc = ndctl_namespace_disable(victim);
+ if (rc) {
+ fprintf(stderr, "failed to disable %s\n", uuid_str);
+ return rc;
+ }
rc = ndctl_namespace_delete(victim);
if (rc) {
fprintf(stderr, "failed to delete %s\n", uuid_str);
4 years, 4 months
[PATCH v2 1/2] libnvdimm/nfit_test: add firmware download emulation
by Vishal Verma
From: Dave Jiang <dave.jiang(a)intel.com>
Adding support in nfit_test for DSM v1.6 firmware update sequence. The test
will simulate the flashing of firmware to the DIMM. A bogus version string
will be returned as the test has no idea how to parse the firmware binary.
Any bogus binary can be used to "update" as the actual binary is not copied
into the kernel.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
Reviewed-by: Vishal Verma <vishal.l.verma(a)intel.com>
[ vishal: also move smart calls into the nd_cmd_call block ]
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
tools/testing/nvdimm/test/nfit.c | 322 +++++++++++++++++++++++++++++++---
tools/testing/nvdimm/test/nfit_test.h | 66 ++++++-
2 files changed, 360 insertions(+), 28 deletions(-)
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 2b57254342aa..a043fea4d58d 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -137,6 +137,14 @@ static u32 handle[] = {
static unsigned long dimm_fail_cmd_flags[NUM_DCR];
+struct nfit_test_fw {
+ enum intel_fw_update_state state;
+ u32 context;
+ u64 version;
+ u32 size_received;
+ u64 end_time;
+};
+
struct nfit_test {
struct acpi_nfit_desc acpi_desc;
struct platform_device pdev;
@@ -172,6 +180,7 @@ struct nfit_test {
struct nd_intel_smart_threshold *smart_threshold;
struct badrange badrange;
struct work_struct work;
+ struct nfit_test_fw *fw;
};
static struct workqueue_struct *nfit_wq;
@@ -183,6 +192,226 @@ static struct nfit_test *to_nfit_test(struct device *dev)
return container_of(pdev, struct nfit_test, pdev);
}
+static int nd_intel_test_get_fw_info(struct nfit_test *t,
+ struct nd_intel_fw_info *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p, buf_len: %u, idx: %d\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ nd_cmd->status = 0;
+ nd_cmd->storage_size = INTEL_FW_STORAGE_SIZE;
+ nd_cmd->max_send_len = INTEL_FW_MAX_SEND_LEN;
+ nd_cmd->query_interval = INTEL_FW_QUERY_INTERVAL;
+ nd_cmd->max_query_time = INTEL_FW_QUERY_MAX_TIME;
+ nd_cmd->update_cap = 0;
+ nd_cmd->fis_version = INTEL_FW_FIS_VERSION;
+ nd_cmd->run_version = 0;
+ nd_cmd->updated_version = fw->version;
+
+ return 0;
+}
+
+static int nd_intel_test_start_update(struct nfit_test *t,
+ struct nd_intel_fw_start *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ if (fw->state != FW_STATE_NEW) {
+ /* extended status, FW update in progress */
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+
+ fw->state = FW_STATE_IN_PROGRESS;
+ fw->context++;
+ fw->size_received = 0;
+ nd_cmd->status = 0;
+ nd_cmd->context = fw->context;
+
+ dev_dbg(dev, "%s: context issued: %#x\n", __func__, nd_cmd->context);
+
+ return 0;
+}
+
+static int nd_intel_test_send_data(struct nfit_test *t,
+ struct nd_intel_fw_send_data *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+ u32 *status = (u32 *)&nd_cmd->data[nd_cmd->length];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+
+ dev_dbg(dev, "%s: cmd->status: %#x\n", __func__, *status);
+ dev_dbg(dev, "%s: cmd->data[0]: %#x\n", __func__, nd_cmd->data[0]);
+ dev_dbg(dev, "%s: cmd->data[%u]: %#x\n", __func__, nd_cmd->length-1,
+ nd_cmd->data[nd_cmd->length-1]);
+
+ if (fw->state != FW_STATE_IN_PROGRESS) {
+ dev_dbg(dev, "%s: not in IN_PROGRESS state\n", __func__);
+ *status = 0x5;
+ return 0;
+ }
+
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context, fw->context);
+ *status = 0x10007;
+ return 0;
+ }
+
+ /*
+ * check offset + len > size of fw storage
+ * check length is > max send length
+ */
+ if (nd_cmd->offset + nd_cmd->length > INTEL_FW_STORAGE_SIZE ||
+ nd_cmd->length > INTEL_FW_MAX_SEND_LEN) {
+ *status = 0x3;
+ dev_dbg(dev, "%s: buffer boundary violation\n", __func__);
+ return 0;
+ }
+
+ fw->size_received += nd_cmd->length;
+ dev_dbg(dev, "%s: copying %u bytes, %u bytes so far\n",
+ __func__, nd_cmd->length, fw->size_received);
+ *status = 0;
+ return 0;
+}
+
+static int nd_intel_test_finish_fw(struct nfit_test *t,
+ struct nd_intel_fw_finish_update *nd_cmd,
+ unsigned int buf_len, int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (fw->state == FW_STATE_UPDATED) {
+ /* update already done, need cold boot */
+ nd_cmd->status = 0x20007;
+ return 0;
+ }
+
+ dev_dbg(dev, "%s: context: %#x ctrl_flags: %#x\n",
+ __func__, nd_cmd->context, nd_cmd->ctrl_flags);
+
+ switch (nd_cmd->ctrl_flags) {
+ case 0: /* finish */
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context,
+ fw->context);
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+ nd_cmd->status = 0;
+ fw->state = FW_STATE_VERIFY;
+ /* set 1 second of time for firmware "update" */
+ fw->end_time = jiffies + HZ;
+ break;
+
+ case 1: /* abort */
+ fw->size_received = 0;
+ /* successfully aborted status */
+ nd_cmd->status = 0x40007;
+ fw->state = FW_STATE_NEW;
+ dev_dbg(dev, "%s: abort successful\n", __func__);
+ break;
+
+ default: /* bad control flag */
+ dev_warn(dev, "%s: unknown control flag: %#x\n",
+ __func__, nd_cmd->ctrl_flags);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int nd_intel_test_finish_query(struct nfit_test *t,
+ struct nd_intel_fw_finish_query *nd_cmd,
+ unsigned int buf_len, int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context, fw->context);
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+
+ dev_dbg(dev, "%s context: %#x\n", __func__, nd_cmd->context);
+
+ switch (fw->state) {
+ case FW_STATE_NEW:
+ nd_cmd->updated_fw_rev = 0;
+ nd_cmd->status = 0;
+ dev_dbg(dev, "%s: new state\n", __func__);
+ break;
+
+ case FW_STATE_IN_PROGRESS:
+ /* sequencing error */
+ nd_cmd->status = 0x40007;
+ nd_cmd->updated_fw_rev = 0;
+ dev_dbg(dev, "%s: sequence error\n", __func__);
+ break;
+
+ case FW_STATE_VERIFY:
+ if (time_is_after_jiffies64(fw->end_time)) {
+ nd_cmd->updated_fw_rev = 0;
+ nd_cmd->status = 0x20007;
+ dev_dbg(dev, "%s: still verifying\n", __func__);
+ break;
+ }
+
+ dev_dbg(dev, "%s: transition out verify\n", __func__);
+ fw->state = FW_STATE_UPDATED;
+ /* we are going to fall through if it's "done" */
+ case FW_STATE_UPDATED:
+ nd_cmd->status = 0;
+ /* bogus test version */
+ fw->version = nd_cmd->updated_fw_rev =
+ INTEL_FW_FAKE_VERSION;
+ dev_dbg(dev, "%s: updated\n", __func__);
+ break;
+
+ default: /* we should never get here */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size *nd_cmd,
unsigned int buf_len)
{
@@ -592,6 +821,23 @@ static int nfit_test_cmd_ars_inject_status(struct nfit_test *t,
return 0;
}
+static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
+{
+ int i;
+
+ /* lookup per-dimm data */
+ for (i = 0; i < ARRAY_SIZE(handle); i++)
+ if (__to_nfit_memdev(nfit_mem)->device_handle == handle[i])
+ break;
+ if (i >= ARRAY_SIZE(handle))
+ return -ENXIO;
+
+ if ((1 << func) & dimm_fail_cmd_flags[i])
+ return -EIO;
+
+ return i;
+}
+
static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
struct nvdimm *nvdimm, unsigned int cmd, void *buf,
unsigned int buf_len, int *cmd_rc)
@@ -620,22 +866,54 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
func = call_pkg->nd_command;
if (call_pkg->nd_family != nfit_mem->family)
return -ENOTTY;
+
+ i = get_dimm(nfit_mem, func);
+ if (i < 0)
+ return i;
+
+ switch (func) {
+ case ND_INTEL_FW_GET_INFO:
+ return nd_intel_test_get_fw_info(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_START_UPDATE:
+ return nd_intel_test_start_update(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_SEND_DATA:
+ return nd_intel_test_send_data(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_FINISH_UPDATE:
+ return nd_intel_test_finish_fw(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_FINISH_QUERY:
+ return nd_intel_test_finish_query(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_SMART:
+ return nfit_test_cmd_smart(buf, buf_len,
+ &t->smart[i - t->dcr_idx]);
+ case ND_INTEL_SMART_THRESHOLD:
+ return nfit_test_cmd_smart_threshold(buf,
+ buf_len,
+ &t->smart_threshold[i -
+ t->dcr_idx]);
+ case ND_INTEL_SMART_SET_THRESHOLD:
+ return 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]);
+ default:
+ return -ENOTTY;
+ }
}
if (!test_bit(cmd, &cmd_mask)
|| !test_bit(func, &nfit_mem->dsm_mask))
return -ENOTTY;
- /* lookup per-dimm data */
- for (i = 0; i < ARRAY_SIZE(handle); i++)
- if (__to_nfit_memdev(nfit_mem)->device_handle ==
- handle[i])
- break;
- if (i >= ARRAY_SIZE(handle))
- return -ENXIO;
-
- if ((1 << func) & dimm_fail_cmd_flags[i])
- return -EIO;
+ i = get_dimm(nfit_mem, func);
+ if (i < 0)
+ return i;
switch (func) {
case ND_CMD_GET_CONFIG_SIZE:
@@ -649,20 +927,6 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
rc = nfit_test_cmd_set_config_data(buf, buf_len,
t->label[i - t->dcr_idx]);
break;
- case ND_INTEL_SMART:
- rc = nfit_test_cmd_smart(buf, buf_len,
- &t->smart[i - t->dcr_idx]);
- break;
- case ND_INTEL_SMART_THRESHOLD:
- rc = nfit_test_cmd_smart_threshold(buf, buf_len,
- &t->smart_threshold[i - t->dcr_idx]);
- break;
- case ND_INTEL_SMART_SET_THRESHOLD:
- 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;
default:
return -ENOTTY;
}
@@ -1728,6 +1992,11 @@ static void nfit_test0_setup(struct nfit_test *t)
set_bit(NFIT_CMD_ARS_INJECT_SET, &acpi_desc->bus_nfit_cmd_force_en);
set_bit(NFIT_CMD_ARS_INJECT_CLEAR, &acpi_desc->bus_nfit_cmd_force_en);
set_bit(NFIT_CMD_ARS_INJECT_GET, &acpi_desc->bus_nfit_cmd_force_en);
+ set_bit(ND_INTEL_FW_GET_INFO, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_START_UPDATE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_SEND_DATA, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_FINISH_UPDATE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_FINISH_QUERY, &acpi_desc->dimm_cmd_force_en);
}
static void nfit_test1_setup(struct nfit_test *t)
@@ -2134,10 +2403,13 @@ static int nfit_test_probe(struct platform_device *pdev)
nfit_test->smart_threshold = devm_kcalloc(dev, num,
sizeof(struct nd_intel_smart_threshold),
GFP_KERNEL);
+ nfit_test->fw = devm_kcalloc(dev, num,
+ sizeof(struct nfit_test_fw), GFP_KERNEL);
if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label
&& nfit_test->label_dma && nfit_test->dcr
&& nfit_test->dcr_dma && nfit_test->flush
- && nfit_test->flush_dma)
+ && nfit_test->flush_dma
+ && nfit_test->fw)
/* pass */;
else
return -ENOMEM;
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index ba230f6f7676..be8fa8ec0615 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -84,9 +84,14 @@ struct nd_cmd_ars_err_inj_stat {
} __packed record[0];
} __packed;
-#define ND_INTEL_SMART 1
-#define ND_INTEL_SMART_THRESHOLD 2
-#define ND_INTEL_SMART_SET_THRESHOLD 17
+#define ND_INTEL_SMART 1
+#define ND_INTEL_SMART_THRESHOLD 2
+#define ND_INTEL_FW_GET_INFO 12
+#define ND_INTEL_FW_START_UPDATE 13
+#define ND_INTEL_FW_SEND_DATA 14
+#define ND_INTEL_FW_FINISH_UPDATE 15
+#define ND_INTEL_FW_FINISH_QUERY 16
+#define ND_INTEL_SMART_SET_THRESHOLD 17
#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
@@ -152,6 +157,61 @@ struct nd_intel_smart_set_threshold {
__u32 status;
} __packed;
+#define INTEL_FW_STORAGE_SIZE 0x100000
+#define INTEL_FW_MAX_SEND_LEN 0xFFEC
+#define INTEL_FW_QUERY_INTERVAL 250000
+#define INTEL_FW_QUERY_MAX_TIME 3000000
+#define INTEL_FW_FIS_VERSION 0x0105
+#define INTEL_FW_FAKE_VERSION 0xffffffffabcd
+
+enum intel_fw_update_state {
+ FW_STATE_NEW = 0,
+ FW_STATE_IN_PROGRESS,
+ FW_STATE_VERIFY,
+ FW_STATE_UPDATED,
+};
+
+struct nd_intel_fw_info {
+ __u32 status;
+ __u32 storage_size;
+ __u32 max_send_len;
+ __u32 query_interval;
+ __u32 max_query_time;
+ __u8 update_cap;
+ __u8 reserved[3];
+ __u32 fis_version;
+ __u64 run_version;
+ __u64 updated_version;
+} __packed;
+
+struct nd_intel_fw_start {
+ __u32 status;
+ __u32 context;
+} __packed;
+
+/* this one has the output first because the variable input data size */
+struct nd_intel_fw_send_data {
+ __u32 context;
+ __u32 offset;
+ __u32 length;
+ __u8 data[0];
+/* this field is not declared due ot variable data from input */
+/* __u32 status; */
+} __packed;
+
+struct nd_intel_fw_finish_update {
+ __u8 ctrl_flags;
+ __u8 reserved[3];
+ __u32 context;
+ __u32 status;
+} __packed;
+
+struct nd_intel_fw_finish_query {
+ __u32 context;
+ __u32 status;
+ __u64 updated_fw_rev;
+} __packed;
+
union acpi_object;
typedef void *acpi_handle;
--
2.14.3
4 years, 4 months
[PATCH] tools/testing/nvdimm: force nfit_test to depend on instrumented modules
by Dan Williams
The libnvdimm unit tests will fail when they are run against the
production / in-tree version of libnvdimm.ko or nfit.ko due to
symbols not being mocked per nfit_test's expectation. For example,
nfit_test expects acpi_evaluate_dsm() to be replaced by
__wrap_acpi_evaluate_dsm() to test how acpi_nfit_ctl() responds to
different stimuli.
Create a test-only symbol name that nfit_test links against to cause
module load failures when the wrong module is present.
For example, with this change, attempts to use the wrong module will
report:
nfit_test: Unknown symbol libnvdimm_test (err 0)
Reported-by: Dave Jiang <dave.jiang(a)intel.com>
Reported-by: Vishal Verma <vishal.l.verma(a)intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
tools/testing/nvdimm/Kbuild | 4 ++++
tools/testing/nvdimm/acpi_nfit_test.c | 8 ++++++++
tools/testing/nvdimm/device_dax_test.c | 8 ++++++++
tools/testing/nvdimm/libnvdimm_test.c | 8 ++++++++
tools/testing/nvdimm/pmem_test.c | 8 ++++++++
tools/testing/nvdimm/test/nfit.c | 6 ++++++
tools/testing/nvdimm/watermark.h | 21 +++++++++++++++++++++
7 files changed, 63 insertions(+)
create mode 100644 tools/testing/nvdimm/acpi_nfit_test.c
create mode 100644 tools/testing/nvdimm/device_dax_test.c
create mode 100644 tools/testing/nvdimm/libnvdimm_test.c
create mode 100644 tools/testing/nvdimm/pmem_test.c
create mode 100644 tools/testing/nvdimm/watermark.h
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index db33b28c5ef3..0392153a0009 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -37,10 +37,12 @@ obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
nfit-y := $(ACPI_SRC)/core.o
nfit-$(CONFIG_X86_MCE) += $(ACPI_SRC)/mce.o
+nfit-y += acpi_nfit_test.o
nfit-y += config_check.o
nd_pmem-y := $(NVDIMM_SRC)/pmem.o
nd_pmem-y += pmem-dax.o
+nd_pmem-y += pmem_test.o
nd_pmem-y += config_check.o
nd_btt-y := $(NVDIMM_SRC)/btt.o
@@ -57,6 +59,7 @@ dax-y += config_check.o
device_dax-y := $(DAX_SRC)/device.o
device_dax-y += dax-dev.o
+device_dax-y += device_dax_test.o
device_dax-y += config_check.o
dax_pmem-y := $(DAX_SRC)/pmem.o
@@ -75,6 +78,7 @@ libnvdimm-$(CONFIG_ND_CLAIM) += $(NVDIMM_SRC)/claim.o
libnvdimm-$(CONFIG_BTT) += $(NVDIMM_SRC)/btt_devs.o
libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
+libnvdimm-y += libnvdimm_test.o
libnvdimm-y += config_check.o
obj-m += test/
diff --git a/tools/testing/nvdimm/acpi_nfit_test.c b/tools/testing/nvdimm/acpi_nfit_test.c
new file mode 100644
index 000000000000..43521512e577
--- /dev/null
+++ b/tools/testing/nvdimm/acpi_nfit_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(acpi_nfit);
diff --git a/tools/testing/nvdimm/device_dax_test.c b/tools/testing/nvdimm/device_dax_test.c
new file mode 100644
index 000000000000..24b17bf42429
--- /dev/null
+++ b/tools/testing/nvdimm/device_dax_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(device_dax);
diff --git a/tools/testing/nvdimm/libnvdimm_test.c b/tools/testing/nvdimm/libnvdimm_test.c
new file mode 100644
index 000000000000..00ca30b23932
--- /dev/null
+++ b/tools/testing/nvdimm/libnvdimm_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(libnvdimm);
diff --git a/tools/testing/nvdimm/pmem_test.c b/tools/testing/nvdimm/pmem_test.c
new file mode 100644
index 000000000000..fd38f92275cf
--- /dev/null
+++ b/tools/testing/nvdimm/pmem_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(pmem);
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 2b57254342aa..77bd5d096333 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -27,6 +27,7 @@
#include <nfit.h>
#include <nd.h>
#include "nfit_test.h"
+#include "../watermark.h"
/*
* Generate an NFIT table to describe the following topology:
@@ -2239,6 +2240,11 @@ static __init int nfit_test_init(void)
{
int rc, i;
+ pmem_test();
+ libnvdimm_test();
+ acpi_nfit_test();
+ device_dax_test();
+
nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
nfit_wq = create_singlethread_workqueue("nfit");
diff --git a/tools/testing/nvdimm/watermark.h b/tools/testing/nvdimm/watermark.h
new file mode 100644
index 000000000000..ed0528757bd4
--- /dev/null
+++ b/tools/testing/nvdimm/watermark.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+#ifndef _TEST_NVDIMM_WATERMARK_H_
+#define _TEST_NVDIMM_WATERMARK_H_
+int pmem_test(void);
+int libnvdimm_test(void);
+int acpi_nfit_test(void);
+int device_dax_test(void);
+
+/*
+ * dummy routine for nfit_test to validate it is linking to the properly
+ * mocked module and not the standard one from the base tree.
+ */
+#define nfit_test_watermark(x) \
+int x##_test(void) \
+{ \
+ pr_debug("%s for nfit_test\n", KBUILD_MODNAME); \
+ return 0; \
+} \
+EXPORT_SYMBOL(x##_test)
+#endif /* _TEST_NVDIMM_WATERMARK_H_ */
4 years, 4 months
[LSF/MM TOPIC] Filesystem-DAX, page-pinning, and RDMA
by Dan Williams
The get_user_pages_longterm() api was recently added as a stop-gap
measure to prevent applications from growing dependencies on the
ability to to pin DAX-mapped filesystem blocks for RDMA indefinitely
with no ongoing coordination with the filesystem. This 'longterm'
pinning is also problematic for the non-DAX VMA case where the core-mm
needs a time bounded way to revoke a pin and manipulate the physical
pages. While existing RDMA applications have already grown the
assumption that they can pin page-cache pages indefinitely, the fact
that we are breaking this assumption for filesystem-dax presents an
opportunity to deprecate the 'indefinite pin' mechanisms and move to a
general interface that supports pin revocation.
While RDMA may grow an explicit Infiniband-verb for this 'memory
registration with lease' semantic, it seems that this problem is
bigger than just RDMA. At LSF/MM it would be useful to have a
discussion between fs, mm, dax, and RDMA folks about addressing this
problem at the core level.
Particular people that would be useful to have in attendance are
Michal Hocko, Christoph Hellwig, and Jason Gunthorpe (cc'd).
4 years, 4 months
[PATCH 2] xfs: fix rt_dev usage for DAX
by Dave Jiang
When using realtime device (rtdev) with xfs where the data device is not
DAX capable, two issues arise. One is when data device is not DAX but the
realtime device is DAX capable, we currently disable DAX.
After passing this check, we are also not marking the inode as DAX capable.
This change will allow DAX enabled if the data device or the realtime
device is DAX capable. S_DAX will be marked for the inode if the file is
residing on a DAX capable device. This will prevent the case of rtdev is not
DAX and data device is DAX to create realtime files.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
Reported-by: Darrick Wong <darrick.wong(a)oracle.com>
---
fs/xfs/xfs_iops.c | 3 ++-
fs/xfs/xfs_super.c | 9 ++++++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 56475fcd76f2..ab352c325301 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1204,7 +1204,8 @@ xfs_diflags_to_iflags(
ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
!xfs_is_reflink_inode(ip) &&
(ip->i_mount->m_flags & XFS_MOUNT_DAX ||
- ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+ ip->i_d.di_flags2 & XFS_DIFLAG2_DAX) &&
+ blk_queue_dax(bdev_get_queue(inode->i_sb->s_bdev)))
inode->i_flags |= S_DAX;
}
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index e8a687232614..5ac478924dce 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1649,11 +1649,18 @@ xfs_fs_fill_super(
sb->s_flags |= SB_I_VERSION;
if (mp->m_flags & XFS_MOUNT_DAX) {
+ bool rtdev_is_dax = false;
+
xfs_warn(mp,
"DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
+ if (mp->m_rtdev_targp->bt_daxdev)
+ if (bdev_dax_supported(mp->m_rtdev_targp->bt_bdev,
+ sb->s_blocksize) == 0)
+ rtdev_is_dax = true;
+
error = bdev_dax_supported(sb->s_bdev, sb->s_blocksize);
- if (error) {
+ if (error && !rtdev_is_dax) {
xfs_alert(mp,
"DAX unsupported by block device. Turning off DAX.");
mp->m_flags &= ~XFS_MOUNT_DAX;
4 years, 4 months
[PATCH v5 0/4] ndctl: add DIMM firmware update support
by Dave Jiang
The following series implements support for DIMM firmware update in ndctl.
v5: fixed rebase conflict against latest ndctl master branch.
v4: Addressed Vishal's comments
- replaced copyright header
- changed gettimeofday to clock_gettime
- changed return error for verify_fw_size()
v3: Addressed Dan's comments
- Removed Intel specific bits from update get info.
- Added inherited context for related commands
- Moved all input params into new_cmd function.
- Added translated status return
---
Dave Jiang (4):
ndctl: add support to alloc_intel_cmd for variable payload
ndctl: add firmware download support functions in libndctl
ndctl: add firmware update command option for ndctl
ndctl, test: firmware update unit test
Documentation/ndctl/Makefile.am | 1
Documentation/ndctl/ndctl-update-firmware.txt | 18 +
builtin.h | 1
ndctl/Makefile.am | 3
ndctl/lib/Makefile.am | 1
ndctl/lib/firmware.c | 109 +++++
ndctl/lib/intel.c | 264 ++++++++++++
ndctl/lib/intel.h | 77 ++++
ndctl/lib/libndctl.sym | 15 +
ndctl/lib/private.h | 16 +
ndctl/libndctl.h | 36 ++
ndctl/ndctl.c | 1
ndctl/update.c | 534 +++++++++++++++++++++++++
test/Makefile.am | 3
test/firmware-update.sh | 65 +++
15 files changed, 1141 insertions(+), 3 deletions(-)
create mode 100644 Documentation/ndctl/ndctl-update-firmware.txt
create mode 100644 ndctl/lib/firmware.c
create mode 100644 ndctl/update.c
create mode 100755 test/firmware-update.sh
--
Signature
4 years, 4 months
Kaggle and Interactions user's List
by Vivian Gray
Hi,
Hope you're doing great. We are a global database provider and preferred partners for Enterprise, Media and Small size companies.
I am writing to you in regards to our recent lists released, and check if you would be interested in acquiring our recently verified Machine Learning Software User's list and Other Related Software User's database.
We do have Users of:
* Kaggle
* Interactions
* Tractica
* arya.ai and many more.
We can also provide other Technologies users such as MS Dynamics users, SAP users, Citrix users, Avaya users, VMware users, JD Edward users, IBM users, Sage users and many more
List Source:
" Direct Research & Subscriptions from websites
" Government records and listings
" Annual reports and public filings
" Yellow pages
" Opt-in email campaigns
" Online Surveys and feedback forms
" Tradeshows and conferences
Other multi-channel programs we are mainly specialized in Technology Industry Database currently holding 3200+ application users type.
This list comes with full contact details like: First and Last names, Organization, Job title and responsibility, Company mailing address, Opt-In Email address, telephone number, email address, fax number, zip code, Province, State, Country, Employee Size, Industry, SIC Code, Zip code etc. across USA, UK and more over the globe. Which help you reach out to your potential clients / market expansion.
Every contact from this database has completed verification as on 30th of December 2017 to give you 95%+ accuracy.
If you are interested, please mention your target geography and which software users list require to you. Then we will furnish you with counts, pricing, samples and more information.
Regards,
Vivian Gray
Sr. Demand Generation Executive
If you don't wish to receive any further emails plz reply with Opt Out.
4 years, 4 months
[ndctl PATCH] ndctl: remove a double put in injection status json
by Vishal Verma
newer json-c catches a double put of the json object in printing the
injection status. We only need to put the containing jobj.
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
ndctl/inject-error.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/ndctl/inject-error.c b/ndctl/inject-error.c
index 374ae0b..9b9d821 100644
--- a/ndctl/inject-error.c
+++ b/ndctl/inject-error.c
@@ -263,8 +263,6 @@ static int injection_status(struct ndctl_namespace *ndns)
printf("%s\n", json_object_to_json_string_ext(jobj,
JSON_C_TO_STRING_PRETTY));
}
-
- json_object_put(jbbs);
json_object_put(jobj);
return rc;
--
2.14.3
4 years, 4 months
[PATCH] xfs: fix rt_dev usage for DAX
by Dave Jiang
When using realtime device (rtdev) with xfs where the data device is not
DAX capable, two issues arise. One is when data device is not DAX but the
realtime device is DAX capable, we currently disable DAX.
After passing this check, we are also not marking the inode as DAX capable.
This change will allow DAX enabled if the data device or the realtime
device is DAX capable. S_DAX will be marked for the inode if the file is
residing on a DAX capable device. This will prevent the case of rtdev is not
DAX and data device is DAX to create realtime files.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
Reported-by: Darrick Wong <darrick.wong(a)oracle.com>
---
fs/xfs/xfs_iops.c | 3 ++-
fs/xfs/xfs_super.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 56475fcd76f2..ab352c325301 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1204,7 +1204,8 @@ xfs_diflags_to_iflags(
ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
!xfs_is_reflink_inode(ip) &&
(ip->i_mount->m_flags & XFS_MOUNT_DAX ||
- ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+ ip->i_d.di_flags2 & XFS_DIFLAG2_DAX) &&
+ blk_queue_dax(bdev_get_queue(inode->i_sb->s_bdev)))
inode->i_flags |= S_DAX;
}
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 1dacccc367f8..2b2a02bcf72e 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1653,7 +1653,7 @@ xfs_fs_fill_super(
"DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
error = bdev_dax_supported(sb, sb->s_blocksize);
- if (error) {
+ if (error && !mp->m_rtdev_targp->bt_daxdev) {
xfs_alert(mp,
"DAX unsupported by block device. Turning off DAX.");
mp->m_flags &= ~XFS_MOUNT_DAX;
4 years, 4 months