libnvdimm fixes 5.2-rc1

* Fix a long standing namespace label corruption scenario when
   re-provisioning capacity for a namespace.
 
 * Restore the ability of the dax_pmem module to be built-in.
 
 * Harden the build for the 'nfit_test' unit test modules so that the
   userspace test harness can ensure all required test modules are
   available.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJc3KYfAAoJEB7SkWpmfYgCGtUP/1eZkLk6X2xYYZw6mMKbaVUm
 F4f7uOhpFFNonor0EhZVgTXqLEjFE9ux3+kZi0EZkvJhOSWAftICo1mzqLBnDxSW
 QiNMOcFeM16Df3a6kwMbrcsjVRMyI63E4qH2puaPcW4sSRVhrMzKcklx+iWtubtk
 q/bXx4B4n78E509FMagF3Irt6iWh235YqAXapbh4jSLGs8BJ0LRE8WVnMridCYcD
 MV4QEYHWwHh0SlQ7HM/jdGtCwJyaFiHK+G6CDqUqTR7NKFpkpAwKDT2UULkdpzSo
 1YUJQfUcdpwp7GUaTvGWL8BDyVklh+pLQtp+lepQfpPbSLPMC6qRC+hZXAuxlX7h
 Dj94P9DYZWJk9b0Z4NaqJCjADi/iKIdCHa9dIOPb4XmbXgTLnS15HsG0asBeoTuF
 UfDNdOLo8Tz+3dwNvmJ9Avb8ShqYLkwiOfkOeBDGu/+OWTiUrbghbAhhM4iOd8ey
 cFYc5MWD0HA4F0f4jw0o0fKQ3qGfhqEabdN1Z54nZ53y+t9MFx2fTAXAq26f+oly
 HM3ehus7EiNUS9gjMC55AAPTt5S/S4nu+YiMQUwlRfj2ErkYvrRsQAl7x4QjEWdu
 RSfrGCMb37OaMnzFGw49GGJsZqPUeT1O2anxVDVTM+RvMCi6fJY75XRJVMs2A6CG
 WNVEIGIQQbHwEyidOAPC
 =QM33
 -----END PGP SIGNATURE-----

Merge tag 'libnvdimm-fixes-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm updates from Dan Williams:
 "Just a small collection of fixes this time around.

  The new virtio-pmem driver is nearly ready, but some last minute
  device-mapper acks and virtio questions made it prudent to await v5.3.

  Other major topics that were brewing on the linux-nvdimm mailing list
  like sub-section hotplug, and other devm_memremap_pages() reworks will
  go upstream through Andrew's tree.

  Summary:

   - Fix a long standing namespace label corruption scenario when
     re-provisioning capacity for a namespace.

   - Restore the ability of the dax_pmem module to be built-in.

   - Harden the build for the 'nfit_test' unit test modules so that the
     userspace test harness can ensure all required test modules are
     available"

* tag 'libnvdimm-fixes-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  drivers/dax: Allow to include DEV_DAX_PMEM as builtin
  libnvdimm/namespace: Fix label tracking error
  tools/testing/nvdimm: add watermarks for dax_pmem* modules
  dax/pmem: Fix whitespace in dax_pmem
This commit is contained in:
Linus Torvalds 2019-05-15 18:56:50 -07:00
commit 83f3ef3de6
11 changed files with 72 additions and 18 deletions

View File

@ -23,7 +23,6 @@ config DEV_DAX
config DEV_DAX_PMEM config DEV_DAX_PMEM
tristate "PMEM DAX: direct access to persistent memory" tristate "PMEM DAX: direct access to persistent memory"
depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX
depends on m # until we can kill DEV_DAX_PMEM_COMPAT
default DEV_DAX default DEV_DAX
help help
Support raw access to persistent memory. Note that this Support raw access to persistent memory. Note that this
@ -50,7 +49,7 @@ config DEV_DAX_KMEM
config DEV_DAX_PMEM_COMPAT config DEV_DAX_PMEM_COMPAT
tristate "PMEM DAX: support the deprecated /sys/class/dax interface" tristate "PMEM DAX: support the deprecated /sys/class/dax interface"
depends on DEV_DAX_PMEM depends on m && DEV_DAX_PMEM=m
default DEV_DAX_PMEM default DEV_DAX_PMEM
help help
Older versions of the libdaxctl library expect to find all Older versions of the libdaxctl library expect to find all

