diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-15 21:56:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-15 21:56:50 -0400 |
commit | 83f3ef3de625a5766de2382f9e077d4daafd5bac (patch) | |
tree | c2ba4781ce52084987a9ddb8cbe2f42f944e8fd2 /drivers | |
parent | 8649efb2f8750dcabff018a27784bab4ecb9f88f (diff) | |
parent | 67476656febd7ec5f1fe1aeec3c441fcf53b1e45 (diff) |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dax/Kconfig | 3 | ||||
-rw-r--r-- | drivers/dax/pmem/core.c | 6 | ||||
-rw-r--r-- | drivers/nvdimm/label.c | 29 | ||||
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 15 | ||||
-rw-r--r-- | drivers/nvdimm/nd.h | 4 |
5 files changed, 39 insertions, 18 deletions
diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig index 5ef624fe3934..a59f338f520f 100644 --- a/drivers/dax/Kconfig +++ b/drivers/dax/Kconfig | |||
@@ -23,7 +23,6 @@ config DEV_DAX | |||
23 | config DEV_DAX_PMEM | 23 | config DEV_DAX_PMEM |
24 | tristate "PMEM DAX: direct access to persistent memory" | 24 | tristate "PMEM DAX: direct access to persistent memory" |
25 | depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX | 25 | depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX |
26 | depends on m # until we can kill DEV_DAX_PMEM_COMPAT | ||
27 | default DEV_DAX | 26 | default DEV_DAX |
28 | help | 27 | help |
29 | Support raw access to persistent memory. Note that this | 28 | Support raw access to persistent memory. Note that this |
@@ -50,7 +49,7 @@ config DEV_DAX_KMEM | |||
50 | 49 | ||
51 | config DEV_DAX_PMEM_COMPAT | 50 | config DEV_DAX_PMEM_COMPAT |
52 | tristate "PMEM DAX: support the deprecated /sys/class/dax interface" | 51 | tristate "PMEM DAX: support the deprecated /sys/class/dax interface" |
53 | depends on DEV_DAX_PMEM | 52 | depends on m && DEV_DAX_PMEM=m |
54 | default DEV_DAX_PMEM | 53 | default DEV_DAX_PMEM |
55 | help | 54 | help |
56 | Older versions of the libdaxctl library expect to find all | 55 | Older versions of the libdaxctl library expect to find all |
diff --git a/drivers/dax/pmem/core.c b/drivers/dax/pmem/core.c index f71019ce0647..f9f51786d556 100644 --- a/drivers/dax/pmem/core.c +++ b/drivers/dax/pmem/core.c | |||
@@ -37,13 +37,13 @@ struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys) | |||
37 | devm_nsio_disable(dev, nsio); | 37 | devm_nsio_disable(dev, nsio); |
38 | 38 | ||
39 | /* reserve the metadata area, device-dax will reserve the data */ | 39 | /* reserve the metadata area, device-dax will reserve the data */ |
40 | pfn_sb = nd_pfn->pfn_sb; | 40 | pfn_sb = nd_pfn->pfn_sb; |
41 | offset = le64_to_cpu(pfn_sb->dataoff); | 41 | offset = le64_to_cpu(pfn_sb->dataoff); |
42 | if (!devm_request_mem_region(dev, nsio->res.start, offset, | 42 | if (!devm_request_mem_region(dev, nsio->res.start, offset, |
43 | dev_name(&ndns->dev))) { | 43 | dev_name(&ndns->dev))) { |
44 | dev_warn(dev, "could not reserve metadata\n"); | 44 | dev_warn(dev, "could not reserve metadata\n"); |
45 | return ERR_PTR(-EBUSY); | 45 | return ERR_PTR(-EBUSY); |
46 | } | 46 | } |
47 | 47 | ||
48 | rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", ®ion_id, &id); | 48 | rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", ®ion_id, &id); |
49 | if (rc != 2) | 49 | if (rc != 2) |
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index f3d753d3169c..2030805aa216 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c | |||
@@ -756,6 +756,17 @@ static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class, | |||
756 | return &guid_null; | 756 | return &guid_null; |
757 | } | 757 | } |
758 | 758 | ||
759 | static void reap_victim(struct nd_mapping *nd_mapping, | ||
760 | struct nd_label_ent *victim) | ||
761 | { | ||
762 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | ||
763 | u32 slot = to_slot(ndd, victim->label); | ||
764 | |||
765 | dev_dbg(ndd->dev, "free: %d\n", slot); | ||
766 | nd_label_free_slot(ndd, slot); | ||
767 | victim->label = NULL; | ||
768 | } | ||
769 | |||
759 | static int __pmem_label_update(struct nd_region *nd_region, | 770 | static int __pmem_label_update(struct nd_region *nd_region, |
760 | struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, | 771 | struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, |
761 | int pos, unsigned long flags) | 772 | int pos, unsigned long flags) |
@@ -763,9 +774,9 @@ static int __pmem_label_update(struct nd_region *nd_region, | |||
763 | struct nd_namespace_common *ndns = &nspm->nsio.common; | 774 | struct nd_namespace_common *ndns = &nspm->nsio.common; |
764 | struct nd_interleave_set *nd_set = nd_region->nd_set; | 775 | struct nd_interleave_set *nd_set = nd_region->nd_set; |
765 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | 776 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); |
766 | struct nd_label_ent *label_ent, *victim = NULL; | ||
767 | struct nd_namespace_label *nd_label; | 777 | struct nd_namespace_label *nd_label; |
768 | struct nd_namespace_index *nsindex; | 778 | struct nd_namespace_index *nsindex; |
779 | struct nd_label_ent *label_ent; | ||
769 | struct nd_label_id label_id; | 780 | struct nd_label_id label_id; |
770 | struct resource *res; | 781 | struct resource *res; |
771 | unsigned long *free; | 782 | unsigned long *free; |
@@ -834,18 +845,10 @@ static int __pmem_label_update(struct nd_region *nd_region, | |||
834 | list_for_each_entry(label_ent, &nd_mapping->labels, list) { | 845 | list_for_each_entry(label_ent, &nd_mapping->labels, list) { |
835 | if (!label_ent->label) | 846 | if (!label_ent->label) |
836 | continue; | 847 | continue; |
837 | if (memcmp(nspm->uuid, label_ent->label->uuid, | 848 | if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags) |
838 | NSLABEL_UUID_LEN) != 0) | 849 | || memcmp(nspm->uuid, label_ent->label->uuid, |
839 | continue; | 850 | NSLABEL_UUID_LEN) == 0) |
840 | victim = label_ent; | 851 | reap_victim(nd_mapping, label_ent); |
841 | list_move_tail(&victim->list, &nd_mapping->labels); | ||
842 | break; | ||
843 | } | ||
844 | if (victim) { | ||
845 | dev_dbg(ndd->dev, "free: %d\n", slot); | ||
846 | slot = to_slot(ndd, victim->label); | ||
847 | nd_label_free_slot(ndd, slot); | ||
848 | victim->label = NULL; | ||
849 | } | 852 | } |
850 | 853 | ||
851 | /* update index */ | 854 | /* update index */ |
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index f293556cbbf6..d0214644e334 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -1247,12 +1247,27 @@ static int namespace_update_uuid(struct nd_region *nd_region, | |||
1247 | for (i = 0; i < nd_region->ndr_mappings; i++) { | 1247 | for (i = 0; i < nd_region->ndr_mappings; i++) { |
1248 | struct nd_mapping *nd_mapping = &nd_region->mapping[i]; | 1248 | struct nd_mapping *nd_mapping = &nd_region->mapping[i]; |
1249 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | 1249 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); |
1250 | struct nd_label_ent *label_ent; | ||
1250 | struct resource *res; | 1251 | struct resource *res; |
1251 | 1252 | ||
1252 | for_each_dpa_resource(ndd, res) | 1253 | for_each_dpa_resource(ndd, res) |
1253 | if (strcmp(res->name, old_label_id.id) == 0) | 1254 | if (strcmp(res->name, old_label_id.id) == 0) |
1254 | sprintf((void *) res->name, "%s", | 1255 | sprintf((void *) res->name, "%s", |
1255 | new_label_id.id); | 1256 | new_label_id.id); |
1257 | |||
1258 | mutex_lock(&nd_mapping->lock); | ||
1259 | list_for_each_entry(label_ent, &nd_mapping->labels, list) { | ||
1260 | struct nd_namespace_label *nd_label = label_ent->label; | ||
1261 | struct nd_label_id label_id; | ||
1262 | |||
1263 | if (!nd_label) | ||
1264 | continue; | ||
1265 | nd_label_gen_id(&label_id, nd_label->uuid, | ||
1266 | __le32_to_cpu(nd_label->flags)); | ||
1267 | if (strcmp(old_label_id.id, label_id.id) == 0) | ||
1268 | set_bit(ND_LABEL_REAP, &label_ent->flags); | ||
1269 | } | ||
1270 | mutex_unlock(&nd_mapping->lock); | ||
1256 | } | 1271 | } |
1257 | kfree(*old_uuid); | 1272 | kfree(*old_uuid); |
1258 | out: | 1273 | out: |
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index a5ac3b240293..191d62af0e51 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h | |||
@@ -113,8 +113,12 @@ struct nd_percpu_lane { | |||
113 | spinlock_t lock; | 113 | spinlock_t lock; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | enum nd_label_flags { | ||
117 | ND_LABEL_REAP, | ||
118 | }; | ||
116 | struct nd_label_ent { | 119 | struct nd_label_ent { |
117 | struct list_head list; | 120 | struct list_head list; |
121 | unsigned long flags; | ||
118 | struct nd_namespace_label *label; | 122 | struct nd_namespace_label *label; |
119 | }; | 123 | }; |
120 | 124 | ||