History

Merge branch 'for-4.9/libnvdimm' into libnvdimm-for-next

Dan Williams committed 10 years ago

Commit 178d6f42 parents db58028 98a29c320 files · +1559 −517Browse files

Unified · Split

20 files
  1. drivers/acpi/nfit/core.c +180 −30
  2. drivers/acpi/nfit/mce.c +19 −5
  3. drivers/acpi/nfit/nfit.h +17 −0
  4. drivers/nvdimm/bus.c +2 −0
  5. drivers/nvdimm/core.c +69 −4
  6. drivers/nvdimm/dimm.c +11 −0
  7. drivers/nvdimm/dimm_devs.c +175 −51
  8. drivers/nvdimm/label.c +120 −72
  9. drivers/nvdimm/namespace_devs.c +547 −245
  10. drivers/nvdimm/nd-core.h +21 −3
  11. drivers/nvdimm/nd.h +26 −3
  12. drivers/nvdimm/pmem.c +23 −5
  13. drivers/nvdimm/region_devs.c +41 −17
  14. include/linux/libnvdimm.h +10 −18
  15. include/linux/nd.h +5 −3
  16. include/uapi/linux/ndctl.h +17 −13
  17. tools/testing/nvdimm/Kbuild +1 −0
  18. tools/testing/nvdimm/test/iomap.c +121 −30
  19. tools/testing/nvdimm/test/nfit.c +143 −17
  20. tools/testing/nvdimm/test/nfit_test.h +11 −1