View File

@ -37,13 +37,13 @@ struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys)
devm_nsio_disable(dev, nsio); devm_nsio_disable(dev, nsio);
/* reserve the metadata area, device-dax will reserve the data */ /* reserve the metadata area, device-dax will reserve the data */
pfn_sb = nd_pfn->pfn_sb; pfn_sb = nd_pfn->pfn_sb;
offset = le64_to_cpu(pfn_sb->dataoff); offset = le64_to_cpu(pfn_sb->dataoff);
if (!devm_request_mem_region(dev, nsio->res.start, offset, if (!devm_request_mem_region(dev, nsio->res.start, offset,
dev_name(&ndns->dev))) { dev_name(&ndns->dev))) {
dev_warn(dev, "could not reserve metadata\n"); dev_warn(dev, "could not reserve metadata\n");
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id); rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
if (rc != 2) if (rc != 2)

View File

@ -756,6 +756,17 @@ static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
return &guid_null; return &guid_null;
} }
static void reap_victim(struct nd_mapping *nd_mapping,
struct nd_label_ent *victim)
{
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
u32 slot = to_slot(ndd, victim->label);
dev_dbg(ndd->dev, "free: %d\n", slot);
nd_label_free_slot(ndd, slot);
victim->label = NULL;
}
static int __pmem_label_update(struct nd_region *nd_region, static int __pmem_label_update(struct nd_region *nd_region,
struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm,
int pos, unsigned long flags) int pos, unsigned long flags)
@ -763,9 +774,9 @@ static int __pmem_label_update(struct nd_region *nd_region,
struct nd_namespace_common *ndns = &nspm->nsio.common; struct nd_namespace_common *ndns = &nspm->nsio.common;
struct nd_interleave_set *nd_set = nd_region->nd_set; struct nd_interleave_set *nd_set = nd_region->nd_set;
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
struct nd_label_ent *label_ent, *victim = NULL;
struct nd_namespace_label *nd_label; struct nd_namespace_label *nd_label;
struct nd_namespace_index *nsindex; struct nd_namespace_index *nsindex;
struct nd_label_ent *label_ent;
struct nd_label_id label_id; struct nd_label_id label_id;
struct resource *res; struct resource *res;
unsigned long *free; unsigned long *free;
@ -834,18 +845,10 @@ static int __pmem_label_update(struct nd_region *nd_region,
list_for_each_entry(label_ent, &nd_mapping->labels, list) { list_for_each_entry(label_ent, &nd_mapping->labels, list) {
if (!label_ent->label) if (!label_ent->label)
continue; continue;
if (memcmp(nspm->uuid, label_ent->label->uuid, if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)
NSLABEL_UUID_LEN) != 0) || memcmp(nspm->uuid, label_ent->label->uuid,
continue; NSLABEL_UUID_LEN) == 0)
victim = label_ent; reap_victim(nd_mapping, label_ent);
list_move_tail(&victim->list, &nd_mapping->labels);
break;
}
if (victim) {
dev_dbg(ndd->dev, "free: %d\n", slot);
slot = to_slot(ndd, victim->label);
nd_label_free_slot(ndd, slot);
victim->label = NULL;
} }
/* update index */ /* update index */

View File

