Merge tag 'libnvdimm-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams:
"libnvdimm updates for the latest ACPI and UEFI specifications. This
pull request also includes new 'struct dax_operations' enabling to
undo the abuse of copy_user_nocache() for copy operations to pmem.
The dax work originally missed 4.12 to address concerns raised by Al.
Summary:
- Introduce the _flushcache() family of memory copy helpers and use
them for persistent memory write operations on x86. The
_flushcache() semantic indicates that the cache is either bypassed
for the copy operation (movnt) or any lines dirtied by the copy
operation are written back (clwb, clflushopt, or clflush).
- Extend dax_operations with ->copy_from_iter() and ->flush()
operations. These operations and other infrastructure updates allow
all persistent memory specific dax functionality to be pushed into
libnvdimm and the pmem driver directly. It also allows dax-specific
sysfs attributes to be linked to a host device, for example:
/sys/block/pmem0/dax/write_cache
- Add support for the new NVDIMM platform/firmware mechanisms
introduced in ACPI 6.2 and UEFI 2.7. This support includes the v1.2
namespace label format, extensions to the address-range-scrub
command set, new error injection commands, and a new BTT
(block-translation-table) layout. These updates support inter-OS
and pre-OS compatibility.
- Fix a longstanding memory corruption bug in nfit_test.
- Make the pmem and nvdimm-region 'badblocks' sysfs files poll(2)
capable.
- Miscellaneous fixes and small updates across libnvdimm and the nfit
driver.
Acknowledgements that came after the branch was pushed: commit
6aa734a2f3
("libnvdimm, region, pmem: fix 'badblocks'
sysfs_get_dirent() reference lifetime") was reviewed by Toshi Kani
<toshi.kani@hpe.com>"
* tag 'libnvdimm-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (42 commits)
libnvdimm, namespace: record 'lbasize' for pmem namespaces
acpi/nfit: Issue Start ARS to retrieve existing records
libnvdimm: New ACPI 6.2 DSM functions
acpi, nfit: Show bus_dsm_mask in sysfs
libnvdimm, acpi, nfit: Add bus level dsm mask for pass thru.
acpi, nfit: Enable DSM pass thru for root functions.
libnvdimm: passthru functions clear to send
libnvdimm, btt: convert some info messages to warn/err
libnvdimm, region, pmem: fix 'badblocks' sysfs_get_dirent() reference lifetime
libnvdimm: fix the clear-error check in nsio_rw_bytes
libnvdimm, btt: fix btt_rw_page not returning errors
acpi, nfit: quiet invalid block-aperture-region warnings
libnvdimm, btt: BTT updates for UEFI 2.7 format
acpi, nfit: constify *_attribute_group
libnvdimm, pmem: disable dax flushing when pmem is fronting a volatile region
libnvdimm, pmem, dax: export a cache control attribute
dax: convert to bitmask for flags
dax: remove default copy_from_iter fallback
libnvdimm, nfit: enable support for volatile ranges
libnvdimm, pmem: fix persistence warning
...
This commit is contained in:
@@ -37,8 +37,8 @@ static int arena_read_bytes(struct arena_info *arena, resource_size_t offset,
|
||||
struct nd_btt *nd_btt = arena->nd_btt;
|
||||
struct nd_namespace_common *ndns = nd_btt->ndns;
|
||||
|
||||
/* arena offsets are 4K from the base of the device */
|
||||
offset += SZ_4K;
|
||||
/* arena offsets may be shifted from the base of the device */
|
||||
offset += arena->nd_btt->initial_offset;
|
||||
return nvdimm_read_bytes(ndns, offset, buf, n, flags);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ static int arena_write_bytes(struct arena_info *arena, resource_size_t offset,
|
||||
struct nd_btt *nd_btt = arena->nd_btt;
|
||||
struct nd_namespace_common *ndns = nd_btt->ndns;
|
||||
|
||||
/* arena offsets are 4K from the base of the device */
|
||||
offset += SZ_4K;
|
||||
/* arena offsets may be shifted from the base of the device */
|
||||
offset += arena->nd_btt->initial_offset;
|
||||
return nvdimm_write_bytes(ndns, offset, buf, n, flags);
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ static int btt_log_read(struct arena_info *arena, u32 lane,
|
||||
|
||||
old_ent = btt_log_get_old(log);
|
||||
if (old_ent < 0 || old_ent > 1) {
|
||||
dev_info(to_dev(arena),
|
||||
dev_err(to_dev(arena),
|
||||
"log corruption (%d): lane %d seq [%d, %d]\n",
|
||||
old_ent, lane, log[0].seq, log[1].seq);
|
||||
/* TODO set error state? */
|
||||
@@ -576,8 +576,8 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
|
||||
arena->internal_lbasize = roundup(arena->external_lbasize,
|
||||
INT_LBASIZE_ALIGNMENT);
|
||||
arena->nfree = BTT_DEFAULT_NFREE;
|
||||
arena->version_major = 1;
|
||||
arena->version_minor = 1;
|
||||
arena->version_major = btt->nd_btt->version_major;
|
||||
arena->version_minor = btt->nd_btt->version_minor;
|
||||
|
||||
if (available % BTT_PG_SIZE)
|
||||
available -= (available % BTT_PG_SIZE);
|
||||
@@ -684,7 +684,7 @@ static int discover_arenas(struct btt *btt)
|
||||
dev_info(to_dev(arena), "No existing arenas\n");
|
||||
goto out;
|
||||
} else {
|
||||
dev_info(to_dev(arena),
|
||||
dev_err(to_dev(arena),
|
||||
"Found corrupted metadata!\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
@@ -1227,7 +1227,7 @@ static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio)
|
||||
err = btt_do_bvec(btt, bip, bvec.bv_page, len, bvec.bv_offset,
|
||||
op_is_write(bio_op(bio)), iter.bi_sector);
|
||||
if (err) {
|
||||
dev_info(&btt->nd_btt->dev,
|
||||
dev_err(&btt->nd_btt->dev,
|
||||
"io error in %s sector %lld, len %d,\n",
|
||||
(op_is_write(bio_op(bio))) ? "WRITE" :
|
||||
"READ",
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1369,7 +1372,7 @@ static struct btt *btt_init(struct nd_btt *nd_btt, unsigned long long rawsize,
|
||||
}
|
||||
|
||||
if (btt->init_state != INIT_READY && nd_region->ro) {
|
||||
dev_info(dev, "%s is read-only, unable to init btt metadata\n",
|
||||
dev_warn(dev, "%s is read-only, unable to init btt metadata\n",
|
||||
dev_name(&nd_region->dev));
|
||||
return NULL;
|
||||
} else if (btt->init_state != INIT_READY) {
|
||||
@@ -1424,6 +1427,7 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
|
||||
{
|
||||
struct nd_btt *nd_btt = to_nd_btt(ndns->claim);
|
||||
struct nd_region *nd_region;
|
||||
struct btt_sb *btt_sb;
|
||||
struct btt *btt;
|
||||
size_t rawsize;
|
||||
|
||||
@@ -1432,10 +1436,21 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
|
||||
btt_sb = devm_kzalloc(&nd_btt->dev, sizeof(*btt_sb), GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* If this returns < 0, that is ok as it just means there wasn't
|
||||
* an existing BTT, and we're creating a new one. We still need to
|
||||
* call this as we need the version dependent fields in nd_btt to be
|
||||
* set correctly based on the holder class
|
||||
*/
|
||||
nd_btt_version(nd_btt, ndns, btt_sb);
|
||||
|
||||
rawsize = nvdimm_namespace_capacity(ndns) - nd_btt->initial_offset;
|
||||
if (rawsize < ARENA_MIN_SIZE) {
|
||||
dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
|
||||
dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
|
||||
dev_name(&ndns->dev),
|
||||
ARENA_MIN_SIZE + nd_btt->initial_offset);
|
||||
return -ENXIO;
|
||||
}
|
||||
nd_region = to_nd_region(nd_btt->dev.parent);
|
||||
|
Reference in New Issue
Block a user