drivers/acpi/nfit/core.c+180−30
@@ -886,6 +886,58 @@ static ssize_t revision_show(struct device *dev, · 885 unmodified lines
886886 }
887887 static DEVICE_ATTR_RO(revision);
888888
889+static ssize_t hw_error_scrub_show(struct device *dev,
890+ struct device_attribute *attr, char *buf)
891+{
892+ struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
893+ struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus);
894+ struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
895+
896+ return sprintf(buf, "%d\n", acpi_desc->scrub_mode);
897+}
898+
899+/*
900+ * The 'hw_error_scrub' attribute can have the following values written to it:
901+ * '0': Switch to the default mode where an exception will only insert
902+ * the address of the memory error into the poison and badblocks lists.
903+ * '1': Enable a full scrub to happen if an exception for a memory error is
904+ * received.
905+ */
906+static ssize_t hw_error_scrub_store(struct device *dev,
907+ struct device_attribute *attr, const char *buf, size_t size)
908+{
909+ struct nvdimm_bus_descriptor *nd_desc;
910+ ssize_t rc;
911+ long val;
912+
913+ rc = kstrtol(buf, 0, &val);
914+ if (rc)
915+ return rc;
916+
917+ device_lock(dev);
918+ nd_desc = dev_get_drvdata(dev);
919+ if (nd_desc) {
920+ struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
921+
922+ switch (val) {
923+ case HW_ERROR_SCRUB_ON:
924+ acpi_desc->scrub_mode = HW_ERROR_SCRUB_ON;
925+ break;
926+ case HW_ERROR_SCRUB_OFF:
927+ acpi_desc->scrub_mode = HW_ERROR_SCRUB_OFF;
928+ break;
929+ default:
930+ rc = -EINVAL;
931+ break;
932+ }
933+ }
934+ device_unlock(dev);
935+ if (rc)
936+ return rc;
937+ return size;
938+}
939+static DEVICE_ATTR_RW(hw_error_scrub);
940+
889941 /*
890942 * This shows the number of full Address Range Scrubs that have been
891943 * completed since driver load time. Userspace can wait on this using
@@ -958,6 +1010,7 @@ static umode_t nfit_visible(struct kobject *kobj, struct attribute *a, int n) · 66 unmodified lines
9581010 static struct attribute *acpi_nfit_attributes[] = {
9591011 &dev_attr_revision.attr,
9601012 &dev_attr_scrub.attr,
1013+ &dev_attr_hw_error_scrub.attr,
9611014 NULL,
9621015 };
9631016
@@ -1256,6 +1309,44 @@ static struct nvdimm *acpi_nfit_dimm_by_handle(struct acpi_nfit_desc *acpi_desc, · 292 unmodified lines
12561309 return NULL;
12571310 }
12581311
1312+void __acpi_nvdimm_notify(struct device *dev, u32 event)
1313+{
1314+ struct nfit_mem *nfit_mem;
1315+ struct acpi_nfit_desc *acpi_desc;
1316+
1317+ dev_dbg(dev->parent, "%s: %s: event: %d\n", dev_name(dev), __func__,
1318+ event);
1319+
1320+ if (event != NFIT_NOTIFY_DIMM_HEALTH) {
1321+ dev_dbg(dev->parent, "%s: unknown event: %d\n", dev_name(dev),
1322+ event);
1323+ return;
1324+ }
1325+
1326+ acpi_desc = dev_get_drvdata(dev->parent);
1327+ if (!acpi_desc)
1328+ return;
1329+
1330+ /*
1331+ * If we successfully retrieved acpi_desc, then we know nfit_mem data
1332+ * is still valid.
1333+ */
1334+ nfit_mem = dev_get_drvdata(dev);
1335+ if (nfit_mem && nfit_mem->flags_attr)
1336+ sysfs_notify_dirent(nfit_mem->flags_attr);
1337+}
1338+EXPORT_SYMBOL_GPL(__acpi_nvdimm_notify);
1339+
1340+static void acpi_nvdimm_notify(acpi_handle handle, u32 event, void *data)
1341+{
1342+ struct acpi_device *adev = data;
1343+ struct device *dev = &adev->dev;
1344+
1345+ device_lock(dev->parent);
1346+ __acpi_nvdimm_notify(dev, event);
1347+ device_unlock(dev->parent);
1348+}
1349+
12591350 static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
12601351 struct nfit_mem *nfit_mem, u32 device_handle)
12611352 {
@@ -1280,6 +1371,13 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, · 18 unmodified lines
12801371 return force_enable_dimms ? 0 : -ENODEV;
12811372 }
12821373
1374+ if (ACPI_FAILURE(acpi_install_notify_handler(adev_dimm->handle,
1375+ ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify, adev_dimm))) {
1376+ dev_err(dev, "%s: notification registration failed\n",
1377+ dev_name(&adev_dimm->dev));
1378+ return -ENXIO;
1379+ }
1380+
12831381 /*
12841382 * Until standardization materializes we need to consider 4
12851383 * different command sets. Note, that checking for function0 (bit0)
@@ -1318,18 +1416,41 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, · 32 unmodified lines
13181416 return 0;
13191417 }
13201418
1419+static void shutdown_dimm_notify(void *data)
1420+{
1421+ struct acpi_nfit_desc *acpi_desc = data;
1422+ struct nfit_mem *nfit_mem;
1423+
1424+ mutex_lock(&acpi_desc->init_mutex);
1425+ /*
1426+ * Clear out the nfit_mem->flags_attr and shut down dimm event
1427+ * notifications.
1428+ */
1429+ list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1430+ struct acpi_device *adev_dimm = nfit_mem->adev;
1431+
1432+ if (nfit_mem->flags_attr) {
1433+ sysfs_put(nfit_mem->flags_attr);
1434+ nfit_mem->flags_attr = NULL;
1435+ }
1436+ if (adev_dimm)
1437+ acpi_remove_notify_handler(adev_dimm->handle,
1438+ ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify);
1439+ }
1440+ mutex_unlock(&acpi_desc->init_mutex);
1441+}
1442+
13211443 static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
13221444 {
13231445 struct nfit_mem *nfit_mem;
1324− int dimm_count = 0;
1446+ int dimm_count = 0, rc;
1447+ struct nvdimm *nvdimm;
13251448
13261449 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
13271450 struct acpi_nfit_flush_address *flush;
13281451 unsigned long flags = 0, cmd_mask;
1329− struct nvdimm *nvdimm;
13301452 u32 device_handle;
13311453 u16 mem_flags;
1332− int rc;
13331454
13341455 device_handle = __to_nfit_memdev(nfit_mem)->device_handle;
13351456 nvdimm = acpi_nfit_dimm_by_handle(acpi_desc, device_handle);
@@ -1382,7 +1503,30 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) · 46 unmodified lines
13821503
13831504 }
13841505
1385− return nvdimm_bus_check_dimm_count(acpi_desc->nvdimm_bus, dimm_count);
1506+ rc = nvdimm_bus_check_dimm_count(acpi_desc->nvdimm_bus, dimm_count);
1507+ if (rc)
1508+ return rc;
1509+
1510+ /*
1511+ * Now that dimms are successfully registered, and async registration
1512+ * is flushed, attempt to enable event notification.
1513+ */
1514+ list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1515+ struct kernfs_node *nfit_kernfs;
1516+
1517+ nvdimm = nfit_mem->nvdimm;
1518+ nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
1519+ if (nfit_kernfs)
1520+ nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
1521+ "flags");
1522+ sysfs_put(nfit_kernfs);
1523+ if (!nfit_mem->flags_attr)
1524+ dev_warn(acpi_desc->dev, "%s: notifications disabled\n",
1525+ nvdimm_name(nvdimm));
1526+ }
1527+
1528+ return devm_add_action_or_reset(acpi_desc->dev, shutdown_dimm_notify,
1529+ acpi_desc);
13861530 }
13871531
13881532 static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
@@ -1491,9 +1635,9 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, · 102 unmodified lines
14911635 if (!info)
14921636 return -ENOMEM;
14931637 for (i = 0; i < nr; i++) {
1494− struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i];
1638+ struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
14951639 struct nfit_set_info_map *map = &info->mapping[i];
1496− struct nvdimm *nvdimm = nd_mapping->nvdimm;
1640+ struct nvdimm *nvdimm = mapping->nvdimm;
14971641 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
14981642 struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
14991643 spa->range_index, i);
@@ -1917,7 +2061,7 @@ static int acpi_nfit_insert_resource(struct acpi_nfit_desc *acpi_desc, · 417 unmodified lines
19172061 }
19182062
19192063 static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
1920− struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc,
2064+ struct nd_mapping_desc *mapping, struct nd_region_desc *ndr_desc,
19212065 struct acpi_nfit_memory_map *memdev,
19222066 struct nfit_spa *nfit_spa)
19232067 {
@@ -1934,12 +2078,12 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, · 10 unmodified lines
19342078 return -ENODEV;
19352079 }
19362080
1937− nd_mapping->nvdimm = nvdimm;
2081+ mapping->nvdimm = nvdimm;
19382082 switch (nfit_spa_type(spa)) {
19392083 case NFIT_SPA_PM:
19402084 case NFIT_SPA_VOLATILE:
1941− nd_mapping->start = memdev->address;
1942− nd_mapping->size = memdev->region_size;
2085+ mapping->start = memdev->address;
2086+ mapping->size = memdev->region_size;
19432087 break;
19442088 case NFIT_SPA_DCR:
19452089 nfit_mem = nvdimm_provider_data(nvdimm);
@@ -1947,13 +2091,13 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, · 1 unmodified line
19472091 dev_dbg(acpi_desc->dev, "spa%d %s missing bdw\n",
19482092 spa->range_index, nvdimm_name(nvdimm));
19492093 } else {
1950− nd_mapping->size = nfit_mem->bdw->capacity;
1951− nd_mapping->start = nfit_mem->bdw->start_address;
2094+ mapping->size = nfit_mem->bdw->capacity;
2095+ mapping->start = nfit_mem->bdw->start_address;
19522096 ndr_desc->num_lanes = nfit_mem->bdw->windows;
19532097 blk_valid = 1;
19542098 }
19552099
1956− ndr_desc->nd_mapping = nd_mapping;
2100+ ndr_desc->mapping = mapping;
19572101 ndr_desc->num_mappings = blk_valid;
19582102 ndbr_desc = to_blk_region_desc(ndr_desc);
19592103 ndbr_desc->enable = acpi_nfit_blk_region_enable;
@@ -1979,7 +2123,7 @@ static bool nfit_spa_is_virtual(struct acpi_nfit_system_address *spa) · 19 unmodified lines
19792123 static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
19802124 struct nfit_spa *nfit_spa)
19812125 {
1982− static struct nd_mapping nd_mappings[ND_MAX_MAPPINGS];
2126+ static struct nd_mapping_desc mappings[ND_MAX_MAPPINGS];
19832127 struct acpi_nfit_system_address *spa = nfit_spa->spa;
19842128 struct nd_blk_region_desc ndbr_desc;
19852129 struct nd_region_desc *ndr_desc;
@@ -1998,7 +2142,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, · 12 unmodified lines
19982142 }
19992143
20002144 memset(&res, 0, sizeof(res));
2001− memset(&nd_mappings, 0, sizeof(nd_mappings));
2145+ memset(&mappings, 0, sizeof(mappings));
20022146 memset(&ndbr_desc, 0, sizeof(ndbr_desc));
20032147 res.start = spa->address;
20042148 res.end = res.start + spa->length - 1;
@@ -2014,7 +2158,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, · 9 unmodified lines
20142158
20152159 list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
20162160 struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
2017− struct nd_mapping *nd_mapping;
2161+ struct nd_mapping_desc *mapping;
20182162
20192163 if (memdev->range_index != spa->range_index)
20202164 continue;
@@ -2023,14 +2167,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, · 2 unmodified lines
20232167 spa->range_index, ND_MAX_MAPPINGS);
20242168 return -ENXIO;
20252169 }
2026− nd_mapping = &nd_mappings[count++];
2027− rc = acpi_nfit_init_mapping(acpi_desc, nd_mapping, ndr_desc,
2170+ mapping = &mappings[count++];
2171+ rc = acpi_nfit_init_mapping(acpi_desc, mapping, ndr_desc,
20282172 memdev, nfit_spa);
20292173 if (rc)
20302174 goto out;
20312175 }
20322176
2033− ndr_desc->nd_mapping = nd_mappings;
2177+ ndr_desc->mapping = mappings;
20342178 ndr_desc->num_mappings = count;
20352179 rc = acpi_nfit_init_interleave_set(acpi_desc, ndr_desc, spa);
20362180 if (rc)
@@ -2678,29 +2822,30 @@ static int acpi_nfit_remove(struct acpi_device *adev) · 641 unmodified lines
26782822 return 0;
26792823 }
26802824
2681−static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
2825+void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
26822826 {
2683− struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev);
2827+ struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
26842828 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
2685− struct device *dev = &adev->dev;
26862829 union acpi_object *obj;
26872830 acpi_status status;
26882831 int ret;
26892832
26902833 dev_dbg(dev, "%s: event: %d\n", __func__, event);
26912834
2692− device_lock(dev);
2835+ if (event != NFIT_NOTIFY_UPDATE)
2836+ return;
2837+
26932838 if (!dev->driver) {
26942839 /* dev->driver may be null if we're being removed */
26952840 dev_dbg(dev, "%s: no driver found for dev\n", __func__);
2696− goto out_unlock;
2841+ return;
26972842 }
26982843
26992844 if (!acpi_desc) {
27002845 acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
27012846 if (!acpi_desc)
2702− goto out_unlock;
2703− acpi_nfit_desc_init(acpi_desc, &adev->dev);
2847+ return;
2848+ acpi_nfit_desc_init(acpi_desc, dev);
27042849 } else {
27052850 /*
27062851 * Finish previous registration before considering new
@@ -2710,10 +2855,10 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) · 3 unmodified lines
27102855 }
27112856
27122857 /* Evaluate _FIT */
2713− status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf);
2858+ status = acpi_evaluate_object(handle, "_FIT", NULL, &buf);
27142859 if (ACPI_FAILURE(status)) {
27152860 dev_err(dev, "failed to evaluate _FIT\n");
2716− goto out_unlock;
2861+ return;
27172862 }
27182863
27192864 obj = buf.pointer;
@@ -2725,9 +2870,14 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) · 5 unmodified lines
27252870 } else
27262871 dev_err(dev, "Invalid _FIT\n");
27272872 kfree(buf.pointer);
2873+}
2874+EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
27282875
2729− out_unlock:
2730− device_unlock(dev);
2876+static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
2877+{
2878+ device_lock(&adev->dev);
2879+ __acpi_nfit_notify(&adev->dev, adev->handle, event);
2880+ device_unlock(&adev->dev);
27312881 }
27322882
27332883 static const struct acpi_device_id acpi_nfit_ids[] = {
drivers/acpi/nfit/mce.c+19−5
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 */
1515 #include <linux/notifier.h>
1616 #include <linux/acpi.h>
17+#include <linux/nd.h>
1718 #include <asm/mce.h>
1819 #include "nfit.h"
1920
@@ -62,12 +63,25 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, · 42 unmodified lines
6263 }
6364 mutex_unlock(&acpi_desc->init_mutex);
6465
65− /*
66− * We can ignore an -EBUSY here because if an ARS is already
67− * in progress, just let that be the last authoritative one
68− */
69− if (found_match)
66+ if (!found_match)
67+ continue;
68+
69+ /* If this fails due to an -ENOMEM, there is little we can do */
70+ nvdimm_bus_add_poison(acpi_desc->nvdimm_bus,
71+ ALIGN(mce->addr, L1_CACHE_BYTES),
72+ L1_CACHE_BYTES);
73+ nvdimm_region_notify(nfit_spa->nd_region,
74+ NVDIMM_REVALIDATE_POISON);
75+
76+ if (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) {
77+ /*
78+ * We can ignore an -EBUSY here because if an ARS is
79+ * already in progress, just let that be the last
80+ * authoritative one
81+ */
7082 acpi_nfit_ars_rescan(acpi_desc);
83+ }
84+ break;
7185 }
7286
7387 mutex_unlock(&acpi_desc_lock);
drivers/acpi/nfit/nfit.h+17−0
@@ -78,6 +78,14 @@ enum { · 77 unmodified lines
7878 NFIT_ARS_TIMEOUT = 90,
7979 };
8080
81+enum nfit_root_notifiers {
82+ NFIT_NOTIFY_UPDATE = 0x80,
83+};
84+
85+enum nfit_dimm_notifiers {
86+ NFIT_NOTIFY_DIMM_HEALTH = 0x81,
87+};
88+
8189 struct nfit_spa {
8290 struct list_head list;
8391 struct nd_region *nd_region;
@@ -124,6 +132,7 @@ struct nfit_mem { · 40 unmodified lines
124132 struct acpi_nfit_system_address *spa_bdw;
125133 struct acpi_nfit_interleave *idt_dcr;
126134 struct acpi_nfit_interleave *idt_bdw;
135+ struct kernfs_node *flags_attr;
127136 struct nfit_flush *nfit_flush;
128137 struct list_head list;
129138 struct acpi_device *adev;
@@ -152,6 +161,7 @@ struct acpi_nfit_desc { · 22 unmodified lines
152161 struct list_head list;
153162 struct kernfs_node *scrub_count_state;
154163 unsigned int scrub_count;
164+ unsigned int scrub_mode;
155165 unsigned int cancel:1;
156166 unsigned long dimm_cmd_force_en;
157167 unsigned long bus_cmd_force_en;
@@ -159,6 +169,11 @@ struct acpi_nfit_desc { · 1 unmodified line
159169 void *iobuf, u64 len, int rw);
160170 };
161171
172+enum scrub_mode {
173+ HW_ERROR_SCRUB_OFF,
174+ HW_ERROR_SCRUB_ON,
175+};
176+
162177 enum nd_blk_mmio_selector {
163178 BDW,
164179 DCR,
@@ -223,5 +238,7 @@ static inline struct acpi_nfit_desc *to_acpi_desc( · 58 unmodified lines
223238
224239 const u8 *to_nfit_uuid(enum nfit_uuids id);
225240 int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
241+void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
242+void __acpi_nvdimm_notify(struct device *dev, u32 event);
226243 void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
227244 #endif /* __NFIT_H__ */
drivers/nvdimm/bus.c+2−0
@@ -217,6 +217,8 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, · 216 unmodified lines
217217 return rc;
218218 if (cmd_rc < 0)
219219 return cmd_rc;
220+
221+ nvdimm_clear_from_poison_list(nvdimm_bus, phys, len);
220222 return clear_err.cleared;
221223 }
222224 EXPORT_SYMBOL_GPL(nvdimm_clear_poison);
drivers/nvdimm/core.c+69−4
@@ -547,11 +547,12 @@ void nvdimm_badblocks_populate(struct nd_region *nd_region, · 546 unmodified lines
547547 }
548548 EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate);
549549
550−static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
550+static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length,
551+ gfp_t flags)
551552 {
552553 struct nd_poison *pl;
553554
554− pl = kzalloc(sizeof(*pl), GFP_KERNEL);
555+ pl = kzalloc(sizeof(*pl), flags);
555556 if (!pl)
556557 return -ENOMEM;
557558
@@ -567,7 +568,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) · 9 unmodified lines
567568 struct nd_poison *pl;
568569
569570 if (list_empty(&nvdimm_bus->poison_list))
570− return add_poison(nvdimm_bus, addr, length);
571+ return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
571572
572573 /*
573574 * There is a chance this is a duplicate, check for those first.
@@ -587,7 +588,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) · 13 unmodified lines
587588 * as any overlapping ranges will get resolved when the list is consumed
588589 * and converted to badblocks
589590 */
590− return add_poison(nvdimm_bus, addr, length);
591+ return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
591592 }
592593
593594 int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
@@ -602,6 +603,70 @@ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) · 8 unmodified lines
602603 }
603604 EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison);
604605
606+void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
607+ phys_addr_t start, unsigned int len)
608+{
609+ struct list_head *poison_list = &nvdimm_bus->poison_list;
610+ u64 clr_end = start + len - 1;
611+ struct nd_poison *pl, *next;
612+
613+ nvdimm_bus_lock(&nvdimm_bus->dev);
614+ WARN_ON_ONCE(list_empty(poison_list));
615+
616+ /*
617+ * [start, clr_end] is the poison interval being cleared.
618+ * [pl->start, pl_end] is the poison_list entry we're comparing
619+ * the above interval against. The poison list entry may need
620+ * to be modified (update either start or length), deleted, or
621+ * split into two based on the overlap characteristics
622+ */
623+
624+ list_for_each_entry_safe(pl, next, poison_list, list) {
625+ u64 pl_end = pl->start + pl->length - 1;
626+
627+ /* Skip intervals with no intersection */
628+ if (pl_end < start)
629+ continue;
630+ if (pl->start > clr_end)
631+ continue;
632+ /* Delete completely overlapped poison entries */
633+ if ((pl->start >= start) && (pl_end <= clr_end)) {
634+ list_del(&pl->list);
635+ kfree(pl);
636+ continue;
637+ }
638+ /* Adjust start point of partially cleared entries */
639+ if ((start <= pl->start) && (clr_end > pl->start)) {
640+ pl->length -= clr_end - pl->start + 1;
641+ pl->start = clr_end + 1;
642+ continue;
643+ }
644+ /* Adjust pl->length for partial clearing at the tail end */
645+ if ((pl->start < start) && (pl_end <= clr_end)) {
646+ /* pl->start remains the same */
647+ pl->length = start - pl->start;
648+ continue;
649+ }
650+ /*
651+ * If clearing in the middle of an entry, we split it into
652+ * two by modifying the current entry to represent one half of
653+ * the split, and adding a new entry for the second half.
654+ */
655+ if ((pl->start < start) && (pl_end > clr_end)) {
656+ u64 new_start = clr_end + 1;
657+ u64 new_len = pl_end - new_start + 1;
658+
659+ /* Add new entry covering the right half */
660+ add_poison(nvdimm_bus, new_start, new_len, GFP_NOIO);
661+ /* Adjust this entry to cover the left half */
662+ pl->length = start - pl->start;
663+ continue;
664+ }
665+ }
666+ nvdimm_bus_unlock(&nvdimm_bus->dev);
667+}
668+EXPORT_SYMBOL_GPL(nvdimm_clear_from_poison_list);
669+
605670 #ifdef CONFIG_BLK_DEV_INTEGRITY
606671 int nd_integrity_init(struct gendisk *disk, unsigned long meta_size)
607672 {
drivers/nvdimm/dimm.c+11−0
@@ -26,6 +26,14 @@ static int nvdimm_probe(struct device *dev) · 25 unmodified lines
2626 struct nvdimm_drvdata *ndd;
2727 int rc;
2828
29+ rc = nvdimm_check_config_data(dev);
30+ if (rc) {
31+ /* not required for non-aliased nvdimm, ex. NVDIMM-N */
32+ if (rc == -ENOTTY)
33+ rc = 0;
34+ return rc;
35+ }
36+
2937 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
3038 if (!ndd)
3139 return -ENOMEM;
@@ -72,6 +80,9 @@ static int nvdimm_remove(struct device *dev) · 40 unmodified lines
7280 {
7381 struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
7482
83+ if (!ndd)
84+ return 0;
85+
7586 nvdimm_bus_lock(dev);
7687 dev_set_drvdata(dev, NULL);
7788 nvdimm_bus_unlock(dev);
drivers/nvdimm/dimm_devs.c+175−51
@@ -28,28 +28,30 @@ static DEFINE_IDA(dimm_ida); · 27 unmodified lines
2828 * Retrieve bus and dimm handle and return if this bus supports
2929 * get_config_data commands
3030 */
31−static int __validate_dimm(struct nvdimm_drvdata *ndd)
31+int nvdimm_check_config_data(struct device *dev)
3232 {
33− struct nvdimm *nvdimm;
34−
35− if (!ndd)
36− return -EINVAL;
37−
38− nvdimm = to_nvdimm(ndd->dev);
33+ struct nvdimm *nvdimm = to_nvdimm(dev);
3934
40− if (!nvdimm->cmd_mask)
41− return -ENXIO;
42− if (!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask))
43− return -ENXIO;
35+ if (!nvdimm->cmd_mask ||
36+ !test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) {
37+ if (nvdimm->flags & NDD_ALIASING)
38+ return -ENXIO;
39+ else
40+ return -ENOTTY;
41+ }
4442
4543 return 0;
4644 }
4745
4846 static int validate_dimm(struct nvdimm_drvdata *ndd)
4947 {
50− int rc = __validate_dimm(ndd);
48+ int rc;
5149
52− if (rc && ndd)
50+ if (!ndd)
51+ return -EINVAL;
52+
53+ rc = nvdimm_check_config_data(ndd->dev);
54+ if (rc)
5355 dev_dbg(ndd->dev, "%pf: %s error: %d\n",
5456 __builtin_return_address(0), __func__, rc);
5557 return rc;
@@ -263,6 +265,12 @@ const char *nvdimm_name(struct nvdimm *nvdimm) · 207 unmodified lines
263265 }
264266 EXPORT_SYMBOL_GPL(nvdimm_name);
265267
268+struct kobject *nvdimm_kobj(struct nvdimm *nvdimm)
269+{
270+ return &nvdimm->dev.kobj;
271+}
272+EXPORT_SYMBOL_GPL(nvdimm_kobj);
273+
266274 unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm)
267275 {
268276 return nvdimm->cmd_mask;
@@ -378,40 +386,166 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, · 109 unmodified lines
378386 }
379387 EXPORT_SYMBOL_GPL(nvdimm_create);
380388
389+int alias_dpa_busy(struct device *dev, void *data)
390+{
391+ resource_size_t map_end, blk_start, new, busy;
392+ struct blk_alloc_info *info = data;
393+ struct nd_mapping *nd_mapping;
394+ struct nd_region *nd_region;
395+ struct nvdimm_drvdata *ndd;
396+ struct resource *res;
397+ int i;
398+
399+ if (!is_nd_pmem(dev))
400+ return 0;
401+
402+ nd_region = to_nd_region(dev);
403+ for (i = 0; i < nd_region->ndr_mappings; i++) {
404+ nd_mapping = &nd_region->mapping[i];
405+ if (nd_mapping->nvdimm == info->nd_mapping->nvdimm)
406+ break;
407+ }
408+
409+ if (i >= nd_region->ndr_mappings)
410+ return 0;
411+
412+ ndd = to_ndd(nd_mapping);
413+ map_end = nd_mapping->start + nd_mapping->size - 1;
414+ blk_start = nd_mapping->start;
415+
416+ /*
417+ * In the allocation case ->res is set to free space that we are
418+ * looking to validate against PMEM aliasing collision rules
419+ * (i.e. BLK is allocated after all aliased PMEM).
420+ */
421+ if (info->res) {
422+ if (info->res->start >= nd_mapping->start
423+ && info->res->start < map_end)
424+ /* pass */;
425+ else
426+ return 0;
427+ }
428+
429+ retry:
430+ /*
431+ * Find the free dpa from the end of the last pmem allocation to
432+ * the end of the interleave-set mapping that is not already
433+ * covered by a blk allocation.
434+ */
435+ busy = 0;
436+ for_each_dpa_resource(ndd, res) {
437+ if ((res->start >= blk_start && res->start < map_end)
438+ || (res->end >= blk_start
439+ && res->end <= map_end)) {
440+ if (strncmp(res->name, "pmem", 4) == 0) {
441+ new = max(blk_start, min(map_end + 1,
442+ res->end + 1));
443+ if (new != blk_start) {
444+ blk_start = new;
445+ goto retry;
446+ }
447+ } else
448+ busy += min(map_end, res->end)
449+ - max(nd_mapping->start, res->start) + 1;
450+ } else if (nd_mapping->start > res->start
451+ && map_end < res->end) {
452+ /* total eclipse of the PMEM region mapping */
453+ busy += nd_mapping->size;
454+ break;
455+ }
456+ }
457+
458+ /* update the free space range with the probed blk_start */
459+ if (info->res && blk_start > info->res->start) {
460+ info->res->start = max(info->res->start, blk_start);
461+ if (info->res->start > info->res->end)
462+ info->res->end = info->res->start - 1;
463+ return 1;
464+ }
465+
466+ info->available -= blk_start - nd_mapping->start + busy;
467+
468+ return 0;
469+}
470+
471+static int blk_dpa_busy(struct device *dev, void *data)
472+{
473+ struct blk_alloc_info *info = data;
474+ struct nd_mapping *nd_mapping;
475+ struct nd_region *nd_region;
476+ resource_size_t map_end;
477+ int i;
478+
479+ if (!is_nd_pmem(dev))
480+ return 0;
481+
482+ nd_region = to_nd_region(dev);
483+ for (i = 0; i < nd_region->ndr_mappings; i++) {
484+ nd_mapping = &nd_region->mapping[i];
485+ if (nd_mapping->nvdimm == info->nd_mapping->nvdimm)
486+ break;
487+ }
488+
489+ if (i >= nd_region->ndr_mappings)
490+ return 0;
491+
492+ map_end = nd_mapping->start + nd_mapping->size - 1;
493+ if (info->res->start >= nd_mapping->start
494+ && info->res->start < map_end) {
495+ if (info->res->end <= map_end) {
496+ info->busy = 0;
497+ return 1;
498+ } else {
499+ info->busy -= info->res->end - map_end;
500+ return 0;
501+ }
502+ } else if (info->res->end >= nd_mapping->start
503+ && info->res->end <= map_end) {
504+ info->busy -= nd_mapping->start - info->res->start;
505+ return 0;
506+ } else {
507+ info->busy -= nd_mapping->size;
508+ return 0;
509+ }
510+}
511+
381512 /**
382513 * nd_blk_available_dpa - account the unused dpa of BLK region
383514 * @nd_mapping: container of dpa-resource-root + labels
384515 *
385− * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges.
516+ * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges, but
517+ * we arrange for them to never start at an lower dpa than the last
518+ * PMEM allocation in an aliased region.
386519 */
387−resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping)
520+resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
388521 {
522+ struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
523+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
389524 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
390− resource_size_t map_end, busy = 0, available;
525+ struct blk_alloc_info info = {
526+ .nd_mapping = nd_mapping,
527+ .available = nd_mapping->size,
528+ .res = NULL,
529+ };
391530 struct resource *res;
392531
393532 if (!ndd)
394533 return 0;
395534
396− map_end = nd_mapping->start + nd_mapping->size - 1;
397− for_each_dpa_resource(ndd, res)
398− if (res->start >= nd_mapping->start && res->start < map_end) {
399− resource_size_t end = min(map_end, res->end);
535+ device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
400536
401− busy += end - res->start + 1;
402− } else if (res->end >= nd_mapping->start
403− && res->end <= map_end) {
404− busy += res->end - nd_mapping->start;
405− } else if (nd_mapping->start > res->start
406− && nd_mapping->start < res->end) {
407− /* total eclipse of the BLK region mapping */
408− busy += nd_mapping->size;
409− }
537+ /* now account for busy blk allocations in unaliased dpa */
538+ for_each_dpa_resource(ndd, res) {
539+ if (strncmp(res->name, "blk", 3) != 0)
540+ continue;
410541
411− available = map_end - nd_mapping->start + 1;
412− if (busy < available)
413− return available - busy;
414− return 0;
542+ info.res = res;
543+ info.busy = resource_size(res);
544+ device_for_each_child(&nvdimm_bus->dev, &info, blk_dpa_busy);
545+ info.available -= info.busy;
546+ }
547+
548+ return info.available;
415549 }
416550
417551 /**
@@ -443,21 +577,16 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, · 25 unmodified lines
443577 map_start = nd_mapping->start;
444578 map_end = map_start + nd_mapping->size - 1;
445579 blk_start = max(map_start, map_end + 1 - *overlap);
446− for_each_dpa_resource(ndd, res)
580+ for_each_dpa_resource(ndd, res) {
447581 if (res->start >= map_start && res->start < map_end) {
448582 if (strncmp(res->name, "blk", 3) == 0)
449− blk_start = min(blk_start, res->start);
450− else if (res->start != map_start) {
583+ blk_start = min(blk_start,
584+ max(map_start, res->start));
585+ else if (res->end > map_end) {
451586 reason = "misaligned to iset";
452587 goto err;
453− } else {
454− if (busy) {
455− reason = "duplicate overlapping PMEM reservations?";
456− goto err;
457− }
588+ } else
458589 busy += resource_size(res);
459− continue;
460− }
461590 } else if (res->end >= map_start && res->end <= map_end) {
462591 if (strncmp(res->name, "blk", 3) == 0) {
463592 /*
@@ -466,15 +595,14 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, · 2 unmodified lines
466595 * be used for BLK.
467596 */
468597 blk_start = map_start;
469− } else {
470− reason = "misaligned to iset";
471− goto err;
472− }
598+ } else
599+ busy += resource_size(res);
473600 } else if (map_start > res->start && map_start < res->end) {
474601 /* total eclipse of the mapping */
475602 busy += nd_mapping->size;
476603 blk_start = map_start;
477604 }
605+ }
478606
479607 *overlap = map_end + 1 - blk_start;
480608 available = blk_start - map_start;
@@ -483,10 +611,6 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, · 2 unmodified lines
483611 return 0;
484612
485613 err:
486− /*
487− * Something is wrong, PMEM must align with the start of the
488− * interleave set, and there can only be one allocation per set.
489− */
490614 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason);
491615 return 0;
492616 }
drivers/nvdimm/label.c+120−72
@@ -494,11 +494,13 @@ static int __pmem_label_update(struct nd_region *nd_region, · 493 unmodified lines
494494 struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm,
495495 int pos)
496496 {
497− u64 cookie = nd_region_interleave_set_cookie(nd_region), rawsize;
497+ u64 cookie = nd_region_interleave_set_cookie(nd_region);
498498 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
499− struct nd_namespace_label *victim_label;
499+ struct nd_label_ent *label_ent, *victim = NULL;
500500 struct nd_namespace_label *nd_label;
501501 struct nd_namespace_index *nsindex;
502+ struct nd_label_id label_id;
503+ struct resource *res;
502504 unsigned long *free;
503505 u32 nslot, slot;
504506 size_t offset;
@@ -507,6 +509,16 @@ static int __pmem_label_update(struct nd_region *nd_region, · 2 unmodified lines
507509 if (!preamble_next(ndd, &nsindex, &free, &nslot))
508510 return -ENXIO;
509511
512+ nd_label_gen_id(&label_id, nspm->uuid, 0);
513+ for_each_dpa_resource(ndd, res)
514+ if (strcmp(res->name, label_id.id) == 0)
515+ break;
516+
517+ if (!res) {
518+ WARN_ON_ONCE(1);
519+ return -ENXIO;
520+ }
521+
510522 /* allocate and write the label to the staging (next) index */
511523 slot = nd_label_alloc_slot(ndd);
512524 if (slot == UINT_MAX)
@@ -522,11 +534,10 @@ static int __pmem_label_update(struct nd_region *nd_region, · 9 unmodified lines
522534 nd_label->nlabel = __cpu_to_le16(nd_region->ndr_mappings);
523535 nd_label->position = __cpu_to_le16(pos);
524536 nd_label->isetcookie = __cpu_to_le64(cookie);
525− rawsize = div_u64(resource_size(&nspm->nsio.res),
526− nd_region->ndr_mappings);
527− nd_label->rawsize = __cpu_to_le64(rawsize);
528− nd_label->dpa = __cpu_to_le64(nd_mapping->start);
537+ nd_label->rawsize = __cpu_to_le64(resource_size(res));
538+ nd_label->dpa = __cpu_to_le64(res->start);
529539 nd_label->slot = __cpu_to_le32(slot);
540+ nd_dbg_dpa(nd_region, ndd, res, "%s\n", __func__);
530541
531542 /* update label */
532543 offset = nd_label_offset(ndd, nd_label);
@@ -536,38 +547,43 @@ static int __pmem_label_update(struct nd_region *nd_region, · 3 unmodified lines
536547 return rc;
537548
538549 /* Garbage collect the previous label */
539− victim_label = nd_mapping->labels[0];
540− if (victim_label) {
541− slot = to_slot(ndd, victim_label);
542− nd_label_free_slot(ndd, slot);
550+ mutex_lock(&nd_mapping->lock);
551+ list_for_each_entry(label_ent, &nd_mapping->labels, list) {
552+ if (!label_ent->label)
553+ continue;
554+ if (memcmp(nspm->uuid, label_ent->label->uuid,
555+ NSLABEL_UUID_LEN) != 0)
556+ continue;
557+ victim = label_ent;
558+ list_move_tail(&victim->list, &nd_mapping->labels);
559+ break;
560+ }
561+ if (victim) {
543562 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot);
563+ slot = to_slot(ndd, victim->label);
564+ nd_label_free_slot(ndd, slot);
565+ victim->label = NULL;
544566 }
545567
546568 /* update index */
547569 rc = nd_label_write_index(ndd, ndd->ns_next,
548570 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
549− if (rc < 0)
550− return rc;
551−
552− nd_mapping->labels[0] = nd_label;
553−
554− return 0;
555−}
556−
557−static void del_label(struct nd_mapping *nd_mapping, int l)
558−{
559− struct nd_namespace_label *next_label, *nd_label;
560− struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
561− unsigned int slot;
562− int j;
563−
564− nd_label = nd_mapping->labels[l];
565− slot = to_slot(ndd, nd_label);
566− dev_vdbg(ndd->dev, "%s: clear: %d\n", __func__, slot);
571+ if (rc == 0) {
572+ list_for_each_entry(label_ent, &nd_mapping->labels, list)
573+ if (!label_ent->label) {
574+ label_ent->label = nd_label;
575+ nd_label = NULL;
576+ break;
577+ }
578+ dev_WARN_ONCE(&nspm->nsio.common.dev, nd_label,
579+ "failed to track label: %d\n",
580+ to_slot(ndd, nd_label));
581+ if (nd_label)
582+ rc = -ENXIO;
583+ }
584+ mutex_unlock(&nd_mapping->lock);
567585
568− for (j = l; (next_label = nd_mapping->labels[j + 1]); j++)
569− nd_mapping->labels[j] = next_label;
570− nd_mapping->labels[j] = NULL;
586+ return rc;
571587 }
572588
573589 static bool is_old_resource(struct resource *res, struct resource **list, int n)
@@ -607,14 +623,16 @@ static int __blk_label_update(struct nd_region *nd_region, · 33 unmodified lines
607623 struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk,
608624 int num_labels)
609625 {
610− int i, l, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO;
626+ int i, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO;
611627 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
612628 struct nd_namespace_label *nd_label;
629+ struct nd_label_ent *label_ent, *e;
613630 struct nd_namespace_index *nsindex;
614631 unsigned long *free, *victim_map = NULL;
615632 struct resource *res, **old_res_list;
616633 struct nd_label_id label_id;
617634 u8 uuid[NSLABEL_UUID_LEN];
635+ LIST_HEAD(list);
618636 u32 nslot, slot;
619637
620638 if (!preamble_next(ndd, &nsindex, &free, &nslot))
@@ -736,15 +754,22 @@ static int __blk_label_update(struct nd_region *nd_region, · 115 unmodified lines
736754 * entries in nd_mapping->labels
737755 */
738756 nlabel = 0;
739− for_each_label(l, nd_label, nd_mapping->labels) {
757+ mutex_lock(&nd_mapping->lock);
758+ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
759+ nd_label = label_ent->label;
760+ if (!nd_label)
761+ continue;
740762 nlabel++;
741763 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
742764 if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
743765 continue;
744766 nlabel--;
745− del_label(nd_mapping, l);
746− l--; /* retry with the new label at this index */
767+ list_move(&label_ent->list, &list);
768+ label_ent->label = NULL;
747769 }
770+ list_splice_tail_init(&list, &nd_mapping->labels);
771+ mutex_unlock(&nd_mapping->lock);
772+
748773 if (nlabel + nsblk->num_resources > num_labels) {
749774 /*
750775 * Bug, we can't end up with more resources than
@@ -755,6 +780,15 @@ static int __blk_label_update(struct nd_region *nd_region, · 4 unmodified lines
755780 goto out;
756781 }
757782
783+ mutex_lock(&nd_mapping->lock);
784+ label_ent = list_first_entry_or_null(&nd_mapping->labels,
785+ typeof(*label_ent), list);
786+ if (!label_ent) {
787+ WARN_ON(1);
788+ mutex_unlock(&nd_mapping->lock);
789+ rc = -ENXIO;
790+ goto out;
791+ }
758792 for_each_clear_bit_le(slot, free, nslot) {
759793 nd_label = nd_label_base(ndd) + slot;
760794 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
@@ -762,11 +796,19 @@ static int __blk_label_update(struct nd_region *nd_region, · 1 unmodified line
762796 continue;
763797 res = to_resource(ndd, nd_label);
764798 res->flags &= ~DPA_RESOURCE_ADJUSTED;
765− dev_vdbg(&nsblk->common.dev, "assign label[%d] slot: %d\n",
766− l, slot);
767− nd_mapping->labels[l++] = nd_label;
799+ dev_vdbg(&nsblk->common.dev, "assign label slot: %d\n", slot);
800+ list_for_each_entry_from(label_ent, &nd_mapping->labels, list) {
801+ if (label_ent->label)
802+ continue;
803+ label_ent->label = nd_label;
804+ nd_label = NULL;
805+ break;
806+ }
807+ if (nd_label)
808+ dev_WARN(&nsblk->common.dev,
809+ "failed to track label slot%d\n", slot);
768810 }
769− nd_mapping->labels[l] = NULL;
811+ mutex_unlock(&nd_mapping->lock);
770812
771813 out:
772814 kfree(old_res_list);
@@ -788,32 +830,28 @@ static int __blk_label_update(struct nd_region *nd_region, · 15 unmodified lines
788830
789831 static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
790832 {
791− int i, l, old_num_labels = 0;
833+ int i, old_num_labels = 0;
834+ struct nd_label_ent *label_ent;
792835 struct nd_namespace_index *nsindex;
793− struct nd_namespace_label *nd_label;
794836 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
795− size_t size = (num_labels + 1) * sizeof(struct nd_namespace_label *);
796837
797− for_each_label(l, nd_label, nd_mapping->labels)
838+ mutex_lock(&nd_mapping->lock);
839+ list_for_each_entry(label_ent, &nd_mapping->labels, list)
798840 old_num_labels++;
841+ mutex_unlock(&nd_mapping->lock);
799842
800843 /*
801844 * We need to preserve all the old labels for the mapping so
802845 * they can be garbage collected after writing the new labels.
803846 */
804− if (num_labels > old_num_labels) {
805− struct nd_namespace_label **labels;
806−
807− labels = krealloc(nd_mapping->labels, size, GFP_KERNEL);
808− if (!labels)
847+ for (i = old_num_labels; i < num_labels; i++) {
848+ label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
849+ if (!label_ent)
809850 return -ENOMEM;
810− nd_mapping->labels = labels;
851+ mutex_lock(&nd_mapping->lock);
852+ list_add_tail(&label_ent->list, &nd_mapping->labels);
853+ mutex_unlock(&nd_mapping->lock);
811854 }
812− if (!nd_mapping->labels)
813− return -ENOMEM;
814−
815− for (i = old_num_labels; i <= num_labels; i++)
816− nd_mapping->labels[i] = NULL;
817855
818856 if (ndd->ns_current == -1 || ndd->ns_next == -1)
819857 /* pass */;
@@ -837,42 +875,45 @@ static int init_labels(struct nd_mapping *nd_mapping, int num_labels) · 17 unmodified lines
837875 static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid)
838876 {
839877 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
840− struct nd_namespace_label *nd_label;
878+ struct nd_label_ent *label_ent, *e;
841879 struct nd_namespace_index *nsindex;
842880 u8 label_uuid[NSLABEL_UUID_LEN];
843− int l, num_freed = 0;
844881 unsigned long *free;
882+ LIST_HEAD(list);
845883 u32 nslot, slot;
884+ int active = 0;
846885
847886 if (!uuid)
848887 return 0;
849888
850889 /* no index || no labels == nothing to delete */
851− if (!preamble_next(ndd, &nsindex, &free, &nslot)
852− || !nd_mapping->labels)
890+ if (!preamble_next(ndd, &nsindex, &free, &nslot))
853891 return 0;
854892
855− for_each_label(l, nd_label, nd_mapping->labels) {
893+ mutex_lock(&nd_mapping->lock);
894+ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
895+ struct nd_namespace_label *nd_label = label_ent->label;
896+
897+ if (!nd_label)
898+ continue;
899+ active++;
856900 memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN);
857901 if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0)
858902 continue;
903+ active--;
859904 slot = to_slot(ndd, nd_label);
860905 nd_label_free_slot(ndd, slot);
861906 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot);
862− del_label(nd_mapping, l);
863− num_freed++;
864− l--; /* retry with new label at this index */
907+ list_move_tail(&label_ent->list, &list);
908+ label_ent->label = NULL;
865909 }
910+ list_splice_tail_init(&list, &nd_mapping->labels);
866911
867− if (num_freed > l) {
868− /*
869− * num_freed will only ever be > l when we delete the last
870− * label
871− */
872− kfree(nd_mapping->labels);
873− nd_mapping->labels = NULL;
874− dev_dbg(ndd->dev, "%s: no more labels\n", __func__);
912+ if (active == 0) {
913+ nd_mapping_free_labels(nd_mapping);
914+ dev_dbg(ndd->dev, "%s: no more active labels\n", __func__);
875915 }
916+ mutex_unlock(&nd_mapping->lock);
876917
877918 return nd_label_write_index(ndd, ndd->ns_next,
878919 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
@@ -885,7 +926,9 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region, · 6 unmodified lines
885926
886927 for (i = 0; i < nd_region->ndr_mappings; i++) {
887928 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
888− int rc;
929+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
930+ struct resource *res;
931+ int rc, count = 0;
889932
890933 if (size == 0) {
891934 rc = del_labels(nd_mapping, nspm->uuid);
@@ -894,7 +937,12 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region, · 2 unmodified lines
894937 continue;
895938 }
896939
897− rc = init_labels(nd_mapping, 1);
940+ for_each_dpa_resource(ndd, res)
941+ if (strncmp(res->name, "pmem", 3) == 0)
942+ count++;
943+ WARN_ON_ONCE(!count);
944+
945+ rc = init_labels(nd_mapping, count);
898946 if (rc < 0)
899947 return rc;
900948
drivers/nvdimm/namespace_devs.c+547−245
@@ -12,8 +12,10 @@ · 11 unmodified lines
1212 */
1313 #include <linux/module.h>
1414 #include <linux/device.h>
15+#include <linux/sort.h>
1516 #include <linux/slab.h>
1617 #include <linux/pmem.h>
18+#include <linux/list.h>
1719 #include <linux/nd.h>
1820 #include "nd-core.h"
1921 #include "nd.h"
@@ -28,7 +30,10 @@ static void namespace_io_release(struct device *dev) · 8 unmodified lines
2830 static void namespace_pmem_release(struct device *dev)
2931 {
3032 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
33+ struct nd_region *nd_region = to_nd_region(dev->parent);
3134
35+ if (nspm->id >= 0)
36+ ida_simple_remove(&nd_region->ns_ida, nspm->id);
3237 kfree(nspm->alt_name);
3338 kfree(nspm->uuid);
3439 kfree(nspm);
@@ -62,17 +67,17 @@ static struct device_type namespace_blk_device_type = { · 27 unmodified lines
6267 .release = namespace_blk_release,
6368 };
6469
65−static bool is_namespace_pmem(struct device *dev)
70+static bool is_namespace_pmem(const struct device *dev)
6671 {
6772 return dev ? dev->type == &namespace_pmem_device_type : false;
6873 }
6974
70−static bool is_namespace_blk(struct device *dev)
75+static bool is_namespace_blk(const struct device *dev)
7176 {
7277 return dev ? dev->type == &namespace_blk_device_type : false;
7378 }
7479
75−static bool is_namespace_io(struct device *dev)
80+static bool is_namespace_io(const struct device *dev)
7681 {
7782 return dev ? dev->type == &namespace_io_device_type : false;
7883 }
@@ -168,7 +173,21 @@ const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns, · 89 unmodified lines
168173 suffix = "s";
169174
170175 if (is_namespace_pmem(&ndns->dev) || is_namespace_io(&ndns->dev)) {
171− sprintf(name, "pmem%d%s", nd_region->id, suffix ? suffix : "");
176+ int nsidx = 0;
177+
178+ if (is_namespace_pmem(&ndns->dev)) {
179+ struct nd_namespace_pmem *nspm;
180+
181+ nspm = to_nd_namespace_pmem(&ndns->dev);
182+ nsidx = nspm->id;
183+ }
184+
185+ if (nsidx)
186+ sprintf(name, "pmem%d.%d%s", nd_region->id, nsidx,
187+ suffix ? suffix : "");
188+ else
189+ sprintf(name, "pmem%d%s", nd_region->id,
190+ suffix ? suffix : "");
172191 } else if (is_namespace_blk(&ndns->dev)) {
173192 struct nd_namespace_blk *nsblk;
174193
@@ -294,7 +313,7 @@ static bool __nd_namespace_blk_validate(struct nd_namespace_blk *nsblk) · 119 unmodified lines
294313 if (strcmp(res->name, label_id.id) != 0)
295314 continue;
296315 /*
297− * Resources with unacknoweldged adjustments indicate a
316+ * Resources with unacknowledged adjustments indicate a
298317 * failure to update labels
299318 */
300319 if (res->flags & DPA_RESOURCE_ADJUSTED)
@@ -510,19 +529,68 @@ static resource_size_t init_dpa_allocation(struct nd_label_id *label_id, · 209 unmodified lines
510529 return rc ? n : 0;
511530 }
512531
513−static bool space_valid(bool is_pmem, bool is_reserve,
514− struct nd_label_id *label_id, struct resource *res)
532+
533+/**
534+ * space_valid() - validate free dpa space against constraints
535+ * @nd_region: hosting region of the free space
536+ * @ndd: dimm device data for debug
537+ * @label_id: namespace id to allocate space
538+ * @prev: potential allocation that precedes free space
539+ * @next: allocation that follows the given free space range
540+ * @exist: first allocation with same id in the mapping
541+ * @n: range that must satisfied for pmem allocations
542+ * @valid: free space range to validate
543+ *
544+ * BLK-space is valid as long as it does not precede a PMEM
545+ * allocation in a given region. PMEM-space must be contiguous
546+ * and adjacent to an existing existing allocation (if one
547+ * exists). If reserving PMEM any space is valid.
548+ */
549+static void space_valid(struct nd_region *nd_region, struct nvdimm_drvdata *ndd,
550+ struct nd_label_id *label_id, struct resource *prev,
551+ struct resource *next, struct resource *exist,
552+ resource_size_t n, struct resource *valid)
515553 {
516− /*
517− * For BLK-space any space is valid, for PMEM-space, it must be
518− * contiguous with an existing allocation unless we are
519− * reserving pmem.
520− */
521− if (is_reserve || !is_pmem)
522− return true;
523− if (!res || strcmp(res->name, label_id->id) == 0)
524− return true;
525− return false;
554+ bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
555+ bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
556+
557+ if (valid->start >= valid->end)
558+ goto invalid;
559+
560+ if (is_reserve)
561+ return;
562+
563+ if (!is_pmem) {
564+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
565+ struct nvdimm_bus *nvdimm_bus;
566+ struct blk_alloc_info info = {
567+ .nd_mapping = nd_mapping,
568+ .available = nd_mapping->size,
569+ .res = valid,
570+ };
571+
572+ WARN_ON(!is_nd_blk(&nd_region->dev));
573+ nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
574+ device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
575+ return;
576+ }
577+
578+ /* allocation needs to be contiguous, so this is all or nothing */
579+ if (resource_size(valid) < n)
580+ goto invalid;
581+
582+ /* we've got all the space we need and no existing allocation */
583+ if (!exist)
584+ return;
585+
586+ /* allocation needs to be contiguous with the existing namespace */
587+ if (valid->start == exist->end + 1
588+ || valid->end == exist->start - 1)
589+ return;
590+
591+ invalid:
592+ /* truncate @valid size to 0 */
593+ valid->end = valid->start - 1;
526594 }
527595
528596 enum alloc_loc {
@@ -534,18 +602,24 @@ static resource_size_t scan_allocate(struct nd_region *nd_region, · 5 unmodified lines
534602 resource_size_t n)
535603 {
536604 resource_size_t mapping_end = nd_mapping->start + nd_mapping->size - 1;
537− bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
538605 bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
539606 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
607+ struct resource *res, *exist = NULL, valid;
540608 const resource_size_t to_allocate = n;
541− struct resource *res;
542609 int first;
543610
611+ for_each_dpa_resource(ndd, res)
612+ if (strcmp(label_id->id, res->name) == 0)
613+ exist = res;
614+
615+ valid.start = nd_mapping->start;
616+ valid.end = mapping_end;
617+ valid.name = "free space";
544618 retry:
545619 first = 0;
546620 for_each_dpa_resource(ndd, res) {
547− resource_size_t allocate, available = 0, free_start, free_end;
548621 struct resource *next = res->sibling, *new_res = NULL;
622+ resource_size_t allocate, available = 0;
549623 enum alloc_loc loc = ALLOC_ERR;
550624 const char *action;
551625 int rc = 0;
@@ -558,32 +632,35 @@ static resource_size_t scan_allocate(struct nd_region *nd_region, · 6 unmodified lines
558632
559633 /* space at the beginning of the mapping */
560634 if (!first++ && res->start > nd_mapping->start) {
561− free_start = nd_mapping->start;
562− available = res->start - free_start;
563− if (space_valid(is_pmem, is_reserve, label_id, NULL))
635+ valid.start = nd_mapping->start;
636+ valid.end = res->start - 1;
637+ space_valid(nd_region, ndd, label_id, NULL, next, exist,
638+ to_allocate, &valid);
639+ available = resource_size(&valid);
640+ if (available)
564641 loc = ALLOC_BEFORE;
565642 }
566643
567644 /* space between allocations */
568645 if (!loc && next) {
569− free_start = res->start + resource_size(res);
570− free_end = min(mapping_end, next->start - 1);
571− if (space_valid(is_pmem, is_reserve, label_id, res)
572− && free_start < free_end) {
573− available = free_end + 1 - free_start;
646+ valid.start = res->start + resource_size(res);
647+ valid.end = min(mapping_end, next->start - 1);
648+ space_valid(nd_region, ndd, label_id, res, next, exist,
649+ to_allocate, &valid);
650+ available = resource_size(&valid);
651+ if (available)
574652 loc = ALLOC_MID;
575− }
576653 }
577654
578655 /* space at the end of the mapping */
579656 if (!loc && !next) {
580− free_start = res->start + resource_size(res);
581− free_end = mapping_end;
582− if (space_valid(is_pmem, is_reserve, label_id, res)
583− && free_start < free_end) {
584− available = free_end + 1 - free_start;
657+ valid.start = res->start + resource_size(res);
658+ valid.end = mapping_end;
659+ space_valid(nd_region, ndd, label_id, res, next, exist,
660+ to_allocate, &valid);
661+ available = resource_size(&valid);
662+ if (available)
585663 loc = ALLOC_AFTER;
586− }
587664 }
588665
589666 if (!loc || !available)
@@ -593,8 +670,6 @@ static resource_size_t scan_allocate(struct nd_region *nd_region, · 3 unmodified lines
593670 case ALLOC_BEFORE:
594671 if (strcmp(res->name, label_id->id) == 0) {
595672 /* adjust current resource up */
596− if (is_pmem && !is_reserve)
597− return n;
598673 rc = adjust_resource(res, res->start - allocate,
599674 resource_size(res) + allocate);
600675 action = "cur grow up";
@@ -604,8 +679,6 @@ static resource_size_t scan_allocate(struct nd_region *nd_region, · 3 unmodified lines
604679 case ALLOC_MID:
605680 if (strcmp(next->name, label_id->id) == 0) {
606681 /* adjust next resource up */
607− if (is_pmem && !is_reserve)
608− return n;
609682 rc = adjust_resource(next, next->start
610683 - allocate, resource_size(next)
611684 + allocate);
@@ -629,12 +702,10 @@ static resource_size_t scan_allocate(struct nd_region *nd_region, · 17 unmodified lines
629702 if (strcmp(action, "allocate") == 0) {
630703 /* BLK allocate bottom up */
631704 if (!is_pmem)
632− free_start += available - allocate;
633− else if (!is_reserve && free_start != nd_mapping->start)
634− return n;
705+ valid.start += available - allocate;
635706
636707 new_res = nvdimm_allocate_dpa(ndd, label_id,
637− free_start, allocate);
708+ valid.start, allocate);
638709 if (!new_res)
639710 rc = -EBUSY;
640711 } else if (strcmp(action, "grow down") == 0) {
@@ -832,13 +903,45 @@ static int grow_dpa_allocation(struct nd_region *nd_region, · 191 unmodified lines
832903 return 0;
833904 }
834905
835−static void nd_namespace_pmem_set_size(struct nd_region *nd_region,
906+static void nd_namespace_pmem_set_resource(struct nd_region *nd_region,
836907 struct nd_namespace_pmem *nspm, resource_size_t size)
837908 {
838909 struct resource *res = &nspm->nsio.res;
910+ resource_size_t offset = 0;
839911
840− res->start = nd_region->ndr_start;
841− res->end = nd_region->ndr_start + size - 1;
912+ if (size && !nspm->uuid) {
913+ WARN_ON_ONCE(1);
914+ size = 0;
915+ }
916+
917+ if (size && nspm->uuid) {
918+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
919+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
920+ struct nd_label_id label_id;
921+ struct resource *res;
922+
923+ if (!ndd) {
924+ size = 0;
925+ goto out;
926+ }
927+
928+ nd_label_gen_id(&label_id, nspm->uuid, 0);
929+
930+ /* calculate a spa offset from the dpa allocation offset */
931+ for_each_dpa_resource(ndd, res)
932+ if (strcmp(res->name, label_id.id) == 0) {
933+ offset = (res->start - nd_mapping->start)
934+ * nd_region->ndr_mappings;
935+ goto out;
936+ }
937+
938+ WARN_ON_ONCE(1);
939+ size = 0;
940+ }
941+
942+ out:
943+ res->start = nd_region->ndr_start + offset;
944+ res->end = res->start + size - 1;
842945 }
843946
844947 static bool uuid_not_set(const u8 *uuid, struct device *dev, const char *where)
@@ -929,7 +1032,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val) · 84 unmodified lines
9291032 if (is_namespace_pmem(dev)) {
9301033 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
9311034
932− nd_namespace_pmem_set_size(nd_region, nspm,
1035+ nd_namespace_pmem_set_resource(nd_region, nspm,
9331036 val * nd_region->ndr_mappings);
9341037 } else if (is_namespace_blk(dev)) {
9351038 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
@@ -1031,22 +1134,27 @@ static ssize_t size_show(struct device *dev, · 95 unmodified lines
10311134 }
10321135 static DEVICE_ATTR(size, S_IRUGO, size_show, size_store);
10331136
1034−static ssize_t uuid_show(struct device *dev,
1035− struct device_attribute *attr, char *buf)
1137+static u8 *namespace_to_uuid(struct device *dev)
10361138 {
1037− u8 *uuid;
1038−
10391139 if (is_namespace_pmem(dev)) {
10401140 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
10411141
1042− uuid = nspm->uuid;
1142+ return nspm->uuid;
10431143 } else if (is_namespace_blk(dev)) {
10441144 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
10451145
1046− uuid = nsblk->uuid;
1146+ return nsblk->uuid;
10471147 } else
1048− return -ENXIO;
1148+ return ERR_PTR(-ENXIO);
1149+}
10491150
1151+static ssize_t uuid_show(struct device *dev,
1152+ struct device_attribute *attr, char *buf)
1153+{
1154+ u8 *uuid = namespace_to_uuid(dev);
1155+
1156+ if (IS_ERR(uuid))
1157+ return PTR_ERR(uuid);
10501158 if (uuid)
10511159 return sprintf(buf, "%pUb\n", uuid);
10521160 return sprintf(buf, "\n");
@@ -1089,7 +1197,7 @@ static int namespace_update_uuid(struct nd_region *nd_region, · 36 unmodified lines
10891197 *
10901198 * FIXME: can we delete uuid with zero dpa allocated?
10911199 */
1092− if (nd_mapping->labels)
1200+ if (list_empty(&nd_mapping->labels))
10931201 return -EBUSY;
10941202 }
10951203
@@ -1491,14 +1599,19 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid, · 395 unmodified lines
14911599
14921600 for (i = 0; i < nd_region->ndr_mappings; i++) {
14931601 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1494− struct nd_namespace_label *nd_label;
1602+ struct nd_label_ent *label_ent;
14951603 bool found_uuid = false;
1496− int l;
14971604
1498− for_each_label(l, nd_label, nd_mapping->labels) {
1499− u64 isetcookie = __le64_to_cpu(nd_label->isetcookie);
1500− u16 position = __le16_to_cpu(nd_label->position);
1501− u16 nlabel = __le16_to_cpu(nd_label->nlabel);
1605+ list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1606+ struct nd_namespace_label *nd_label = label_ent->label;
1607+ u16 position, nlabel;
1608+ u64 isetcookie;
1609+
1610+ if (!nd_label)
1611+ continue;
1612+ isetcookie = __le64_to_cpu(nd_label->isetcookie);
1613+ position = __le16_to_cpu(nd_label->position);
1614+ nlabel = __le16_to_cpu(nd_label->nlabel);
15021615
15031616 if (isetcookie != cookie)
15041617 continue;
@@ -1528,7 +1641,6 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid, · 23 unmodified lines
15281641
15291642 static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
15301643 {
1531− struct nd_namespace_label *select = NULL;
15321644 int i;
15331645
15341646 if (!pmem_id)
@@ -1536,90 +1648,106 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id) · 1 unmodified line
15361648
15371649 for (i = 0; i < nd_region->ndr_mappings; i++) {
15381650 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1539− struct nd_namespace_label *nd_label;
1651+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1652+ struct nd_namespace_label *nd_label = NULL;
15401653 u64 hw_start, hw_end, pmem_start, pmem_end;
1541− int l;
1654+ struct nd_label_ent *label_ent;
15421655
1543− for_each_label(l, nd_label, nd_mapping->labels)
1656+ WARN_ON(!mutex_is_locked(&nd_mapping->lock));
1657+ list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1658+ nd_label = label_ent->label;
1659+ if (!nd_label)
1660+ continue;
15441661 if (memcmp(nd_label->uuid, pmem_id, NSLABEL_UUID_LEN) == 0)
15451662 break;
1663+ nd_label = NULL;
1664+ }
15461665
15471666 if (!nd_label) {
15481667 WARN_ON(1);
15491668 return -EINVAL;
15501669 }
15511670
1552− select = nd_label;
15531671 /*
15541672 * Check that this label is compliant with the dpa
15551673 * range published in NFIT
15561674 */
15571675 hw_start = nd_mapping->start;
15581676 hw_end = hw_start + nd_mapping->size;
1559− pmem_start = __le64_to_cpu(select->dpa);
1560− pmem_end = pmem_start + __le64_to_cpu(select->rawsize);
1561− if (pmem_start == hw_start && pmem_end <= hw_end)
1677+ pmem_start = __le64_to_cpu(nd_label->dpa);
1678+ pmem_end = pmem_start + __le64_to_cpu(nd_label->rawsize);
1679+ if (pmem_start >= hw_start && pmem_start < hw_end
1680+ && pmem_end <= hw_end && pmem_end > hw_start)
15621681 /* pass */;
1563− else
1682+ else {
1683+ dev_dbg(&nd_region->dev, "%s invalid label for %pUb\n",
1684+ dev_name(ndd->dev), nd_label->uuid);
15641685 return -EINVAL;
1686+ }
15651687
1566− nd_mapping->labels[0] = select;
1567− nd_mapping->labels[1] = NULL;
1688+ /* move recently validated label to the front of the list */
1689+ list_move(&label_ent->list, &nd_mapping->labels);
15681690 }
15691691 return 0;
15701692 }
15711693
15721694 /**
1573− * find_pmem_label_set - validate interleave set labelling, retrieve label0
1695+ * create_namespace_pmem - validate interleave set labelling, retrieve label0
15741696 * @nd_region: region with mappings to validate
1697+ * @nspm: target namespace to create
1698+ * @nd_label: target pmem namespace label to evaluate
15751699 */
1576−static int find_pmem_label_set(struct nd_region *nd_region,
1577− struct nd_namespace_pmem *nspm)
1700+struct device *create_namespace_pmem(struct nd_region *nd_region,
1701+ struct nd_namespace_label *nd_label)
15781702 {
15791703 u64 cookie = nd_region_interleave_set_cookie(nd_region);
1580− struct nd_namespace_label *nd_label;
1581− u8 select_id[NSLABEL_UUID_LEN];
1704+ struct nd_label_ent *label_ent;
1705+ struct nd_namespace_pmem *nspm;
1706+ struct nd_mapping *nd_mapping;
15821707 resource_size_t size = 0;
1583− u8 *pmem_id = NULL;
1584− int rc = -ENODEV, l;
1708+ struct resource *res;
1709+ struct device *dev;
1710+ int rc = 0;
15851711 u16 i;
15861712
1587− if (cookie == 0)
1588− return -ENXIO;
1713+ if (cookie == 0) {
1714+ dev_dbg(&nd_region->dev, "invalid interleave-set-cookie\n");
1715+ return ERR_PTR(-ENXIO);
1716+ }
15891717
1590− /*
1591− * Find a complete set of labels by uuid. By definition we can start
1592− * with any mapping as the reference label
1593− */
1594− for_each_label(l, nd_label, nd_region->mapping[0].labels) {
1595− u64 isetcookie = __le64_to_cpu(nd_label->isetcookie);
1718+ if (__le64_to_cpu(nd_label->isetcookie) != cookie) {
1719+ dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n",
1720+ nd_label->uuid);
1721+ return ERR_PTR(-EAGAIN);
1722+ }
15961723
1597− if (isetcookie != cookie)
1598− continue;
1724+ nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
1725+ if (!nspm)
1726+ return ERR_PTR(-ENOMEM);
15991727
1600− for (i = 0; nd_region->ndr_mappings; i++)
1601− if (!has_uuid_at_pos(nd_region, nd_label->uuid,
1602− cookie, i))
1603− break;
1604− if (i < nd_region->ndr_mappings) {
1605− /*
1606− * Give up if we don't find an instance of a
1607− * uuid at each position (from 0 to
1608− * nd_region->ndr_mappings - 1), or if we find a
1609− * dimm with two instances of the same uuid.
1610− */
1611− rc = -EINVAL;
1612− goto err;
1613− } else if (pmem_id) {
1614− /*
1615− * If there is more than one valid uuid set, we
1616− * need userspace to clean this up.
1617− */
1618− rc = -EBUSY;
1619− goto err;
1620− }
1621− memcpy(select_id, nd_label->uuid, NSLABEL_UUID_LEN);
1622− pmem_id = select_id;
1728+ nspm->id = -1;
1729+ dev = &nspm->nsio.common.dev;
1730+ dev->type = &namespace_pmem_device_type;
1731+ dev->parent = &nd_region->dev;
1732+ res = &nspm->nsio.res;
1733+ res->name = dev_name(&nd_region->dev);
1734+ res->flags = IORESOURCE_MEM;
1735+
1736+ for (i = 0; i < nd_region->ndr_mappings; i++)
1737+ if (!has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
1738+ break;
1739+ if (i < nd_region->ndr_mappings) {
1740+ struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]);
1741+
1742+ /*
1743+ * Give up if we don't find an instance of a uuid at each
1744+ * position (from 0 to nd_region->ndr_mappings - 1), or if we
1745+ * find a dimm with two instances of the same uuid.
1746+ */
1747+ dev_err(&nd_region->dev, "%s missing label for %pUb\n",
1748+ dev_name(ndd->dev), nd_label->uuid);
1749+ rc = -EINVAL;
1750+ goto err;
16231751 }
16241752
16251753 /*
@@ -1630,14 +1758,23 @@ static int find_pmem_label_set(struct nd_region *nd_region, · 4 unmodified lines
16301758 * the dimm being enabled (i.e. nd_label_reserve_dpa()
16311759 * succeeded).
16321760 */
1633− rc = select_pmem_id(nd_region, pmem_id);
1761+ rc = select_pmem_id(nd_region, nd_label->uuid);
16341762 if (rc)
16351763 goto err;
16361764
16371765 /* Calculate total size and populate namespace properties from label0 */
16381766 for (i = 0; i < nd_region->ndr_mappings; i++) {
1639− struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1640− struct nd_namespace_label *label0 = nd_mapping->labels[0];
1767+ struct nd_namespace_label *label0;
1768+
1769+ nd_mapping = &nd_region->mapping[i];
1770+ label_ent = list_first_entry_or_null(&nd_mapping->labels,
1771+ typeof(*label_ent), list);
1772+ label0 = label_ent ? label_ent->label : 0;
1773+
1774+ if (!label0) {
1775+ WARN_ON(1);
1776+ continue;
1777+ }
16411778
16421779 size += __le64_to_cpu(label0->rawsize);
16431780 if (__le16_to_cpu(label0->position) != 0)
@@ -1654,10 +1791,11 @@ static int find_pmem_label_set(struct nd_region *nd_region, · 10 unmodified lines
16541791 goto err;
16551792 }
16561793
1657− nd_namespace_pmem_set_size(nd_region, nspm, size);
1794+ nd_namespace_pmem_set_resource(nd_region, nspm, size);
16581795
1659− return 0;
1796+ return dev;
16601797 err:
1798+ namespace_pmem_release(dev);
16611799 switch (rc) {
16621800 case -EINVAL:
16631801 dev_dbg(&nd_region->dev, "%s: invalid label(s)\n", __func__);
@@ -1670,55 +1808,7 @@ static int find_pmem_label_set(struct nd_region *nd_region, · 6 unmodified lines
16701808 __func__, rc);
16711809 break;
16721810 }
1673− return rc;
1674−}
1675−
1676−static struct device **create_namespace_pmem(struct nd_region *nd_region)
1677−{
1678− struct nd_namespace_pmem *nspm;
1679− struct device *dev, **devs;
1680− struct resource *res;
1681− int rc;
1682−
1683− nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
1684− if (!nspm)
1685− return NULL;
1686−
1687− dev = &nspm->nsio.common.dev;
1688− dev->type = &namespace_pmem_device_type;
1689− dev->parent = &nd_region->dev;
1690− res = &nspm->nsio.res;
1691− res->name = dev_name(&nd_region->dev);
1692− res->flags = IORESOURCE_MEM;
1693− rc = find_pmem_label_set(nd_region, nspm);
1694− if (rc == -ENODEV) {
1695− int i;
1696−
1697− /* Pass, try to permit namespace creation... */
1698− for (i = 0; i < nd_region->ndr_mappings; i++) {
1699− struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1700−
1701− kfree(nd_mapping->labels);
1702− nd_mapping->labels = NULL;
1703− }
1704−
1705− /* Publish a zero-sized namespace for userspace to configure. */
1706− nd_namespace_pmem_set_size(nd_region, nspm, 0);
1707−
1708− rc = 0;
1709− } else if (rc)
1710− goto err;
1711−
1712− devs = kcalloc(2, sizeof(struct device *), GFP_KERNEL);
1713− if (!devs)
1714− goto err;
1715−
1716− devs[0] = dev;
1717− return devs;
1718−
1719− err:
1720− namespace_pmem_release(&nspm->nsio.common.dev);
1721− return NULL;
1811+ return ERR_PTR(rc);
17221812 }
17231813
17241814 struct resource *nsblk_add_resource(struct nd_region *nd_region,
@@ -1770,16 +1860,58 @@ static struct device *nd_namespace_blk_create(struct nd_region *nd_region) · 45 unmodified lines
17701860 return &nsblk->common.dev;
17711861 }
17721862
1773−void nd_region_create_blk_seed(struct nd_region *nd_region)
1863+static struct device *nd_namespace_pmem_create(struct nd_region *nd_region)
1864+{
1865+ struct nd_namespace_pmem *nspm;
1866+ struct resource *res;
1867+ struct device *dev;
1868+
1869+ if (!is_nd_pmem(&nd_region->dev))
1870+ return NULL;
1871+
1872+ nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
1873+ if (!nspm)
1874+ return NULL;
1875+
1876+ dev = &nspm->nsio.common.dev;
1877+ dev->type = &namespace_pmem_device_type;
1878+ dev->parent = &nd_region->dev;
1879+ res = &nspm->nsio.res;
1880+ res->name = dev_name(&nd_region->dev);
1881+ res->flags = IORESOURCE_MEM;
1882+
1883+ nspm->id = ida_simple_get(&nd_region->ns_ida, 0, 0, GFP_KERNEL);
1884+ if (nspm->id < 0) {
1885+ kfree(nspm);
1886+ return NULL;
1887+ }
1888+ dev_set_name(dev, "namespace%d.%d", nd_region->id, nspm->id);
1889+ dev->parent = &nd_region->dev;
1890+ dev->groups = nd_namespace_attribute_groups;
1891+ nd_namespace_pmem_set_resource(nd_region, nspm, 0);
1892+
1893+ return dev;
1894+}
1895+
1896+void nd_region_create_ns_seed(struct nd_region *nd_region)
17741897 {
17751898 WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev));
1776− nd_region->ns_seed = nd_namespace_blk_create(nd_region);
1899+
1900+ if (nd_region_to_nstype(nd_region) == ND_DEVICE_NAMESPACE_IO)
1901+ return;
1902+
1903+ if (is_nd_blk(&nd_region->dev))
1904+ nd_region->ns_seed = nd_namespace_blk_create(nd_region);
1905+ else
1906+ nd_region->ns_seed = nd_namespace_pmem_create(nd_region);
1907+
17771908 /*
17781909 * Seed creation failures are not fatal, provisioning is simply
17791910 * disabled until memory becomes available
17801911 */
17811912 if (!nd_region->ns_seed)
1782− dev_err(&nd_region->dev, "failed to create blk namespace\n");
1913+ dev_err(&nd_region->dev, "failed to create %s namespace\n",
1914+ is_nd_blk(&nd_region->dev) ? "blk" : "pmem");
17831915 else
17841916 nd_device_register(nd_region->ns_seed);
17851917 }
@@ -1820,43 +1952,137 @@ void nd_region_create_btt_seed(struct nd_region *nd_region) · 34 unmodified lines
18201952 dev_err(&nd_region->dev, "failed to create btt namespace\n");
18211953 }
18221954
1823−static struct device **create_namespace_blk(struct nd_region *nd_region)
1955+static int add_namespace_resource(struct nd_region *nd_region,
1956+ struct nd_namespace_label *nd_label, struct device **devs,
1957+ int count)
18241958 {
18251959 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1826− struct nd_namespace_label *nd_label;
1827− struct device *dev, **devs = NULL;
1960+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1961+ int i;
1962+
1963+ for (i = 0; i < count; i++) {
1964+ u8 *uuid = namespace_to_uuid(devs[i]);
1965+ struct resource *res;
1966+
1967+ if (IS_ERR_OR_NULL(uuid)) {
1968+ WARN_ON(1);
1969+ continue;
1970+ }
1971+
1972+ if (memcmp(uuid, nd_label->uuid, NSLABEL_UUID_LEN) != 0)
1973+ continue;
1974+ if (is_namespace_blk(devs[i])) {
1975+ res = nsblk_add_resource(nd_region, ndd,
1976+ to_nd_namespace_blk(devs[i]),
1977+ __le64_to_cpu(nd_label->dpa));
1978+ if (!res)
1979+ return -ENXIO;
1980+ nd_dbg_dpa(nd_region, ndd, res, "%d assign\n", count);
1981+ } else {
1982+ dev_err(&nd_region->dev,
1983+ "error: conflicting extents for uuid: %pUb\n",
1984+ nd_label->uuid);
1985+ return -ENXIO;
1986+ }
1987+ break;
1988+ }
1989+
1990+ return i;
1991+}
1992+
1993+struct device *create_namespace_blk(struct nd_region *nd_region,
1994+ struct nd_namespace_label *nd_label, int count)
1995+{
1996+
1997+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1998+ struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
18281999 struct nd_namespace_blk *nsblk;
1829− struct nvdimm_drvdata *ndd;
1830− int i, l, count = 0;
2000+ char *name[NSLABEL_NAME_LEN];
2001+ struct device *dev = NULL;
18312002 struct resource *res;
18322003
1833− if (nd_region->ndr_mappings == 0)
1834− return NULL;
2004+ nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
2005+ if (!nsblk)
2006+ return ERR_PTR(-ENOMEM);
2007+ dev = &nsblk->common.dev;
2008+ dev->type = &namespace_blk_device_type;
2009+ dev->parent = &nd_region->dev;
2010+ nsblk->id = -1;
2011+ nsblk->lbasize = __le64_to_cpu(nd_label->lbasize);
2012+ nsblk->uuid = kmemdup(nd_label->uuid, NSLABEL_UUID_LEN,
2013+ GFP_KERNEL);
2014+ if (!nsblk->uuid)
2015+ goto blk_err;
2016+ memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
2017+ if (name[0])
2018+ nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN,
2019+ GFP_KERNEL);
2020+ res = nsblk_add_resource(nd_region, ndd, nsblk,
2021+ __le64_to_cpu(nd_label->dpa));
2022+ if (!res)
2023+ goto blk_err;
2024+ nd_dbg_dpa(nd_region, ndd, res, "%d: assign\n", count);
2025+ return dev;
2026+ blk_err:
2027+ namespace_blk_release(dev);
2028+ return ERR_PTR(-ENXIO);
2029+}
2030+
2031+static int cmp_dpa(const void *a, const void *b)
2032+{
2033+ const struct device *dev_a = *(const struct device **) a;
2034+ const struct device *dev_b = *(const struct device **) b;
2035+ struct nd_namespace_blk *nsblk_a, *nsblk_b;
2036+ struct nd_namespace_pmem *nspm_a, *nspm_b;
2037+
2038+ if (is_namespace_io(dev_a))
2039+ return 0;
2040+
2041+ if (is_namespace_blk(dev_a)) {
2042+ nsblk_a = to_nd_namespace_blk(dev_a);
2043+ nsblk_b = to_nd_namespace_blk(dev_b);
2044+
2045+ return memcmp(&nsblk_a->res[0]->start, &nsblk_b->res[0]->start,
2046+ sizeof(resource_size_t));
2047+ }
2048+
2049+ nspm_a = to_nd_namespace_pmem(dev_a);
2050+ nspm_b = to_nd_namespace_pmem(dev_b);
2051+
2052+ return memcmp(&nspm_a->nsio.res.start, &nspm_b->nsio.res.start,
2053+ sizeof(resource_size_t));
2054+}
18352055
1836− ndd = to_ndd(nd_mapping);
1837− for_each_label(l, nd_label, nd_mapping->labels) {
1838− u32 flags = __le32_to_cpu(nd_label->flags);
1839− char *name[NSLABEL_NAME_LEN];
2056+static struct device **scan_labels(struct nd_region *nd_region)
2057+{
2058+ int i, count = 0;
2059+ struct device *dev, **devs = NULL;
2060+ struct nd_label_ent *label_ent, *e;
2061+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
2062+ resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1;
2063+
2064+ /* "safe" because create_namespace_pmem() might list_move() label_ent */
2065+ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
2066+ struct nd_namespace_label *nd_label = label_ent->label;
18402067 struct device **__devs;
2068+ u32 flags;
18412069
1842− if (flags & NSLABEL_FLAG_LOCAL)
1843− /* pass */;
2070+ if (!nd_label)
2071+ continue;
2072+ flags = __le32_to_cpu(nd_label->flags);
2073+ if (is_nd_blk(&nd_region->dev)
2074+ == !!(flags & NSLABEL_FLAG_LOCAL))
2075+ /* pass, region matches label type */;
18442076 else
18452077 continue;
18462078
1847− for (i = 0; i < count; i++) {
1848− nsblk = to_nd_namespace_blk(devs[i]);
1849− if (memcmp(nsblk->uuid, nd_label->uuid,
1850− NSLABEL_UUID_LEN) == 0) {
1851− res = nsblk_add_resource(nd_region, ndd, nsblk,
1852− __le64_to_cpu(nd_label->dpa));
1853− if (!res)
1854− goto err;
1855− nd_dbg_dpa(nd_region, ndd, res, "%s assign\n",
1856− dev_name(&nsblk->common.dev));
1857− break;
1858− }
1859− }
2079+ /* skip labels that describe extents outside of the region */
2080+ if (nd_label->dpa < nd_mapping->start || nd_label->dpa > map_end)
2081+ continue;
2082+
2083+ i = add_namespace_resource(nd_region, nd_label, devs, count);
2084+ if (i < 0)
2085+ goto err;
18602086 if (i < count)
18612087 continue;
18622088 __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
@@ -1866,67 +2092,126 @@ static struct device **create_namespace_blk(struct nd_region *nd_region) · 3 unmodified lines
18662092 kfree(devs);
18672093 devs = __devs;
18682094
1869− nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
1870− if (!nsblk)
1871− goto err;
1872− dev = &nsblk->common.dev;
1873− dev->type = &namespace_blk_device_type;
1874− dev->parent = &nd_region->dev;
1875− dev_set_name(dev, "namespace%d.%d", nd_region->id, count);
1876− devs[count++] = dev;
1877− nsblk->id = -1;
1878− nsblk->lbasize = __le64_to_cpu(nd_label->lbasize);
1879− nsblk->uuid = kmemdup(nd_label->uuid, NSLABEL_UUID_LEN,
1880− GFP_KERNEL);
1881− if (!nsblk->uuid)
1882− goto err;
1883− memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
1884− if (name[0])
1885− nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN,
1886− GFP_KERNEL);
1887− res = nsblk_add_resource(nd_region, ndd, nsblk,
1888− __le64_to_cpu(nd_label->dpa));
1889− if (!res)
1890− goto err;
1891− nd_dbg_dpa(nd_region, ndd, res, "%s assign\n",
1892− dev_name(&nsblk->common.dev));
2095+ if (is_nd_blk(&nd_region->dev)) {
2096+ dev = create_namespace_blk(nd_region, nd_label, count);
2097+ if (IS_ERR(dev))
2098+ goto err;
2099+ devs[count++] = dev;
2100+ } else {
2101+ dev = create_namespace_pmem(nd_region, nd_label);
2102+ if (IS_ERR(dev)) {
2103+ switch (PTR_ERR(dev)) {
2104+ case -EAGAIN:
2105+ /* skip invalid labels */
2106+ continue;
2107+ case -ENODEV:
2108+ /* fallthrough to seed creation */
2109+ break;
2110+ default:
2111+ goto err;
2112+ }
2113+ } else
2114+ devs[count++] = dev;
2115+ }
18932116 }
18942117
1895− dev_dbg(&nd_region->dev, "%s: discovered %d blk namespace%s\n",
1896− __func__, count, count == 1 ? "" : "s");
2118+ dev_dbg(&nd_region->dev, "%s: discovered %d %s namespace%s\n",
2119+ __func__, count, is_nd_blk(&nd_region->dev)
2120+ ? "blk" : "pmem", count == 1 ? "" : "s");
18972121
18982122 if (count == 0) {
18992123 /* Publish a zero-sized namespace for userspace to configure. */
1900− for (i = 0; i < nd_region->ndr_mappings; i++) {
1901− struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1902−
1903− kfree(nd_mapping->labels);
1904− nd_mapping->labels = NULL;
1905− }
2124+ nd_mapping_free_labels(nd_mapping);
19062125
19072126 devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
19082127 if (!devs)
19092128 goto err;
1910− nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
1911− if (!nsblk)
1912− goto err;
1913− dev = &nsblk->common.dev;
1914− dev->type = &namespace_blk_device_type;
2129+ if (is_nd_blk(&nd_region->dev)) {
2130+ struct nd_namespace_blk *nsblk;
2131+
2132+ nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
2133+ if (!nsblk)
2134+ goto err;
2135+ dev = &nsblk->common.dev;
2136+ dev->type = &namespace_blk_device_type;
2137+ } else {
2138+ struct nd_namespace_pmem *nspm;
2139+
2140+ nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
2141+ if (!nspm)
2142+ goto err;
2143+ dev = &nspm->nsio.common.dev;
2144+ dev->type = &namespace_pmem_device_type;
2145+ nd_namespace_pmem_set_resource(nd_region, nspm, 0);
2146+ }
19152147 dev->parent = &nd_region->dev;
19162148 devs[count++] = dev;
2149+ } else if (is_nd_pmem(&nd_region->dev)) {
2150+ /* clean unselected labels */
2151+ for (i = 0; i < nd_region->ndr_mappings; i++) {
2152+ struct list_head *l, *e;
2153+ LIST_HEAD(list);
2154+ int j;
2155+
2156+ nd_mapping = &nd_region->mapping[i];
2157+ if (list_empty(&nd_mapping->labels)) {
2158+ WARN_ON(1);
2159+ continue;
2160+ }
2161+
2162+ j = count;
2163+ list_for_each_safe(l, e, &nd_mapping->labels) {
2164+ if (!j--)
2165+ break;
2166+ list_move_tail(l, &list);
2167+ }
2168+ nd_mapping_free_labels(nd_mapping);
2169+ list_splice_init(&list, &nd_mapping->labels);
2170+ }
19172171 }
19182172
2173+ if (count > 1)
2174+ sort(devs, count, sizeof(struct device *), cmp_dpa, NULL);
2175+
19192176 return devs;
19202177
1921−err:
1922− for (i = 0; i < count; i++) {
1923− nsblk = to_nd_namespace_blk(devs[i]);
1924− namespace_blk_release(&nsblk->common.dev);
1925− }
2178+ err:
2179+ for (i = 0; devs[i]; i++)
2180+ if (is_nd_blk(&nd_region->dev))
2181+ namespace_blk_release(devs[i]);
2182+ else
2183+ namespace_pmem_release(devs[i]);
19262184 kfree(devs);
19272185 return NULL;
19282186 }
19292187
2188+static struct device **create_namespaces(struct nd_region *nd_region)
2189+{
2190+ struct nd_mapping *nd_mapping = &nd_region->mapping[0];
2191+ struct device **devs;
2192+ int i;
2193+
2194+ if (nd_region->ndr_mappings == 0)
2195+ return NULL;
2196+
2197+ /* lock down all mappings while we scan labels */
2198+ for (i = 0; i < nd_region->ndr_mappings; i++) {
2199+ nd_mapping = &nd_region->mapping[i];
2200+ mutex_lock_nested(&nd_mapping->lock, i);
2201+ }
2202+
2203+ devs = scan_labels(nd_region);
2204+
2205+ for (i = 0; i < nd_region->ndr_mappings; i++) {
2206+ int reverse = nd_region->ndr_mappings - 1 - i;
2207+
2208+ nd_mapping = &nd_region->mapping[reverse];
2209+ mutex_unlock(&nd_mapping->lock);
2210+ }
2211+
2212+ return devs;
2213+}
2214+
19302215 static int init_active_labels(struct nd_region *nd_region)
19312216 {
19322217 int i;
@@ -1935,6 +2220,7 @@ static int init_active_labels(struct nd_region *nd_region) · 2 unmodified lines
19352220 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
19362221 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
19372222 struct nvdimm *nvdimm = nd_mapping->nvdimm;
2223+ struct nd_label_ent *label_ent;
19382224 int count, j;
19392225
19402226 /*
@@ -1956,16 +2242,27 @@ static int init_active_labels(struct nd_region *nd_region) · 15 unmodified lines
19562242 dev_dbg(ndd->dev, "%s: %d\n", __func__, count);
19572243 if (!count)
19582244 continue;
1959− nd_mapping->labels = kcalloc(count + 1, sizeof(void *),
1960− GFP_KERNEL);
1961− if (!nd_mapping->labels)
1962− return -ENOMEM;
19632245 for (j = 0; j < count; j++) {
19642246 struct nd_namespace_label *label;
19652247
2248+ label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
2249+ if (!label_ent)
2250+ break;
19662251 label = nd_label_active(ndd, j);
1967− nd_mapping->labels[j] = label;
2252+ label_ent->label = label;
2253+
2254+ mutex_lock(&nd_mapping->lock);
2255+ list_add_tail(&label_ent->list, &nd_mapping->labels);
2256+ mutex_unlock(&nd_mapping->lock);
19682257 }
2258+
2259+ if (j >= count)
2260+ continue;
2261+
2262+ mutex_lock(&nd_mapping->lock);
2263+ nd_mapping_free_labels(nd_mapping);
2264+ mutex_unlock(&nd_mapping->lock);
2265+ return -ENOMEM;
19692266 }
19702267
19712268 return 0;
@@ -1990,10 +2287,8 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err) · 18 unmodified lines
19902287 devs = create_namespace_io(nd_region);
19912288 break;
19922289 case ND_DEVICE_NAMESPACE_PMEM:
1993− devs = create_namespace_pmem(nd_region);
1994− break;
19952290 case ND_DEVICE_NAMESPACE_BLK:
1996− devs = create_namespace_blk(nd_region);
2291+ devs = create_namespaces(nd_region);
19972292 break;
19982293 default:
19992294 break;
@@ -2014,6 +2309,13 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err) · 14 unmodified lines
20142309 id = ida_simple_get(&nd_region->ns_ida, 0, 0,
20152310 GFP_KERNEL);
20162311 nsblk->id = id;
2312+ } else if (type == ND_DEVICE_NAMESPACE_PMEM) {
2313+ struct nd_namespace_pmem *nspm;
2314+
2315+ nspm = to_nd_namespace_pmem(dev);
2316+ id = ida_simple_get(&nd_region->ns_ida, 0, 0,
2317+ GFP_KERNEL);
2318+ nspm->id = id;
20172319 } else
20182320 id = i;
20192321
drivers/nvdimm/nd-core.h+21−3
@@ -44,6 +44,23 @@ struct nvdimm { · 43 unmodified lines
4444 struct resource *flush_wpq;
4545 };
4646
47+/**
48+ * struct blk_alloc_info - tracking info for BLK dpa scanning
49+ * @nd_mapping: blk region mapping boundaries
50+ * @available: decremented in alias_dpa_busy as aliased PMEM is scanned
51+ * @busy: decremented in blk_dpa_busy to account for ranges already
52+ * handled by alias_dpa_busy
53+ * @res: alias_dpa_busy interprets this a free space range that needs to
54+ * be truncated to the valid BLK allocation starting DPA, blk_dpa_busy
55+ * treats it as a busy range that needs the aliased PMEM ranges
56+ * truncated.
57+ */
58+struct blk_alloc_info {
59+ struct nd_mapping *nd_mapping;
60+ resource_size_t available, busy;
61+ struct resource *res;
62+};
63+
4764 bool is_nvdimm(struct device *dev);
4865 bool is_nd_pmem(struct device *dev);
4966 bool is_nd_blk(struct device *dev);
@@ -54,7 +71,7 @@ void nvdimm_devs_exit(void); · 4 unmodified lines
5471 void nd_region_devs_exit(void);
5572 void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev);
5673 struct nd_region;
57−void nd_region_create_blk_seed(struct nd_region *nd_region);
74+void nd_region_create_ns_seed(struct nd_region *nd_region);
5875 void nd_region_create_btt_seed(struct nd_region *nd_region);
5976 void nd_region_create_pfn_seed(struct nd_region *nd_region);
6077 void nd_region_create_dax_seed(struct nd_region *nd_region);
@@ -73,13 +90,14 @@ bool nd_is_uuid_unique(struct device *dev, u8 *uuid); · 12 unmodified lines
7390 struct nd_region;
7491 struct nvdimm_drvdata;
7592 struct nd_mapping;
93+void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
7694 resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
7795 struct nd_mapping *nd_mapping, resource_size_t *overlap);
78−resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping);
96+resource_size_t nd_blk_available_dpa(struct nd_region *nd_region);
7997 resource_size_t nd_region_available_dpa(struct nd_region *nd_region);
8098 resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
8199 struct nd_label_id *label_id);
82−struct nd_mapping;
100+int alias_dpa_busy(struct device *dev, void *data);
83101 struct resource *nsblk_add_resource(struct nd_region *nd_region,
84102 struct nvdimm_drvdata *ndd, struct nd_namespace_blk *nsblk,
85103 resource_size_t start);
drivers/nvdimm/nd.h+26−3
@@ -101,9 +101,6 @@ static inline struct nd_namespace_index *to_next_namespace_index( · 100 unmodified lines
101101 (unsigned long long) (res ? resource_size(res) : 0), \
102102 (unsigned long long) (res ? res->start : 0), ##arg)
103103
104−#define for_each_label(l, label, labels) \
105− for (l = 0; (label = labels ? labels[l] : NULL); l++)
106−
107104 #define for_each_dpa_resource(ndd, res) \
108105 for (res = (ndd)->dpa.child; res; res = res->sibling)
109106
@@ -116,6 +113,31 @@ struct nd_percpu_lane { · 6 unmodified lines
116113 spinlock_t lock;
117114 };
118115
116+struct nd_label_ent {
117+ struct list_head list;
118+ struct nd_namespace_label *label;
119+};
120+
121+enum nd_mapping_lock_class {
122+ ND_MAPPING_CLASS0,
123+ ND_MAPPING_UUID_SCAN,
124+};
125+
126+struct nd_mapping {
127+ struct nvdimm *nvdimm;
128+ u64 start;
129+ u64 size;
130+ struct list_head labels;
131+ struct mutex lock;
132+ /*
133+ * @ndd is for private use at region enable / disable time for
134+ * get_ndd() + put_ndd(), all other nd_mapping to ndd
135+ * conversions use to_ndd() which respects enabled state of the
136+ * nvdimm.
137+ */
138+ struct nvdimm_drvdata *ndd;
139+};
140+
119141 struct nd_region {
120142 struct device dev;
121143 struct ida ns_ida;
@@ -209,6 +231,7 @@ void nvdimm_exit(void); · 87 unmodified lines
209231 void nd_region_exit(void);
210232 struct nvdimm;
211233 struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping);
234+int nvdimm_check_config_data(struct device *dev);
212235 int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd);
213236 int nvdimm_init_config_data(struct nvdimm_drvdata *ndd);
214237 int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
drivers/nvdimm/pmem.c+23−5
@@ -66,13 +66,32 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, · 65 unmodified lines
6666 invalidate_pmem(pmem->virt_addr + offset, len);
6767 }
6868
69+static void write_pmem(void *pmem_addr, struct page *page,
70+ unsigned int off, unsigned int len)
71+{
72+ void *mem = kmap_atomic(page);
73+
74+ memcpy_to_pmem(pmem_addr, mem + off, len);
75+ kunmap_atomic(mem);
76+}
77+
78+static int read_pmem(struct page *page, unsigned int off,
79+ void *pmem_addr, unsigned int len)
80+{
81+ int rc;
82+ void *mem = kmap_atomic(page);
83+
84+ rc = memcpy_from_pmem(mem + off, pmem_addr, len);
85+ kunmap_atomic(mem);
86+ return rc;
87+}
88+
6989 static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
7090 unsigned int len, unsigned int off, bool is_write,
7191 sector_t sector)
7292 {
7393 int rc = 0;
7494 bool bad_pmem = false;
75− void *mem = kmap_atomic(page);
7695 phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
7796 void *pmem_addr = pmem->virt_addr + pmem_off;
7897
@@ -83,7 +102,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, · 4 unmodified lines
83102 if (unlikely(bad_pmem))
84103 rc = -EIO;
85104 else {
86− rc = memcpy_from_pmem(mem + off, pmem_addr, len);
105+ rc = read_pmem(page, off, pmem_addr, len);
87106 flush_dcache_page(page);
88107 }
89108 } else {
@@ -102,14 +121,13 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, · 12 unmodified lines
102121 * after clear poison.
103122 */
104123 flush_dcache_page(page);
105− memcpy_to_pmem(pmem_addr, mem + off, len);
124+ write_pmem(pmem_addr, page, off, len);
106125 if (unlikely(bad_pmem)) {
107126 pmem_clear_poison(pmem, pmem_off, len);
108− memcpy_to_pmem(pmem_addr, mem + off, len);
127+ write_pmem(pmem_addr, page, off, len);
109128 }
110129 }
111130
112− kunmap_atomic(mem);
113131 return rc;
114132 }
115133
drivers/nvdimm/region_devs.c+41−17
@@ -313,9 +313,8 @@ resource_size_t nd_region_available_dpa(struct nd_region *nd_region) · 312 unmodified lines
313313 blk_max_overlap = overlap;
314314 goto retry;
315315 }
316− } else if (is_nd_blk(&nd_region->dev)) {
317− available += nd_blk_available_dpa(nd_mapping);
318− }
316+ } else if (is_nd_blk(&nd_region->dev))
317+ available += nd_blk_available_dpa(nd_region);
319318 }
320319
321320 return available;
@@ -506,6 +505,17 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region) · 184 unmodified lines
506505 return 0;
507506 }
508507
508+void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
509+{
510+ struct nd_label_ent *label_ent, *e;
511+
512+ WARN_ON(!mutex_is_locked(&nd_mapping->lock));
513+ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
514+ list_del(&label_ent->list);
515+ kfree(label_ent);
516+ }
517+}
518+
509519 /*
510520 * Upon successful probe/remove, take/release a reference on the
511521 * associated interleave set (if present), and plant new btt + namespace
@@ -526,8 +536,10 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, · 14 unmodified lines
526536 struct nvdimm_drvdata *ndd = nd_mapping->ndd;
527537 struct nvdimm *nvdimm = nd_mapping->nvdimm;
528538
529− kfree(nd_mapping->labels);
530− nd_mapping->labels = NULL;
539+ mutex_lock(&nd_mapping->lock);
540+ nd_mapping_free_labels(nd_mapping);
541+ mutex_unlock(&nd_mapping->lock);
542+
531543 put_ndd(ndd);
532544 nd_mapping->ndd = NULL;
533545 if (ndd)
@@ -537,11 +549,12 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, · 3 unmodified lines
537549 if (is_nd_pmem(dev))
538550 return;
539551 }
540− if (dev->parent && is_nd_blk(dev->parent) && probe) {
552+ if (dev->parent && (is_nd_blk(dev->parent) || is_nd_pmem(dev->parent))
553+ && probe) {
541554 nd_region = to_nd_region(dev->parent);
542555 nvdimm_bus_lock(dev);
543556 if (nd_region->ns_seed == dev)
544− nd_region_create_blk_seed(nd_region);
557+ nd_region_create_ns_seed(nd_region);
545558 nvdimm_bus_unlock(dev);
546559 }
547560 if (is_nd_btt(dev) && probe) {
@@ -551,23 +564,30 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, · 3 unmodified lines
551564 nvdimm_bus_lock(dev);
552565 if (nd_region->btt_seed == dev)
553566 nd_region_create_btt_seed(nd_region);
554− if (nd_region->ns_seed == &nd_btt->ndns->dev &&
555− is_nd_blk(dev->parent))
556− nd_region_create_blk_seed(nd_region);
567+ if (nd_region->ns_seed == &nd_btt->ndns->dev)
568+ nd_region_create_ns_seed(nd_region);
557569 nvdimm_bus_unlock(dev);
558570 }
559571 if (is_nd_pfn(dev) && probe) {
572+ struct nd_pfn *nd_pfn = to_nd_pfn(dev);
573+
560574 nd_region = to_nd_region(dev->parent);
561575 nvdimm_bus_lock(dev);
562576 if (nd_region->pfn_seed == dev)
563577 nd_region_create_pfn_seed(nd_region);
578+ if (nd_region->ns_seed == &nd_pfn->ndns->dev)
579+ nd_region_create_ns_seed(nd_region);
564580 nvdimm_bus_unlock(dev);
565581 }
566582 if (is_nd_dax(dev) && probe) {
583+ struct nd_dax *nd_dax = to_nd_dax(dev);
584+
567585 nd_region = to_nd_region(dev->parent);
568586 nvdimm_bus_lock(dev);
569587 if (nd_region->dax_seed == dev)
570588 nd_region_create_dax_seed(nd_region);
589+ if (nd_region->ns_seed == &nd_dax->nd_pfn.ndns->dev)
590+ nd_region_create_ns_seed(nd_region);
571591 nvdimm_bus_unlock(dev);
572592 }
573593 }
@@ -774,10 +794,10 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, · 200 unmodified lines
774794 int ro = 0;
775795
776796 for (i = 0; i < ndr_desc->num_mappings; i++) {
777− struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i];
778− struct nvdimm *nvdimm = nd_mapping->nvdimm;
797+ struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
798+ struct nvdimm *nvdimm = mapping->nvdimm;
779799
780− if ((nd_mapping->start | nd_mapping->size) % SZ_4K) {
800+ if ((mapping->start | mapping->size) % SZ_4K) {
781801 dev_err(&nvdimm_bus->dev, "%s: %s mapping%d is not 4K aligned\n",
782802 caller, dev_name(&nvdimm->dev), i);
783803
@@ -828,11 +848,15 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, · 44 unmodified lines
828848 ndl->count = 0;
829849 }
830850
831− memcpy(nd_region->mapping, ndr_desc->nd_mapping,
832− sizeof(struct nd_mapping) * ndr_desc->num_mappings);
833851 for (i = 0; i < ndr_desc->num_mappings; i++) {
834− struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i];
835− struct nvdimm *nvdimm = nd_mapping->nvdimm;
852+ struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
853+ struct nvdimm *nvdimm = mapping->nvdimm;
854+
855+ nd_region->mapping[i].nvdimm = nvdimm;
856+ nd_region->mapping[i].start = mapping->start;
857+ nd_region->mapping[i].size = mapping->size;
858+ INIT_LIST_HEAD(&nd_region->mapping[i].labels);
859+ mutex_init(&nd_region->mapping[i].lock);
836860
837861 get_device(&nvdimm->dev);
838862 }
include/linux/libnvdimm.h+10−18
@@ -50,23 +50,6 @@ typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc, · 49 unmodified lines
5050 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
5151 unsigned int buf_len, int *cmd_rc);
5252
53−struct nd_namespace_label;
54−struct nvdimm_drvdata;
55−
56−struct nd_mapping {
57− struct nvdimm *nvdimm;
58− struct nd_namespace_label **labels;
59− u64 start;
60− u64 size;
61− /*
62− * @ndd is for private use at region enable / disable time for
63− * get_ndd() + put_ndd(), all other nd_mapping to ndd
64− * conversions use to_ndd() which respects enabled state of the
65− * nvdimm.
66− */
67− struct nvdimm_drvdata *ndd;
68−};
69−
7053 struct nvdimm_bus_descriptor {
7154 const struct attribute_group **attr_groups;
7255 unsigned long cmd_mask;
@@ -89,9 +72,15 @@ struct nd_interleave_set { · 16 unmodified lines
8972 u64 cookie;
9073 };
9174
75+struct nd_mapping_desc {
76+ struct nvdimm *nvdimm;
77+ u64 start;
78+ u64 size;
79+};
80+
9281 struct nd_region_desc {
9382 struct resource *res;
94− struct nd_mapping *nd_mapping;
83+ struct nd_mapping_desc *mapping;
9584 u16 num_mappings;
9685 const struct attribute_group **attr_groups;
9786 struct nd_interleave_set *nd_set;
@@ -129,6 +118,8 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( · 31 unmodified lines
129118 }
130119
131120 int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
121+void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
122+ phys_addr_t start, unsigned int len);
132123 struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
133124 struct nvdimm_bus_descriptor *nfit_desc);
134125 void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
@@ -139,6 +130,7 @@ struct nd_blk_region *to_nd_blk_region(struct device *dev); · 4 unmodified lines
139130 struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus);
140131 struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus);
141132 const char *nvdimm_name(struct nvdimm *nvdimm);
133+struct kobject *nvdimm_kobj(struct nvdimm *nvdimm);
142134 unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm);
143135 void *nvdimm_provider_data(struct nvdimm *nvdimm);
144136 struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
include/linux/nd.h+5−3
@@ -77,11 +77,13 @@ struct nd_namespace_io { · 76 unmodified lines
7777 * @nsio: device and system physical address range to drive
7878 * @alt_name: namespace name supplied in the dimm label
7979 * @uuid: namespace name supplied in the dimm label
80+ * @id: ida allocated id
8081 */
8182 struct nd_namespace_pmem {
8283 struct nd_namespace_io nsio;
8384 char *alt_name;
8485 u8 *uuid;
86+ int id;
8587 };
8688
8789 /**
@@ -105,19 +107,19 @@ struct nd_namespace_blk { · 17 unmodified lines
105107 struct resource **res;
106108 };
107109
108−static inline struct nd_namespace_io *to_nd_namespace_io(struct device *dev)
110+static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev)
109111 {
110112 return container_of(dev, struct nd_namespace_io, common.dev);
111113 }
112114
113−static inline struct nd_namespace_pmem *to_nd_namespace_pmem(struct device *dev)
115+static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev)
114116 {
115117 struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
116118
117119 return container_of(nsio, struct nd_namespace_pmem, nsio);
118120 }
119121
120−static inline struct nd_namespace_blk *to_nd_namespace_blk(struct device *dev)
122+static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev)
121123 {
122124 return container_of(dev, struct nd_namespace_blk, common.dev);
123125 }
include/uapi/linux/ndctl.h+17−13
@@ -21,14 +21,16 @@ struct nd_cmd_smart { · 20 unmodified lines
2121 } __packed;
2222
2323 #define ND_SMART_HEALTH_VALID (1 << 0)
24−#define ND_SMART_TEMP_VALID (1 << 1)
25−#define ND_SMART_SPARES_VALID (1 << 2)
26−#define ND_SMART_ALARM_VALID (1 << 3)
27−#define ND_SMART_USED_VALID (1 << 4)
28−#define ND_SMART_SHUTDOWN_VALID (1 << 5)
29−#define ND_SMART_VENDOR_VALID (1 << 6)
30−#define ND_SMART_TEMP_TRIP (1 << 0)
31−#define ND_SMART_SPARE_TRIP (1 << 1)
24+#define ND_SMART_SPARES_VALID (1 << 1)
25+#define ND_SMART_USED_VALID (1 << 2)
26+#define ND_SMART_TEMP_VALID (1 << 3)
27+#define ND_SMART_CTEMP_VALID (1 << 4)
28+#define ND_SMART_ALARM_VALID (1 << 9)
29+#define ND_SMART_SHUTDOWN_VALID (1 << 10)
30+#define ND_SMART_VENDOR_VALID (1 << 11)
31+#define ND_SMART_SPARE_TRIP (1 << 0)
32+#define ND_SMART_TEMP_TRIP (1 << 1)
33+#define ND_SMART_CTEMP_TRIP (1 << 2)
3234 #define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
3335 #define ND_SMART_CRITICAL_HEALTH (1 << 1)
3436 #define ND_SMART_FATAL_HEALTH (1 << 2)
@@ -37,14 +39,15 @@ struct nd_smart_payload { · 2 unmodified lines
3739 __u32 flags;
3840 __u8 reserved0[4];
3941 __u8 health;
40− __u16 temperature;
4142 __u8 spares;
42− __u8 alarm_flags;
4343 __u8 life_used;
44+ __u8 alarm_flags;
45+ __u16 temperature;
46+ __u16 ctrl_temperature;
47+ __u8 reserved1[15];
4448 __u8 shutdown_state;
45− __u8 reserved1;
4649 __u32 vendor_size;
47− __u8 vendor_data[108];
50+ __u8 vendor_data[92];
4851 } __packed;
4952
5053 struct nd_cmd_smart_threshold {
@@ -53,7 +56,8 @@ struct nd_cmd_smart_threshold { · 2 unmodified lines
5356 } __packed;
5457
5558 struct nd_smart_threshold_payload {
56− __u16 alarm_control;
59+ __u8 alarm_control;
60+ __u8 reserved0;
5761 __u16 temperature;
5862 __u8 spares;
5963 __u8 reserved[3];
tools/testing/nvdimm/Kbuild+1−0
@@ -13,6 +13,7 @@ ldflags-y += --wrap=__release_region · 12 unmodified lines
1313 ldflags-y += --wrap=devm_memremap_pages
1414 ldflags-y += --wrap=insert_resource
1515 ldflags-y += --wrap=remove_resource
16+ldflags-y += --wrap=acpi_evaluate_object
1617
1718 DRIVERS := ../../../drivers
1819 NVDIMM_SRC := $(DRIVERS)/nvdimm
tools/testing/nvdimm/test/iomap.c+121−30
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <linux/module.h>
1818 #include <linux/types.h>
1919 #include <linux/pfn_t.h>
20+#include <linux/acpi.h>
2021 #include <linux/io.h>
2122 #include <linux/mm.h>
2223 #include "nfit_test.h"
@@ -73,7 +74,7 @@ void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, · 50 unmodified lines
7374
7475 if (nfit_res)
7576 return (void __iomem *) nfit_res->buf + offset
76− - nfit_res->res->start;
77+ - nfit_res->res.start;
7778 return fallback_fn(offset, size);
7879 }
7980
@@ -84,7 +85,7 @@ void __iomem *__wrap_devm_ioremap_nocache(struct device *dev, · 4 unmodified lines
8485
8586 if (nfit_res)
8687 return (void __iomem *) nfit_res->buf + offset
87− - nfit_res->res->start;
88+ - nfit_res->res.start;
8889 return devm_ioremap_nocache(dev, offset, size);
8990 }
9091 EXPORT_SYMBOL(__wrap_devm_ioremap_nocache);
@@ -95,7 +96,7 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset, · 4 unmodified lines
9596 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
9697
9798 if (nfit_res)
98− return nfit_res->buf + offset - nfit_res->res->start;
99+ return nfit_res->buf + offset - nfit_res->res.start;
99100 return devm_memremap(dev, offset, size, flags);
100101 }
101102 EXPORT_SYMBOL(__wrap_devm_memremap);
@@ -107,7 +108,7 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res, · 5 unmodified lines
107108 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
108109
109110 if (nfit_res)
110− return nfit_res->buf + offset - nfit_res->res->start;
111+ return nfit_res->buf + offset - nfit_res->res.start;
111112 return devm_memremap_pages(dev, res, ref, altmap);
112113 }
113114 EXPORT_SYMBOL(__wrap_devm_memremap_pages);
@@ -128,7 +129,7 @@ void *__wrap_memremap(resource_size_t offset, size_t size, · 14 unmodified lines
128129 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
129130
130131 if (nfit_res)
131− return nfit_res->buf + offset - nfit_res->res->start;
132+ return nfit_res->buf + offset - nfit_res->res.start;
132133 return memremap(offset, size, flags);
133134 }
134135 EXPORT_SYMBOL(__wrap_memremap);
@@ -174,6 +175,63 @@ void __wrap_memunmap(void *addr) · 39 unmodified lines
174175 }
175176 EXPORT_SYMBOL(__wrap_memunmap);
176177
178+static bool nfit_test_release_region(struct device *dev,
179+ struct resource *parent, resource_size_t start,
180+ resource_size_t n);
181+
182+static void nfit_devres_release(struct device *dev, void *data)
183+{
184+ struct resource *res = *((struct resource **) data);
185+
186+ WARN_ON(!nfit_test_release_region(NULL, &iomem_resource, res->start,
187+ resource_size(res)));
188+}
189+
190+static int match(struct device *dev, void *__res, void *match_data)
191+{
192+ struct resource *res = *((struct resource **) __res);
193+ resource_size_t start = *((resource_size_t *) match_data);
194+
195+ return res->start == start;
196+}
197+
198+static bool nfit_test_release_region(struct device *dev,
199+ struct resource *parent, resource_size_t start,
200+ resource_size_t n)
201+{
202+ if (parent == &iomem_resource) {
203+ struct nfit_test_resource *nfit_res = get_nfit_res(start);
204+
205+ if (nfit_res) {
206+ struct nfit_test_request *req;
207+ struct resource *res = NULL;
208+
209+ if (dev) {
210+ devres_release(dev, nfit_devres_release, match,
211+ &start);
212+ return true;
213+ }
214+
215+ spin_lock(&nfit_res->lock);
216+ list_for_each_entry(req, &nfit_res->requests, list)
217+ if (req->res.start == start) {
218+ res = &req->res;
219+ list_del(&req->list);
220+ break;
221+ }
222+ spin_unlock(&nfit_res->lock);
223+
224+ WARN(!res || resource_size(res) != n,
225+ "%s: start: %llx n: %llx mismatch: %pr\n",
226+ __func__, start, n, res);
227+ if (res)
228+ kfree(req);
229+ return true;
230+ }
231+ }
232+ return false;
233+}
234+
177235 static struct resource *nfit_test_request_region(struct device *dev,
178236 struct resource *parent, resource_size_t start,
179237 resource_size_t n, const char *name, int flags)
@@ -183,21 +241,57 @@ static struct resource *nfit_test_request_region(struct device *dev, · 3 unmodified lines
183241 if (parent == &iomem_resource) {
184242 nfit_res = get_nfit_res(start);
185243 if (nfit_res) {
186− struct resource *res = nfit_res->res + 1;
244+ struct nfit_test_request *req;
245+ struct resource *res = NULL;
187246
188− if (start + n > nfit_res->res->start
189− + resource_size(nfit_res->res)) {
247+ if (start + n > nfit_res->res.start
248+ + resource_size(&nfit_res->res)) {
190249 pr_debug("%s: start: %llx n: %llx overflow: %pr\n",
191250 __func__, start, n,
192− nfit_res->res);
251+ &nfit_res->res);
193252 return NULL;
194253 }
195254
255+ spin_lock(&nfit_res->lock);
256+ list_for_each_entry(req, &nfit_res->requests, list)
257+ if (start == req->res.start) {
258+ res = &req->res;
259+ break;
260+ }
261+ spin_unlock(&nfit_res->lock);
262+
263+ if (res) {
264+ WARN(1, "%pr already busy\n", res);
265+ return NULL;
266+ }
267+
268+ req = kzalloc(sizeof(*req), GFP_KERNEL);
269+ if (!req)
270+ return NULL;
271+ INIT_LIST_HEAD(&req->list);
272+ res = &req->res;
273+
196274 res->start = start;
197275 res->end = start + n - 1;
198276 res->name = name;
199277 res->flags = resource_type(parent);
200278 res->flags |= IORESOURCE_BUSY | flags;
279+ spin_lock(&nfit_res->lock);
280+ list_add(&req->list, &nfit_res->requests);
281+ spin_unlock(&nfit_res->lock);
282+
283+ if (dev) {
284+ struct resource **d;
285+
286+ d = devres_alloc(nfit_devres_release,
287+ sizeof(struct resource *),
288+ GFP_KERNEL);
289+ if (!d)
290+ return NULL;
291+ *d = res;
292+ devres_add(dev, d);
293+ }
294+
201295 pr_debug("%s: %pr\n", __func__, res);
202296 return res;
203297 }
@@ -241,29 +335,10 @@ struct resource *__wrap___devm_request_region(struct device *dev, · 37 unmodified lines
241335 }
242336 EXPORT_SYMBOL(__wrap___devm_request_region);
243337
244−static bool nfit_test_release_region(struct resource *parent,
245− resource_size_t start, resource_size_t n)
246−{
247− if (parent == &iomem_resource) {
248− struct nfit_test_resource *nfit_res = get_nfit_res(start);
249− if (nfit_res) {
250− struct resource *res = nfit_res->res + 1;
251−
252− if (start != res->start || resource_size(res) != n)
253− pr_info("%s: start: %llx n: %llx mismatch: %pr\n",
254− __func__, start, n, res);
255− else
256− memset(res, 0, sizeof(*res));
257− return true;
258− }
259− }
260− return false;
261−}
262−
263338 void __wrap___release_region(struct resource *parent, resource_size_t start,
264339 resource_size_t n)
265340 {
266− if (!nfit_test_release_region(parent, start, n))
341+ if (!nfit_test_release_region(NULL, parent, start, n))
267342 __release_region(parent, start, n);
268343 }
269344 EXPORT_SYMBOL(__wrap___release_region);
@@ -271,9 +346,25 @@ EXPORT_SYMBOL(__wrap___release_region); · 1 unmodified line
271346 void __wrap___devm_release_region(struct device *dev, struct resource *parent,
272347 resource_size_t start, resource_size_t n)
273348 {
274− if (!nfit_test_release_region(parent, start, n))
349+ if (!nfit_test_release_region(dev, parent, start, n))
275350 __devm_release_region(dev, parent, start, n);
276351 }
277352 EXPORT_SYMBOL(__wrap___devm_release_region);
278353
354+acpi_status __wrap_acpi_evaluate_object(acpi_handle handle, acpi_string path,
355+ struct acpi_object_list *p, struct acpi_buffer *buf)
356+{
357+ struct nfit_test_resource *nfit_res = get_nfit_res((long) handle);
358+ union acpi_object **obj;
359+
360+ if (!nfit_res || strcmp(path, "_FIT") || !buf)
361+ return acpi_evaluate_object(handle, path, p, buf);
362+
363+ obj = nfit_res->buf;
364+ buf->length = sizeof(union acpi_object);
365+ buf->pointer = *obj;
366+ return AE_OK;
367+}
368+EXPORT_SYMBOL(__wrap_acpi_evaluate_object);
369+
279370 MODULE_LICENSE("GPL v2");
tools/testing/nvdimm/test/nfit.c+143−17
@@ -132,6 +132,8 @@ static u32 handle[NUM_DCR] = { · 131 unmodified lines
132132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
133133 };
134134
135+static unsigned long dimm_fail_cmd_flags[NUM_DCR];
136+
135137 struct nfit_test {
136138 struct acpi_nfit_desc acpi_desc;
137139 struct platform_device pdev;
@@ -154,11 +156,14 @@ struct nfit_test { · 16 unmodified lines
154156 int (*alloc)(struct nfit_test *t);
155157 void (*setup)(struct nfit_test *t);
156158 int setup_hotplug;
159+ union acpi_object **_fit;
160+ dma_addr_t _fit_dma;
157161 struct ars_state {
158162 struct nd_cmd_ars_status *ars_status;
159163 unsigned long deadline;
160164 spinlock_t lock;
161165 } ars_state;
166+ struct device *dimm_dev[NUM_DCR];
162167 };
163168
164169 static struct nfit_test *to_nfit_test(struct device *dev)
@@ -411,6 +416,9 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, · 246 unmodified lines
411416 if (i >= ARRAY_SIZE(handle))
412417 return -ENXIO;
413418
419+ if ((1 << func) & dimm_fail_cmd_flags[i])
420+ return -EIO;
421+
414422 switch (func) {
415423 case ND_CMD_GET_CONFIG_SIZE:
416424 rc = nfit_test_cmd_get_config_size(buf, buf_len);
@@ -428,6 +436,9 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, · 11 unmodified lines
428436 break;
429437 case ND_CMD_SMART_THRESHOLD:
430438 rc = nfit_test_cmd_smart_threshold(buf, buf_len);
439+ device_lock(&t->pdev.dev);
440+ __acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
441+ device_unlock(&t->pdev.dev);
431442 break;
432443 default:
433444 return -ENOTTY;
@@ -467,14 +478,12 @@ static struct nfit_test *instances[NUM_NFITS]; · 33 unmodified lines
467478 static void release_nfit_res(void *data)
468479 {
469480 struct nfit_test_resource *nfit_res = data;
470− struct resource *res = nfit_res->res;
471481
472482 spin_lock(&nfit_test_lock);
473483 list_del(&nfit_res->list);
474484 spin_unlock(&nfit_test_lock);
475485
476486 vfree(nfit_res->buf);
477− kfree(res);
478487 kfree(nfit_res);
479488 }
480489
@@ -482,12 +491,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, · 1 unmodified line
482491 void *buf)
483492 {
484493 struct device *dev = &t->pdev.dev;
485− struct resource *res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
486494 struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res),
487495 GFP_KERNEL);
488496 int rc;
489497
490− if (!res || !buf || !nfit_res)
498+ if (!buf || !nfit_res)
491499 goto err;
492500 rc = devm_add_action(dev, release_nfit_res, nfit_res);
493501 if (rc)
@@ -496,10 +504,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, · 2 unmodified lines
496504 memset(buf, 0, size);
497505 nfit_res->dev = dev;
498506 nfit_res->buf = buf;
499− nfit_res->res = res;
500− res->start = *dma;
501− res->end = *dma + size - 1;
502− res->name = "NFIT";
507+ nfit_res->res.start = *dma;
508+ nfit_res->res.end = *dma + size - 1;
509+ nfit_res->res.name = "NFIT";
510+ spin_lock_init(&nfit_res->lock);
511+ INIT_LIST_HEAD(&nfit_res->requests);
503512 spin_lock(&nfit_test_lock);
504513 list_add(&nfit_res->list, &t->resources);
505514 spin_unlock(&nfit_test_lock);
@@ -508,7 +517,6 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma, · 2 unmodified lines
508517 err:
509518 if (buf)
510519 vfree(buf);
511− kfree(res);
512520 kfree(nfit_res);
513521 return NULL;
514522 }
@@ -533,13 +541,13 @@ static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr) · 18 unmodified lines
533541 continue;
534542 spin_lock(&nfit_test_lock);
535543 list_for_each_entry(n, &t->resources, list) {
536− if (addr >= n->res->start && (addr < n->res->start
537− + resource_size(n->res))) {
544+ if (addr >= n->res.start && (addr < n->res.start
545+ + resource_size(&n->res))) {
538546 nfit_res = n;
539547 break;
540548 } else if (addr >= (unsigned long) n->buf
541549 && (addr < (unsigned long) n->buf
542− + resource_size(n->res))) {
550+ + resource_size(&n->res))) {
543551 nfit_res = n;
544552 break;
545553 }
@@ -564,6 +572,86 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state) · 18 unmodified lines
564572 return 0;
565573 }
566574
575+static void put_dimms(void *data)
576+{
577+ struct device **dimm_dev = data;
578+ int i;
579+
580+ for (i = 0; i < NUM_DCR; i++)
581+ if (dimm_dev[i])
582+ device_unregister(dimm_dev[i]);
583+}
584+
585+static struct class *nfit_test_dimm;
586+
587+static int dimm_name_to_id(struct device *dev)
588+{
589+ int dimm;
590+
591+ if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
592+ || dimm >= NUM_DCR || dimm < 0)
593+ return -ENXIO;
594+ return dimm;
595+}
596+
597+
598+static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
599+ char *buf)
600+{
601+ int dimm = dimm_name_to_id(dev);
602+
603+ if (dimm < 0)
604+ return dimm;
605+
606+ return sprintf(buf, "%#x", handle[dimm]);
607+}
608+DEVICE_ATTR_RO(handle);
609+
610+static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr,
611+ char *buf)
612+{
613+ int dimm = dimm_name_to_id(dev);
614+
615+ if (dimm < 0)
616+ return dimm;
617+
618+ return sprintf(buf, "%#lx\n", dimm_fail_cmd_flags[dimm]);
619+}
620+
621+static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
622+ const char *buf, size_t size)
623+{
624+ int dimm = dimm_name_to_id(dev);
625+ unsigned long val;
626+ ssize_t rc;
627+
628+ if (dimm < 0)
629+ return dimm;
630+
631+ rc = kstrtol(buf, 0, &val);
632+ if (rc)
633+ return rc;
634+
635+ dimm_fail_cmd_flags[dimm] = val;
636+ return size;
637+}
638+static DEVICE_ATTR_RW(fail_cmd);
639+
640+static struct attribute *nfit_test_dimm_attributes[] = {
641+ &dev_attr_fail_cmd.attr,
642+ &dev_attr_handle.attr,
643+ NULL,
644+};
645+
646+static struct attribute_group nfit_test_dimm_attribute_group = {
647+ .attrs = nfit_test_dimm_attributes,
648+};
649+
650+static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
651+ &nfit_test_dimm_attribute_group,
652+ NULL,
653+};
654+
567655 static int nfit_test0_alloc(struct nfit_test *t)
568656 {
569657 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
@@ -616,6 +704,21 @@ static int nfit_test0_alloc(struct nfit_test *t) · 46 unmodified lines
616704 return -ENOMEM;
617705 }
618706
707+ t->_fit = test_alloc(t, sizeof(union acpi_object **), &t->_fit_dma);
708+ if (!t->_fit)
709+ return -ENOMEM;
710+
711+ if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
712+ return -ENOMEM;
713+ for (i = 0; i < NUM_DCR; i++) {
714+ t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
715+ &t->pdev.dev, 0, NULL,
716+ nfit_test_dimm_attribute_groups,
717+ "test_dimm%d", i);
718+ if (!t->dimm_dev[i])
719+ return -ENOMEM;
720+ }
721+
619722 return ars_state_init(&t->pdev.dev, &t->ars_state);
620723 }
621724
@@ -1409,6 +1512,8 @@ static int nfit_test_probe(struct platform_device *pdev) · 787 unmodified lines
14091512 struct acpi_nfit_desc *acpi_desc;
14101513 struct device *dev = &pdev->dev;
14111514 struct nfit_test *nfit_test;
1515+ struct nfit_mem *nfit_mem;
1516+ union acpi_object *obj;
14121517 int rc;
14131518
14141519 nfit_test = to_nfit_test(&pdev->dev);
@@ -1476,14 +1581,30 @@ static int nfit_test_probe(struct platform_device *pdev) · 61 unmodified lines
14761581 if (nfit_test->setup != nfit_test0_setup)
14771582 return 0;
14781583
1479− flush_work(&acpi_desc->work);
14801584 nfit_test->setup_hotplug = 1;
14811585 nfit_test->setup(nfit_test);
14821586
1483− rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1484− nfit_test->nfit_size);
1485− if (rc)
1486− return rc;
1587+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1588+ if (!obj)
1589+ return -ENOMEM;
1590+ obj->type = ACPI_TYPE_BUFFER;
1591+ obj->buffer.length = nfit_test->nfit_size;
1592+ obj->buffer.pointer = nfit_test->nfit_buf;
1593+ *(nfit_test->_fit) = obj;
1594+ __acpi_nfit_notify(&pdev->dev, nfit_test, 0x80);
1595+
1596+ /* associate dimm devices with nfit_mem data for notification testing */
1597+ mutex_lock(&acpi_desc->init_mutex);
1598+ list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1599+ u32 nfit_handle = __to_nfit_memdev(nfit_mem)->device_handle;
1600+ int i;
1601+
1602+ for (i = 0; i < NUM_DCR; i++)
1603+ if (nfit_handle == handle[i])
1604+ dev_set_drvdata(nfit_test->dimm_dev[i],
1605+ nfit_mem);
1606+ }
1607+ mutex_unlock(&acpi_desc->init_mutex);
14871608
14881609 return 0;
14891610 }
@@ -1518,6 +1639,10 @@ static __init int nfit_test_init(void) · 28 unmodified lines
15181639 {
15191640 int rc, i;
15201641
1642+ nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
1643+ if (IS_ERR(nfit_test_dimm))
1644+ return PTR_ERR(nfit_test_dimm);
1645+
15211646 nfit_test_setup(nfit_test_lookup);
15221647
15231648 for (i = 0; i < NUM_NFITS; i++) {
@@ -1584,6 +1709,7 @@ static __exit void nfit_test_exit(void) · 60 unmodified lines
15841709 for (i = 0; i < NUM_NFITS; i++)
15851710 platform_device_unregister(&instances[i]->pdev);
15861711 nfit_test_teardown();
1712+ class_destroy(nfit_test_dimm);
15871713 }
15881714
15891715 module_init(nfit_test_init);
tools/testing/nvdimm/test/nfit_test.h+11−1
@@ -13,11 +13,21 @@ · 12 unmodified lines
1313 #ifndef __NFIT_TEST_H__
1414 #define __NFIT_TEST_H__
1515 #include <linux/list.h>
16+#include <linux/ioport.h>
17+#include <linux/spinlock_types.h>
18+
19+struct nfit_test_request {
20+ struct list_head list;
21+ struct resource res;
22+};
1623
1724 struct nfit_test_resource {
25+ struct list_head requests;
1826 struct list_head list;
19− struct resource *res;
27+ struct resource res;
2028 struct device *dev;
29+ spinlock_t lock;
30+ int req_count;
2131 void *buf;
2232 };
2333