@ -1247,12 +1247,27 @@ static int namespace_update_uuid(struct nd_region *nd_region,
for (i = 0; i < nd_region->ndr_mappings; i++) { for (i = 0; i < nd_region->ndr_mappings; i++) {
struct nd_mapping *nd_mapping = &nd_region->mapping[i]; struct nd_mapping *nd_mapping = &nd_region->mapping[i];
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
struct nd_label_ent *label_ent;
struct resource *res; struct resource *res;
for_each_dpa_resource(ndd, res) for_each_dpa_resource(ndd, res)
if (strcmp(res->name, old_label_id.id) == 0) if (strcmp(res->name, old_label_id.id) == 0)
sprintf((void *) res->name, "%s", sprintf((void *) res->name, "%s",
new_label_id.id); new_label_id.id);
mutex_lock(&nd_mapping->lock);
list_for_each_entry(label_ent, &nd_mapping->labels, list) {
struct nd_namespace_label *nd_label = label_ent->label;
struct nd_label_id label_id;
if (!nd_label)
continue;
nd_label_gen_id(&label_id, nd_label->uuid,
__le32_to_cpu(nd_label->flags));
if (strcmp(old_label_id.id, label_id.id) == 0)
set_bit(ND_LABEL_REAP, &label_ent->flags);
}
mutex_unlock(&nd_mapping->lock);
} }
kfree(*old_uuid); kfree(*old_uuid);
out: out:

View File

@ -113,8 +113,12 @@ struct nd_percpu_lane {
spinlock_t lock; spinlock_t lock;
}; };
enum nd_label_flags {
ND_LABEL_REAP,
};
struct nd_label_ent { struct nd_label_ent {
struct list_head list; struct list_head list;
unsigned long flags;
struct nd_namespace_label *label; struct nd_namespace_label *label;
}; };

View File

@ -68,8 +68,11 @@ device_dax-y += device_dax_test.o
device_dax-y += config_check.o device_dax-y += config_check.o
dax_pmem-y := $(DAX_SRC)/pmem/pmem.o dax_pmem-y := $(DAX_SRC)/pmem/pmem.o
dax_pmem-y += dax_pmem_test.o
dax_pmem_core-y := $(DAX_SRC)/pmem/core.o dax_pmem_core-y := $(DAX_SRC)/pmem/core.o
dax_pmem_core-y += dax_pmem_core_test.o
dax_pmem_compat-y := $(DAX_SRC)/pmem/compat.o dax_pmem_compat-y := $(DAX_SRC)/pmem/compat.o
dax_pmem_compat-y += dax_pmem_compat_test.o
dax_pmem-y += config_check.o dax_pmem-y += config_check.o
libnvdimm-y := $(NVDIMM_SRC)/core.o libnvdimm-y := $(NVDIMM_SRC)/core.o

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright(c) 2019 Intel Corporation. All rights reserved.
#include <linux/module.h>
#include <linux/printk.h>
#include "watermark.h"
nfit_test_watermark(dax_pmem_compat);

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright(c) 2019 Intel Corporation. All rights reserved.
#include <linux/module.h>
#include <linux/printk.h>
#include "watermark.h"
nfit_test_watermark(dax_pmem_core);

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright(c) 2019 Intel Corporation. All rights reserved.
#include <linux/module.h>
#include <linux/printk.h>
#include "watermark.h"
nfit_test_watermark(dax_pmem);

View File

@ -3171,6 +3171,9 @@ static __init int nfit_test_init(void)
acpi_nfit_test(); acpi_nfit_test();
device_dax_test(); device_dax_test();
mcsafe_test(); mcsafe_test();
dax_pmem_test();
dax_pmem_core_test();
dax_pmem_compat_test();
nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm); nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);

View File

@ -6,6 +6,9 @@ int pmem_test(void);
int libnvdimm_test(void); int libnvdimm_test(void);
int acpi_nfit_test(void); int acpi_nfit_test(void);
int device_dax_test(void); int device_dax_test(void);
int dax_pmem_test(void);
int dax_pmem_core_test(void);
int dax_pmem_compat_test(void);
/* /*
* dummy routine for nfit_test to validate it is linking to the properly * dummy routine for nfit_test to validate it is linking to the properly