[PATCH v3 0/7] Enable DSM pass thru for root functions
by Jerry Hoemann
The ACPI 6.2 spec added NVDIMM root DSM functions that managibility
and test software need to call.
This patch set enables the calling of root functions DSMs via the
pass thru mechanism.
Changes v4
----------
1. Minor refactoring of patch sequence.
Changes v3
----------
1. Fix checkpatch warnings
2. modify bus_dsm_mask_show to display name "dsm_mask" in sysfs.
3. modified submittal comments.
Changes v2
----------
1. Add bus_dsm_mask to filter root pass thru calls.
2. Add bus_dsm_mask_show to display bus_dsm_mask in sysfs
3. Extend override_dsm_mask to be used for bus_dms_mask also.
Details v1
----------
__nd_ioctl:
Check pass thru functions against nd_cmd_clear_to_send.
acpi_nfit_init_dsms:
Set additional bits in cmd_mask for new functions.
ndctl.h:
Define data structure for the new 6.2 functions.
Jerry Hoemann (6):
libnvdimm: passthru functions clear to send
acpi, nfit: Enable DSM pass thru for root functions.
libnvdimm, acpi, nfit: Add bus level dsm mask for pass thru.
acpi, nfit: Show bus_dsm_mask in sysfs
libnvdimm: New ACPI 6.2 DSM functions
nfit allow override of root dsm mask
drivers/acpi/nfit/core.c | 23 +++++++++++++++++++++++
drivers/nvdimm/bus.c | 4 +++-
include/linux/libnvdimm.h | 1 +
include/uapi/linux/ndctl.h | 41 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 2 deletions(-)
--
1.8.5.6
3 years, 6 months
[PATCH v4 00/16] pmem: stop abusing copy_user_nocache(), and other reworks
by Dan Williams
Changes since v3 [1]:
* Remove default copy_from_iter() fallback in the dax core (Christoph).
* Don't abuse block/queue sysfs for cache-flush control, introduce a
dax-specific interface (Christoph).
* Don't export clean_cache_range() export an arch_wb_cache_pmem() wrapper
instead (Christoph). This also allows us to remove asm/pmem.h along
with include/linux/pmem.h.
[1]: https://lkml.org/lkml/2017/6/9/842
The changes above are constrained to the last 4 patches of the series.
Patch1 still needs Al's review.
---
A few months back, in the course of reviewing the memcpy_nocache()
proposal from Brian, Linus proposed that the pmem specific
memcpy_to_pmem() routine be moved to be implemented at the driver level
[2]:
"Quite frankly, the whole 'memcpy_nocache()' idea or (ab-)using
copy_user_nocache() just needs to die. It's idiotic.
As you point out, it's also fundamentally buggy crap.
Throw it away. There is no possible way this is ever valid or
portable. We're not going to lie and claim that it is.
If some driver ends up using 'movnt' by hand, that is up to that
*driver*. But no way in hell should we care about this one whit in
the sense of <linux/uaccess.h>."
This feedback also dovetails with another fs/dax.c design wart of being
hard coded to assume the backing device is pmem. We call the pmem
specific copy, clear, and flush routines even if the backing device
driver is one of the other 3 dax drivers (axonram, dccssblk, or brd).
There is no reason to spend cpu cycles flushing the cache after writing
to brd, for example, since it is using volatile memory for storage.
Moreover, the pmem driver might be fronting a volatile memory range
published by the ACPI NFIT, or the platform might have arranged to flush
cpu caches on power fail. This latter capability is a feature that has
appeared in embedded storage appliances (pre-ACPI-NFIT nvdimm
platforms).
Now, the comment about completely avoiding uaccess.h is augmented by
Al's recent assertion:
"And for !@#!@# sake, comments like this
+ * On x86_64 __copy_from_user_nocache() uses non-temporal stores
+ * for the bulk of the transfer, but we need to manually flush
+ * if the transfer is unaligned. A cached memory copy is used
+ * when destination or size is not naturally aligned. That is:
+ * - Require 8-byte alignment when size is 8 bytes or larger.
+ * - Require 4-byte alignment when size is 4 bytes.
mean only one thing: this should live in arch/x86/lib/usercopy_64.c,
right next to the actual function that does copying. NOT in
drivers/nvdimm/x86.c. At the very least it needs a comment in usercopy_64.c
with dire warnings along the lines of "don't touch that code without
looking into <filename>:pmem_from_user().."
So, this series proceeds to keep all the usercopy code centralized. The
change set:
1/ Moves what was previously named "the pmem api" out of the global
namespace and into the libnvdimm sub-system that needs to be
concerned with architecture specific persistent memory considerations.
2/ Arranges for dax to stop abusing __copy_user_nocache() and implements
formal _flushcache helpers that use 'movnt' on x86_64.
3/ Makes filesystem-dax cache maintenance optional by arranging for dax
to call driver specific copy and flush operations only if the driver
publishes them.
4/ Allows filesytem-dax cache-flushing to be controlled by a new
'dax/write_cache' sysfs attribute. The pmem driver is updated to
clear the flag by default when pmem is driving volatile memory. ACPI
6.2 defines a mechanism to detect if the platform handles cpu cache
flushing for pmem and will be used to set the default for this flag.
[2]: https://lists.01.org/pipermail/linux-nvdimm/2017-January/008364.html
This series is based on v4.12-rc4 and passes the current ndctl
regression suite.
---
Dan Williams (16):
x86, uaccess: introduce copy_from_iter_flushcache for pmem / cache-bypass operations
dm: add ->copy_from_iter() dax operation support
filesystem-dax: convert to dax_copy_from_iter()
dax, pmem: introduce an optional 'flush' dax_operation
dm: add ->flush() dax operation support
filesystem-dax: convert to dax_flush()
x86, dax: replace clear_pmem() with open coded memset + dax_ops->flush
x86, dax, libnvdimm: remove wb_cache_pmem() indirection
x86, libnvdimm, pmem: move arch_invalidate_pmem() to libnvdimm
x86, libnvdimm, pmem: remove global pmem api
libnvdimm, pmem: fix persistence warning
libnvdimm, nfit: enable support for volatile ranges
dax: remove default copy_from_iter fallback
dax: convert to bitmask for flags
libnvdimm, pmem, dax: export a cache control attribute
libnvdimm, pmem: disable dax flushing when pmem is fronting a volatile region
MAINTAINERS | 4 -
arch/powerpc/sysdev/axonram.c | 8 ++
arch/x86/Kconfig | 1
arch/x86/include/asm/pmem.h | 136 -----------------------------------
arch/x86/include/asm/string_64.h | 5 +
arch/x86/include/asm/uaccess_64.h | 11 +++
arch/x86/lib/usercopy_64.c | 134 +++++++++++++++++++++++++++++++++++
arch/x86/mm/pageattr.c | 6 ++
drivers/acpi/nfit/core.c | 15 +++-
drivers/block/brd.c | 8 ++
drivers/dax/super.c | 118 +++++++++++++++++++++++++++++--
drivers/md/dm-linear.c | 30 ++++++++
drivers/md/dm-stripe.c | 40 ++++++++++
drivers/md/dm.c | 45 ++++++++++++
drivers/nvdimm/bus.c | 8 +-
drivers/nvdimm/claim.c | 6 +-
drivers/nvdimm/core.c | 2 -
drivers/nvdimm/dax_devs.c | 2 -
drivers/nvdimm/dimm_devs.c | 10 ++-
drivers/nvdimm/namespace_devs.c | 14 +---
drivers/nvdimm/nd-core.h | 9 ++
drivers/nvdimm/pfn_devs.c | 4 +
drivers/nvdimm/pmem.c | 40 +++++++++-
drivers/nvdimm/pmem.h | 14 ++++
drivers/nvdimm/region_devs.c | 43 +++++++----
drivers/s390/block/dcssblk.c | 8 ++
fs/dax.c | 9 +-
include/linux/dax.h | 12 +++
include/linux/device-mapper.h | 6 ++
include/linux/libnvdimm.h | 2 +
include/linux/pmem.h | 142 -------------------------------------
include/linux/string.h | 6 ++
include/linux/uio.h | 15 ++++
lib/Kconfig | 3 +
lib/iov_iter.c | 22 ++++++
35 files changed, 597 insertions(+), 341 deletions(-)
delete mode 100644 arch/x86/include/asm/pmem.h
delete mode 100644 include/linux/pmem.h
3 years, 6 months
[ndctl PATCH v2] ndctl, test: unit test updates for the BTT 2.0 format
by Vishal Verma
With the BTT 2.0 update, a couple of minor updates to the unit tests are
needed:
test/libndctl: Update expected BTT sizes
test/libndctl: in btt_autodetect, when wiping an old BTT, wipe the first
two 4K pages instead of one.
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
v2:
- Move the new BTT size check under a 4.13.0 attempt (Dan)
test/libndctl.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/test/libndctl.c b/test/libndctl.c
index 24aff36..0f67d54 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -994,16 +994,16 @@ static int check_btt_size(struct ndctl_btt *btt)
int size_select, sect_select;
unsigned long long expect_table[][2] = {
[0] = {
- [0] = 0x11b4400,
- [1] = 0x8da2000,
+ [0] = 0x11b5400,
+ [1] = 0x8daa000,
},
[1] = {
- [0] = 0x13b0400,
- [1] = 0x9d82000,
+ [0] = 0x13b1400,
+ [1] = 0x9d8a000,
},
[2] = {
- [0] = 0x1aa2600,
- [1] = 0xd513000,
+ [0] = 0x1aa3600,
+ [1] = 0xd51b000,
},
};
@@ -1107,9 +1107,12 @@ static int check_btt_create(struct ndctl_region *region, struct ndctl_namespace
devname, mode);
}
- rc = check_btt_size(btt);
- if (rc)
- goto err;
+ /* prior to v4.13 the expected sizes were different due to BTT1.1 */
+ if (ndctl_test_attempt(test, KERNEL_VERSION(4, 13, 0))) {
+ rc = check_btt_size(btt);
+ if (rc)
+ goto err;
+ }
if (btt_seed == ndctl_region_get_btt_seed(region)
&& btt == btt_seed) {
@@ -1517,12 +1520,19 @@ static int check_btt_autodetect(struct ndctl_bus *bus,
}
memset(buf, 0, 4096);
+ /* Delete both the first and second 4K pages */
rc = pwrite(fd, buf, 4096, 4096);
if (rc < 4096) {
rc = -ENXIO;
fprintf(stderr, "%s: failed to overwrite btt on %s\n",
devname, bdev);
}
+ rc = pwrite(fd, buf, 4096, 0);
+ if (rc < 4096) {
+ rc = -ENXIO;
+ fprintf(stderr, "%s: failed to overwrite btt on %s\n",
+ devname, bdev);
+ }
out:
ndctl_region_set_ro(region, namespace->ro);
ndctl_namespace_set_raw_mode(ndns, 0);
--
2.9.3
3 years, 6 months
[PATCH v2] libnvdimm, pmem: Add sysfs notifications to badblocks
by Toshi Kani
Sysfs "badblocks" information may be updated during run-time that:
- MCE, SCI, and sysfs "scrub" may add new bad blocks
- Writes and ioctl() may clear bad blocks
Add support to send sysfs notifications to sysfs "badblocks" file
under region and pmem directories when their badblocks information
is re-evaluated (but is not necessarily changed) during run-time.
Signed-off-by: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Vishal Verma <vishal.l.verma(a)intel.com>
Cc: Linda Knippers <linda.knippers(a)hpe.com>
---
v2: Send notifications for the clearing case
---
drivers/nvdimm/bus.c | 3 +++
drivers/nvdimm/nd.h | 1 +
drivers/nvdimm/pmem.c | 14 ++++++++++++++
drivers/nvdimm/pmem.h | 1 +
drivers/nvdimm/region.c | 12 ++++++++++--
5 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index e9361bf..63ce50d 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -198,6 +198,9 @@ static int nvdimm_clear_badblocks_region(struct device *dev, void *data)
sector = (ctx->phys - nd_region->ndr_start) / 512;
badblocks_clear(&nd_region->bb, sector, ctx->cleared / 512);
+ if (nd_region->bb_state)
+ sysfs_notify_dirent(nd_region->bb_state);
+
return 0;
}
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 03852d7..4bb57ff 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -155,6 +155,7 @@ struct nd_region {
u64 ndr_start;
int id, num_lanes, ro, numa_node;
void *provider_data;
+ struct kernfs_node *bb_state;
struct badblocks bb;
struct nd_interleave_set *nd_set;
struct nd_percpu_lane __percpu *lane;
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index c544d46..6c14c72 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -68,6 +68,8 @@ static int pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
(unsigned long long) sector, cleared,
cleared > 1 ? "s" : "");
badblocks_clear(&pmem->bb, sector, cleared);
+ if (pmem->bb_state)
+ sysfs_notify_dirent(pmem->bb_state);
}
invalidate_pmem(pmem->virt_addr + offset, len);
@@ -377,6 +379,13 @@ static int pmem_attach_disk(struct device *dev,
revalidate_disk(disk);
+ pmem->bb_state = sysfs_get_dirent(disk_to_dev(disk)->kobj.sd,
+ "badblocks");
+ if (pmem->bb_state)
+ sysfs_put(pmem->bb_state);
+ else
+ dev_warn(dev, "sysfs_get_dirent 'badblocks' failed\n");
+
return 0;
}
@@ -428,6 +437,7 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
struct nd_namespace_io *nsio;
struct resource res;
struct badblocks *bb;
+ struct kernfs_node *bb_state;
if (event != NVDIMM_REVALIDATE_POISON)
return;
@@ -439,11 +449,13 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
nd_region = to_nd_region(ndns->dev.parent);
nsio = to_nd_namespace_io(&ndns->dev);
bb = &nsio->bb;
+ bb_state = NULL;
} else {
struct pmem_device *pmem = dev_get_drvdata(dev);
nd_region = to_region(pmem);
bb = &pmem->bb;
+ bb_state = pmem->bb_state;
if (is_nd_pfn(dev)) {
struct nd_pfn *nd_pfn = to_nd_pfn(dev);
@@ -463,6 +475,8 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
res.start = nsio->res.start + offset;
res.end = nsio->res.end - end_trunc;
nvdimm_badblocks_populate(nd_region, bb, &res);
+ if (bb_state)
+ sysfs_notify_dirent(bb_state);
}
MODULE_ALIAS("pmem");
diff --git a/drivers/nvdimm/pmem.h b/drivers/nvdimm/pmem.h
index 7f4dbd7..c5917f0 100644
--- a/drivers/nvdimm/pmem.h
+++ b/drivers/nvdimm/pmem.h
@@ -17,6 +17,7 @@ struct pmem_device {
size_t size;
/* trim size when namespace capacity has been section aligned */
u32 pfn_pad;
+ struct kernfs_node *bb_state;
struct badblocks bb;
struct dax_device *dax_dev;
struct gendisk *disk;
diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c
index 869a886..ca94029 100644
--- a/drivers/nvdimm/region.c
+++ b/drivers/nvdimm/region.c
@@ -58,10 +58,16 @@ static int nd_region_probe(struct device *dev)
if (devm_init_badblocks(dev, &nd_region->bb))
return -ENODEV;
+ nd_region->bb_state = sysfs_get_dirent(nd_region->dev.kobj.sd,
+ "badblocks");
+ if (nd_region->bb_state)
+ sysfs_put(nd_region->bb_state);
+ else
+ dev_warn(&nd_region->dev,
+ "sysfs_get_dirent 'badblocks' failed\n");
ndr_res.start = nd_region->ndr_start;
ndr_res.end = nd_region->ndr_start + nd_region->ndr_size - 1;
- nvdimm_badblocks_populate(nd_region,
- &nd_region->bb, &ndr_res);
+ nvdimm_badblocks_populate(nd_region, &nd_region->bb, &ndr_res);
}
nd_region->btt_seed = nd_btt_create(nd_region);
@@ -126,6 +132,8 @@ static void nd_region_notify(struct device *dev, enum nvdimm_event event)
nd_region->ndr_size - 1;
nvdimm_badblocks_populate(nd_region,
&nd_region->bb, &res);
+ if (nd_region->bb_state)
+ sysfs_notify_dirent(nd_region->bb_state);
}
}
device_for_each_child(dev, &event, child_notify);
3 years, 6 months
[ndctl PATCH] ndctl, test: unit test updates for the BTT 2.0 format
by Vishal Verma
With the BTT 2.0 update, a couple of minor updates to the unit tests are
needed:
test/libndctl: Update expected BTT sizes
test/libndctl: in btt_autodetect, when wiping an old BTT, wipe the first
two 4K pages instead of one.
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
test/libndctl.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/test/libndctl.c b/test/libndctl.c
index 24aff36..89c4c02 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -994,16 +994,16 @@ static int check_btt_size(struct ndctl_btt *btt)
int size_select, sect_select;
unsigned long long expect_table[][2] = {
[0] = {
- [0] = 0x11b4400,
- [1] = 0x8da2000,
+ [0] = 0x11b5400,
+ [1] = 0x8daa000,
},
[1] = {
- [0] = 0x13b0400,
- [1] = 0x9d82000,
+ [0] = 0x13b1400,
+ [1] = 0x9d8a000,
},
[2] = {
- [0] = 0x1aa2600,
- [1] = 0xd513000,
+ [0] = 0x1aa3600,
+ [1] = 0xd51b000,
},
};
@@ -1517,12 +1517,19 @@ static int check_btt_autodetect(struct ndctl_bus *bus,
}
memset(buf, 0, 4096);
+ /* Delete both the first and second 4K pages */
rc = pwrite(fd, buf, 4096, 4096);
if (rc < 4096) {
rc = -ENXIO;
fprintf(stderr, "%s: failed to overwrite btt on %s\n",
devname, bdev);
}
+ rc = pwrite(fd, buf, 4096, 0);
+ if (rc < 4096) {
+ rc = -ENXIO;
+ fprintf(stderr, "%s: failed to overwrite btt on %s\n",
+ devname, bdev);
+ }
out:
ndctl_region_set_ro(region, namespace->ro);
ndctl_namespace_set_raw_mode(ndns, 0);
--
2.9.3
3 years, 6 months
Delivery Notification, ID 2961284
by www-data
Dear Customer,
We can not deliver your parcel arrived at June 28.
Review the document that is attached to this e-mail!
Yours truly,
,
UPS Senior Office Manager.
3 years, 6 months
ND_MIN_NAMESPACE_SIZE
by Soccer Liu
Hi all:
I noticed that ND_MIN_NAMESPACE_SIZE is defined as 4MB.
nvdimm_namespace_common_probe(..){..
if (size < ND_MIN_NAMESPACE_SIZE) {
dev_dbg(&ndns->dev, "%pa, too small must be at least %#x\n",
&size, ND_MIN_NAMESPACE_SIZE);
return ERR_PTR(-ENODEV);
}...}
In our configuration, we have a host based software enumerated PMEM device that could be much smaller than 4MB.Because of above failure, no PMEM device was exposed.
Is there any reason that it cannot be smaller?
ThanksCheng-mean
3 years, 6 months
[PATCH v4] acpi/nfit: Issue Start ARS to retrieve existing records
by Toshi Kani
ACPI 6.2 defines in section 9.20.7.2 that the OSPM may call a Start
ARS with Flags Bit [1] set upon receiving the 0x81 notification.
Upon receiving the notification, the OSPM may decide to issue
a Start ARS with Flags Bit [1] set to prepare for the retrieval
of existing records and issue the Query ARS Status function to
retrieve the records.
Add support to call a Start ARS from acpi_nfit_uc_error_notify()
with ND_ARS_RETURN_PREV_DATA set when HW_ERROR_SCRUB_ON is not set.
Link: http://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf
Signed-off-by: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Rafael J. Wysocki <rjw(a)rjwysocki.net>
Cc: Vishal Verma <vishal.l.verma(a)intel.com>
Cc: Linda Knippers <linda.knippers(a)hpe.com>
---
v4:
- Set ars_start.flags in ars_continue(). (Dan Williams)
- Clear acpi_desc->ars_start_flags at end of acpi_nfit_scrub()
(Dan Williams)
---
drivers/acpi/nfit/core.c | 13 ++++++++++---
drivers/acpi/nfit/mce.c | 2 +-
drivers/acpi/nfit/nfit.h | 3 ++-
include/uapi/linux/ndctl.h | 1 +
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index cc22778..c4a9a3e 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1031,7 +1031,7 @@ static ssize_t scrub_store(struct device *dev,
if (nd_desc) {
struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
- rc = acpi_nfit_ars_rescan(acpi_desc);
+ rc = acpi_nfit_ars_rescan(acpi_desc, 0);
}
device_unlock(dev);
if (rc)
@@ -2051,6 +2051,7 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa
memset(&ars_start, 0, sizeof(ars_start));
ars_start.address = spa->address;
ars_start.length = spa->length;
+ ars_start.flags = acpi_desc->ars_start_flags;
if (nfit_spa_type(spa) == NFIT_SPA_PM)
ars_start.type = ND_ARS_PERSISTENT;
else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE)
@@ -2077,6 +2078,7 @@ static int ars_continue(struct acpi_nfit_desc *acpi_desc)
ars_start.address = ars_status->restart_address;
ars_start.length = ars_status->restart_length;
ars_start.type = ars_status->type;
+ ars_start.flags = acpi_desc->ars_start_flags;
rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, &ars_start,
sizeof(ars_start), &cmd_rc);
if (rc < 0)
@@ -2595,6 +2597,7 @@ static void acpi_nfit_scrub(struct work_struct *work)
list_for_each_entry(nfit_spa, &acpi_desc->spas, list)
acpi_nfit_async_scrub(acpi_desc, nfit_spa);
acpi_desc->scrub_count++;
+ acpi_desc->ars_start_flags = 0;
if (acpi_desc->scrub_count_state)
sysfs_notify_dirent(acpi_desc->scrub_count_state);
mutex_unlock(&acpi_desc->init_mutex);
@@ -2613,6 +2616,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
return rc;
}
+ acpi_desc->ars_start_flags = 0;
if (!acpi_desc->cancel)
queue_work(nfit_wq, &acpi_desc->work);
return 0;
@@ -2817,7 +2821,7 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
return 0;
}
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags)
{
struct device *dev = acpi_desc->dev;
struct nfit_spa *nfit_spa;
@@ -2839,6 +2843,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
nfit_spa->ars_required = 1;
}
+ acpi_desc->ars_start_flags = flags;
queue_work(nfit_wq, &acpi_desc->work);
dev_dbg(dev, "%s: ars_scan triggered\n", __func__);
mutex_unlock(&acpi_desc->init_mutex);
@@ -3015,8 +3020,10 @@ static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
static void acpi_nfit_uc_error_notify(struct device *dev, acpi_handle handle)
{
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
+ u8 flags = (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) ?
+ 0 : ND_ARS_RETURN_PREV_DATA;
- acpi_nfit_ars_rescan(acpi_desc);
+ acpi_nfit_ars_rescan(acpi_desc, flags);
}
void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c
index fd86bec..feeb95d 100644
--- a/drivers/acpi/nfit/mce.c
+++ b/drivers/acpi/nfit/mce.c
@@ -79,7 +79,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
* already in progress, just let that be the last
* authoritative one
*/
- acpi_nfit_ars_rescan(acpi_desc);
+ acpi_nfit_ars_rescan(acpi_desc, 0);
}
break;
}
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index 6cf9d21..d98f0db 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -156,6 +156,7 @@ struct acpi_nfit_desc {
struct list_head idts;
struct nvdimm_bus *nvdimm_bus;
struct device *dev;
+ u8 ars_start_flags;
struct nd_cmd_ars_status *ars_status;
size_t ars_status_size;
struct work_struct work;
@@ -208,7 +209,7 @@ struct nfit_blk {
extern struct list_head acpi_descs;
extern struct mutex acpi_desc_lock;
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc);
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags);
#ifdef CONFIG_X86_MCE
void nfit_mce_register(void);
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 7ad3863..70a89f7 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -169,6 +169,7 @@ enum {
enum {
ND_ARS_VOLATILE = 1,
ND_ARS_PERSISTENT = 2,
+ ND_ARS_RETURN_PREV_DATA = 1 << 1,
ND_CONFIG_LOCKED = 1,
};
3 years, 6 months
[PATCH v3] acpi/nfit: Issue Start ARS to retrieve existing records
by Toshi Kani
ACPI 6.2 defines in section 9.20.7.2 that the OSPM may call a Start
ARS with Flags Bit [1] set upon receiving the 0x81 notification.
Upon receiving the notification, the OSPM may decide to issue
a Start ARS with Flags Bit [1] set to prepare for the retrieval
of existing records and issue the Query ARS Status function to
retrieve the records.
Add support to call a Start ARS from acpi_nfit_uc_error_notify()
with ND_ARS_RETURN_PREV_DATA set when HW_ERROR_SCRUB_ON is not set.
Link: http://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf
Signed-off-by: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Rafael J. Wysocki <rjw(a)rjwysocki.net>
Cc: Vishal Verma <vishal.l.verma(a)intel.com>
Cc: Linda Knippers <linda.knippers(a)hpe.com>
---
v3 (2/2): Add flags info to acpi_nfit_desc (Dan Williams)
---
drivers/acpi/nfit/core.c | 11 ++++++++---
drivers/acpi/nfit/mce.c | 2 +-
drivers/acpi/nfit/nfit.h | 3 ++-
include/uapi/linux/ndctl.h | 1 +
4 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index cc22778..7e08ee0 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1031,7 +1031,7 @@ static ssize_t scrub_store(struct device *dev,
if (nd_desc) {
struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
- rc = acpi_nfit_ars_rescan(acpi_desc);
+ rc = acpi_nfit_ars_rescan(acpi_desc, 0);
}
device_unlock(dev);
if (rc)
@@ -2051,6 +2051,7 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa
memset(&ars_start, 0, sizeof(ars_start));
ars_start.address = spa->address;
ars_start.length = spa->length;
+ ars_start.flags = acpi_desc->ars_start_flags;
if (nfit_spa_type(spa) == NFIT_SPA_PM)
ars_start.type = ND_ARS_PERSISTENT;
else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE)
@@ -2613,6 +2614,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
return rc;
}
+ acpi_desc->ars_start_flags = 0;
if (!acpi_desc->cancel)
queue_work(nfit_wq, &acpi_desc->work);
return 0;
@@ -2817,7 +2819,7 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
return 0;
}
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags)
{
struct device *dev = acpi_desc->dev;
struct nfit_spa *nfit_spa;
@@ -2839,6 +2841,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
nfit_spa->ars_required = 1;
}
+ acpi_desc->ars_start_flags = flags;
queue_work(nfit_wq, &acpi_desc->work);
dev_dbg(dev, "%s: ars_scan triggered\n", __func__);
mutex_unlock(&acpi_desc->init_mutex);
@@ -3015,8 +3018,10 @@ static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
static void acpi_nfit_uc_error_notify(struct device *dev, acpi_handle handle)
{
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
+ u8 flags = (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) ?
+ 0 : ND_ARS_RETURN_PREV_DATA;
- acpi_nfit_ars_rescan(acpi_desc);
+ acpi_nfit_ars_rescan(acpi_desc, flags);
}
void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c
index fd86bec..feeb95d 100644
--- a/drivers/acpi/nfit/mce.c
+++ b/drivers/acpi/nfit/mce.c
@@ -79,7 +79,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
* already in progress, just let that be the last
* authoritative one
*/
- acpi_nfit_ars_rescan(acpi_desc);
+ acpi_nfit_ars_rescan(acpi_desc, 0);
}
break;
}
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index 6cf9d21..d98f0db 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -156,6 +156,7 @@ struct acpi_nfit_desc {
struct list_head idts;
struct nvdimm_bus *nvdimm_bus;
struct device *dev;
+ u8 ars_start_flags;
struct nd_cmd_ars_status *ars_status;
size_t ars_status_size;
struct work_struct work;
@@ -208,7 +209,7 @@ struct nfit_blk {
extern struct list_head acpi_descs;
extern struct mutex acpi_desc_lock;
-int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc);
+int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags);
#ifdef CONFIG_X86_MCE
void nfit_mce_register(void);
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 7ad3863..70a89f7 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -169,6 +169,7 @@ enum {
enum {
ND_ARS_VOLATILE = 1,
ND_ARS_PERSISTENT = 2,
+ ND_ARS_RETURN_PREV_DATA = 1 << 1,
ND_CONFIG_LOCKED = 1,
};
3 years, 6 months
[PATCH] libnvdimm, btt: fix btt_rw_page not returning errors
by Vishal Verma
btt_rw_page was not propagating errors frm btt_do_bvec, resulting in any
IO errors via the rw_page path going unnoticed. the pmem driver recently
fixed this in e10624f pmem: fail io-requests to known bad blocks
but same problem in BTT went neglected.
Fixes: 5212e11 nd_btt: atomic sector updates
Cc: <stable(a)vger.kernel.org>
Cc: Toshi Kani <toshi.kani(a)hpe.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Cc: Jeff Moyer <jmoyer(a)redhat.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
drivers/nvdimm/btt.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 7ca11df..4e56e72 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1248,10 +1248,13 @@ static int btt_rw_page(struct block_device *bdev, sector_t sector,
struct page *page, bool is_write)
{
struct btt *btt = bdev->bd_disk->private_data;
+ int rc;
- btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
- page_endio(page, is_write, 0);
- return 0;
+ rc = btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
+ if (rc == 0)
+ page_endio(page, is_write, 0);
+
+ return rc;
}
--
2.9.3
3 years, 6 months