aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-10-07 19:46:24 -0400
committerDan Williams <dan.j.williams@intel.com>2016-10-07 19:46:24 -0400
commit178d6f4be8bf42b298bedf8ea2a00754100e0c4e (patch)
treea71865455adc31082a4ad21a942286520a7b5da1
parentdb58028ee4e360430de8e3b48f657dc798ee6591 (diff)
parent98a29c39dc689298d2f834f40102cba752eb49c0 (diff)
Merge branch 'for-4.9/libnvdimm' into libnvdimm-for-next
-rw-r--r--drivers/acpi/nfit/core.c210
-rw-r--r--drivers/acpi/nfit/mce.c24
-rw-r--r--drivers/acpi/nfit/nfit.h17
-rw-r--r--drivers/nvdimm/bus.c2
-rw-r--r--drivers/nvdimm/core.c73
-rw-r--r--drivers/nvdimm/dimm.c11
-rw-r--r--drivers/nvdimm/dimm_devs.c226
-rw-r--r--drivers/nvdimm/label.c192
-rw-r--r--drivers/nvdimm/namespace_devs.c792
-rw-r--r--drivers/nvdimm/nd-core.h24
-rw-r--r--drivers/nvdimm/nd.h29
-rw-r--r--drivers/nvdimm/pmem.c28
-rw-r--r--drivers/nvdimm/region_devs.c58
-rw-r--r--include/linux/libnvdimm.h28
-rw-r--r--include/linux/nd.h8
-rw-r--r--include/uapi/linux/ndctl.h30
-rw-r--r--tools/testing/nvdimm/Kbuild1
-rw-r--r--tools/testing/nvdimm/test/iomap.c151
-rw-r--r--tools/testing/nvdimm/test/nfit.c160
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h12
20 files changed, 1559 insertions, 517 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index e1d5ea6d5e40..71a7d07c28c9 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -886,6 +886,58 @@ static ssize_t revision_show(struct device *dev,
886} 886}
887static DEVICE_ATTR_RO(revision); 887static DEVICE_ATTR_RO(revision);
888 888
889static 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 */
906static 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}
939static DEVICE_ATTR_RW(hw_error_scrub);
940
889/* 941/*
890 * This shows the number of full Address Range Scrubs that have been 942 * This shows the number of full Address Range Scrubs that have been
891 * completed since driver load time. Userspace can wait on this using 943 * 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)
958static struct attribute *acpi_nfit_attributes[] = { 1010static struct attribute *acpi_nfit_attributes[] = {
959 &dev_attr_revision.attr, 1011 &dev_attr_revision.attr,
960 &dev_attr_scrub.attr, 1012 &dev_attr_scrub.attr,
1013 &dev_attr_hw_error_scrub.attr,
961 NULL, 1014 NULL,
962}; 1015};
963 1016
@@ -1256,6 +1309,44 @@ static struct nvdimm *acpi_nfit_dimm_by_handle(struct acpi_nfit_desc *acpi_desc,
1256 return NULL; 1309 return NULL;
1257} 1310}
1258 1311
1312void __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}
1338EXPORT_SYMBOL_GPL(__acpi_nvdimm_notify);
1339
1340static 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
1259static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, 1350static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
1260 struct nfit_mem *nfit_mem, u32 device_handle) 1351 struct nfit_mem *nfit_mem, u32 device_handle)
1261{ 1352{
@@ -1280,6 +1371,13 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
1280 return force_enable_dimms ? 0 : -ENODEV; 1371 return force_enable_dimms ? 0 : -ENODEV;
1281 } 1372 }
1282 1373
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
1283 /* 1381 /*
1284 * Until standardization materializes we need to consider 4 1382 * Until standardization materializes we need to consider 4
1285 * different command sets. Note, that checking for function0 (bit0) 1383 * 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,
1318 return 0; 1416 return 0;
1319} 1417}
1320 1418
1419static 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
1321static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) 1443static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
1322{ 1444{
1323 struct nfit_mem *nfit_mem; 1445 struct nfit_mem *nfit_mem;
1324 int dimm_count = 0; 1446 int dimm_count = 0, rc;
1447 struct nvdimm *nvdimm;
1325 1448
1326 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) { 1449 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1327 struct acpi_nfit_flush_address *flush; 1450 struct acpi_nfit_flush_address *flush;
1328 unsigned long flags = 0, cmd_mask; 1451 unsigned long flags = 0, cmd_mask;
1329 struct nvdimm *nvdimm;
1330 u32 device_handle; 1452 u32 device_handle;
1331 u16 mem_flags; 1453 u16 mem_flags;
1332 int rc;
1333 1454
1334 device_handle = __to_nfit_memdev(nfit_mem)->device_handle; 1455 device_handle = __to_nfit_memdev(nfit_mem)->device_handle;
1335 nvdimm = acpi_nfit_dimm_by_handle(acpi_desc, device_handle); 1456 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)
1382 1503
1383 } 1504 }
1384 1505
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);
1386} 1530}
1387 1531
1388static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc) 1532static 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,
1491 if (!info) 1635 if (!info)
1492 return -ENOMEM; 1636 return -ENOMEM;
1493 for (i = 0; i < nr; i++) { 1637 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];
1495 struct nfit_set_info_map *map = &info->mapping[i]; 1639 struct nfit_set_info_map *map = &info->mapping[i];
1496 struct nvdimm *nvdimm = nd_mapping->nvdimm; 1640 struct nvdimm *nvdimm = mapping->nvdimm;
1497 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 1641 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
1498 struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc, 1642 struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
1499 spa->range_index, i); 1643 spa->range_index, i);
@@ -1917,7 +2061,7 @@ static int acpi_nfit_insert_resource(struct acpi_nfit_desc *acpi_desc,
1917} 2061}
1918 2062
1919static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, 2063static 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,
1921 struct acpi_nfit_memory_map *memdev, 2065 struct acpi_nfit_memory_map *memdev,
1922 struct nfit_spa *nfit_spa) 2066 struct nfit_spa *nfit_spa)
1923{ 2067{
@@ -1934,12 +2078,12 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
1934 return -ENODEV; 2078 return -ENODEV;
1935 } 2079 }
1936 2080
1937 nd_mapping->nvdimm = nvdimm; 2081 mapping->nvdimm = nvdimm;
1938 switch (nfit_spa_type(spa)) { 2082 switch (nfit_spa_type(spa)) {
1939 case NFIT_SPA_PM: 2083 case NFIT_SPA_PM:
1940 case NFIT_SPA_VOLATILE: 2084 case NFIT_SPA_VOLATILE:
1941 nd_mapping->start = memdev->address; 2085 mapping->start = memdev->address;
1942 nd_mapping->size = memdev->region_size; 2086 mapping->size = memdev->region_size;
1943 break; 2087 break;
1944 case NFIT_SPA_DCR: 2088 case NFIT_SPA_DCR:
1945 nfit_mem = nvdimm_provider_data(nvdimm); 2089 nfit_mem = nvdimm_provider_data(nvdimm);
@@ -1947,13 +2091,13 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
1947 dev_dbg(acpi_desc->dev, "spa%d %s missing bdw\n", 2091 dev_dbg(acpi_desc->dev, "spa%d %s missing bdw\n",
1948 spa->range_index, nvdimm_name(nvdimm)); 2092 spa->range_index, nvdimm_name(nvdimm));
1949 } else { 2093 } else {
1950 nd_mapping->size = nfit_mem->bdw->capacity; 2094 mapping->size = nfit_mem->bdw->capacity;
1951 nd_mapping->start = nfit_mem->bdw->start_address; 2095 mapping->start = nfit_mem->bdw->start_address;
1952 ndr_desc->num_lanes = nfit_mem->bdw->windows; 2096 ndr_desc->num_lanes = nfit_mem->bdw->windows;
1953 blk_valid = 1; 2097 blk_valid = 1;
1954 } 2098 }
1955 2099
1956 ndr_desc->nd_mapping = nd_mapping; 2100 ndr_desc->mapping = mapping;
1957 ndr_desc->num_mappings = blk_valid; 2101 ndr_desc->num_mappings = blk_valid;
1958 ndbr_desc = to_blk_region_desc(ndr_desc); 2102 ndbr_desc = to_blk_region_desc(ndr_desc);
1959 ndbr_desc->enable = acpi_nfit_blk_region_enable; 2103 ndbr_desc->enable = acpi_nfit_blk_region_enable;
@@ -1979,7 +2123,7 @@ static bool nfit_spa_is_virtual(struct acpi_nfit_system_address *spa)
1979static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, 2123static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
1980 struct nfit_spa *nfit_spa) 2124 struct nfit_spa *nfit_spa)
1981{ 2125{
1982 static struct nd_mapping nd_mappings[ND_MAX_MAPPINGS]; 2126 static struct nd_mapping_desc mappings[ND_MAX_MAPPINGS];
1983 struct acpi_nfit_system_address *spa = nfit_spa->spa; 2127 struct acpi_nfit_system_address *spa = nfit_spa->spa;
1984 struct nd_blk_region_desc ndbr_desc; 2128 struct nd_blk_region_desc ndbr_desc;
1985 struct nd_region_desc *ndr_desc; 2129 struct nd_region_desc *ndr_desc;
@@ -1998,7 +2142,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
1998 } 2142 }
1999 2143
2000 memset(&res, 0, sizeof(res)); 2144 memset(&res, 0, sizeof(res));
2001 memset(&nd_mappings, 0, sizeof(nd_mappings)); 2145 memset(&mappings, 0, sizeof(mappings));
2002 memset(&ndbr_desc, 0, sizeof(ndbr_desc)); 2146 memset(&ndbr_desc, 0, sizeof(ndbr_desc));
2003 res.start = spa->address; 2147 res.start = spa->address;
2004 res.end = res.start + spa->length - 1; 2148 res.end = res.start + spa->length - 1;
@@ -2014,7 +2158,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
2014 2158
2015 list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { 2159 list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
2016 struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev; 2160 struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
2017 struct nd_mapping *nd_mapping; 2161 struct nd_mapping_desc *mapping;
2018 2162
2019 if (memdev->range_index != spa->range_index) 2163 if (memdev->range_index != spa->range_index)
2020 continue; 2164 continue;
@@ -2023,14 +2167,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
2023 spa->range_index, ND_MAX_MAPPINGS); 2167 spa->range_index, ND_MAX_MAPPINGS);
2024 return -ENXIO; 2168 return -ENXIO;
2025 } 2169 }
2026 nd_mapping = &nd_mappings[count++]; 2170 mapping = &mappings[count++];
2027 rc = acpi_nfit_init_mapping(acpi_desc, nd_mapping, ndr_desc, 2171 rc = acpi_nfit_init_mapping(acpi_desc, mapping, ndr_desc,
2028 memdev, nfit_spa); 2172 memdev, nfit_spa);
2029 if (rc) 2173 if (rc)
2030 goto out; 2174 goto out;
2031 } 2175 }
2032 2176
2033 ndr_desc->nd_mapping = nd_mappings; 2177 ndr_desc->mapping = mappings;
2034 ndr_desc->num_mappings = count; 2178 ndr_desc->num_mappings = count;
2035 rc = acpi_nfit_init_interleave_set(acpi_desc, ndr_desc, spa); 2179 rc = acpi_nfit_init_interleave_set(acpi_desc, ndr_desc, spa);
2036 if (rc) 2180 if (rc)
@@ -2678,29 +2822,30 @@ static int acpi_nfit_remove(struct acpi_device *adev)
2678 return 0; 2822 return 0;
2679} 2823}
2680 2824
2681static void acpi_nfit_notify(struct acpi_device *adev, u32 event) 2825void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
2682{ 2826{
2683 struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev); 2827 struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
2684 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 2828 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
2685 struct device *dev = &adev->dev;
2686 union acpi_object *obj; 2829 union acpi_object *obj;
2687 acpi_status status; 2830 acpi_status status;
2688 int ret; 2831 int ret;
2689 2832
2690 dev_dbg(dev, "%s: event: %d\n", __func__, event); 2833 dev_dbg(dev, "%s: event: %d\n", __func__, event);
2691 2834
2692 device_lock(dev); 2835 if (event != NFIT_NOTIFY_UPDATE)
2836 return;
2837
2693 if (!dev->driver) { 2838 if (!dev->driver) {
2694 /* dev->driver may be null if we're being removed */ 2839 /* dev->driver may be null if we're being removed */
2695 dev_dbg(dev, "%s: no driver found for dev\n", __func__); 2840 dev_dbg(dev, "%s: no driver found for dev\n", __func__);
2696 goto out_unlock; 2841 return;
2697 } 2842 }
2698 2843
2699 if (!acpi_desc) { 2844 if (!acpi_desc) {
2700 acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL); 2845 acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
2701 if (!acpi_desc) 2846 if (!acpi_desc)
2702 goto out_unlock; 2847 return;
2703 acpi_nfit_desc_init(acpi_desc, &adev->dev); 2848 acpi_nfit_desc_init(acpi_desc, dev);
2704 } else { 2849 } else {
2705 /* 2850 /*
2706 * Finish previous registration before considering new 2851 * Finish previous registration before considering new
@@ -2710,10 +2855,10 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
2710 } 2855 }
2711 2856
2712 /* Evaluate _FIT */ 2857 /* Evaluate _FIT */
2713 status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf); 2858 status = acpi_evaluate_object(handle, "_FIT", NULL, &buf);
2714 if (ACPI_FAILURE(status)) { 2859 if (ACPI_FAILURE(status)) {
2715 dev_err(dev, "failed to evaluate _FIT\n"); 2860 dev_err(dev, "failed to evaluate _FIT\n");
2716 goto out_unlock; 2861 return;
2717 } 2862 }
2718 2863
2719 obj = buf.pointer; 2864 obj = buf.pointer;
@@ -2725,9 +2870,14 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
2725 } else 2870 } else
2726 dev_err(dev, "Invalid _FIT\n"); 2871 dev_err(dev, "Invalid _FIT\n");
2727 kfree(buf.pointer); 2872 kfree(buf.pointer);
2873}
2874EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
2728 2875
2729 out_unlock: 2876static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
2730 device_unlock(dev); 2877{
2878 device_lock(&adev->dev);
2879 __acpi_nfit_notify(&adev->dev, adev->handle, event);
2880 device_unlock(&adev->dev);
2731} 2881}
2732 2882
2733static const struct acpi_device_id acpi_nfit_ids[] = { 2883static const struct acpi_device_id acpi_nfit_ids[] = {
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c
index 161f91539ae6..e5ce81c38eed 100644
--- a/drivers/acpi/nfit/mce.c
+++ b/drivers/acpi/nfit/mce.c
@@ -14,6 +14,7 @@
14 */ 14 */
15#include <linux/notifier.h> 15#include <linux/notifier.h>
16#include <linux/acpi.h> 16#include <linux/acpi.h>
17#include <linux/nd.h>
17#include <asm/mce.h> 18#include <asm/mce.h>
18#include "nfit.h" 19#include "nfit.h"
19 20
@@ -62,12 +63,25 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
62 } 63 }
63 mutex_unlock(&acpi_desc->init_mutex); 64 mutex_unlock(&acpi_desc->init_mutex);
64 65
65 /* 66 if (!found_match)
66 * We can ignore an -EBUSY here because if an ARS is already 67 continue;
67 * in progress, just let that be the last authoritative one 68
68 */ 69 /* If this fails due to an -ENOMEM, there is little we can do */
69 if (found_match) 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 */
70 acpi_nfit_ars_rescan(acpi_desc); 82 acpi_nfit_ars_rescan(acpi_desc);
83 }
84 break;
71 } 85 }
72 86
73 mutex_unlock(&acpi_desc_lock); 87 mutex_unlock(&acpi_desc_lock);
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index e894ded24d99..14296f5267c8 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -78,6 +78,14 @@ enum {
78 NFIT_ARS_TIMEOUT = 90, 78 NFIT_ARS_TIMEOUT = 90,
79}; 79};
80 80
81enum nfit_root_notifiers {
82 NFIT_NOTIFY_UPDATE = 0x80,
83};
84
85enum nfit_dimm_notifiers {
86 NFIT_NOTIFY_DIMM_HEALTH = 0x81,
87};
88
81struct nfit_spa { 89struct nfit_spa {
82 struct list_head list; 90 struct list_head list;
83 struct nd_region *nd_region; 91 struct nd_region *nd_region;
@@ -124,6 +132,7 @@ struct nfit_mem {
124 struct acpi_nfit_system_address *spa_bdw; 132 struct acpi_nfit_system_address *spa_bdw;
125 struct acpi_nfit_interleave *idt_dcr; 133 struct acpi_nfit_interleave *idt_dcr;
126 struct acpi_nfit_interleave *idt_bdw; 134 struct acpi_nfit_interleave *idt_bdw;
135 struct kernfs_node *flags_attr;
127 struct nfit_flush *nfit_flush; 136 struct nfit_flush *nfit_flush;
128 struct list_head list; 137 struct list_head list;
129 struct acpi_device *adev; 138 struct acpi_device *adev;
@@ -152,6 +161,7 @@ struct acpi_nfit_desc {
152 struct list_head list; 161 struct list_head list;
153 struct kernfs_node *scrub_count_state; 162 struct kernfs_node *scrub_count_state;
154 unsigned int scrub_count; 163 unsigned int scrub_count;
164 unsigned int scrub_mode;
155 unsigned int cancel:1; 165 unsigned int cancel:1;
156 unsigned long dimm_cmd_force_en; 166 unsigned long dimm_cmd_force_en;
157 unsigned long bus_cmd_force_en; 167 unsigned long bus_cmd_force_en;
@@ -159,6 +169,11 @@ struct acpi_nfit_desc {
159 void *iobuf, u64 len, int rw); 169 void *iobuf, u64 len, int rw);
160}; 170};
161 171
172enum scrub_mode {
173 HW_ERROR_SCRUB_OFF,
174 HW_ERROR_SCRUB_ON,
175};
176
162enum nd_blk_mmio_selector { 177enum nd_blk_mmio_selector {
163 BDW, 178 BDW,
164 DCR, 179 DCR,
@@ -223,5 +238,7 @@ static inline struct acpi_nfit_desc *to_acpi_desc(
223 238
224const u8 *to_nfit_uuid(enum nfit_uuids id); 239const u8 *to_nfit_uuid(enum nfit_uuids id);
225int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); 240int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
241void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
242void __acpi_nvdimm_notify(struct device *dev, u32 event);
226void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev); 243void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
227#endif /* __NFIT_H__ */ 244#endif /* __NFIT_H__ */
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 935866fe5ec2..a8b6949a8778 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -217,6 +217,8 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
217 return rc; 217 return rc;
218 if (cmd_rc < 0) 218 if (cmd_rc < 0)
219 return cmd_rc; 219 return cmd_rc;
220
221 nvdimm_clear_from_poison_list(nvdimm_bus, phys, len);
220 return clear_err.cleared; 222 return clear_err.cleared;
221} 223}
222EXPORT_SYMBOL_GPL(nvdimm_clear_poison); 224EXPORT_SYMBOL_GPL(nvdimm_clear_poison);
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 4d7bbd2df5c0..7ceba08774b6 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -547,11 +547,12 @@ void nvdimm_badblocks_populate(struct nd_region *nd_region,
547} 547}
548EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate); 548EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate);
549 549
550static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) 550static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length,
551 gfp_t flags)
551{ 552{
552 struct nd_poison *pl; 553 struct nd_poison *pl;
553 554
554 pl = kzalloc(sizeof(*pl), GFP_KERNEL); 555 pl = kzalloc(sizeof(*pl), flags);
555 if (!pl) 556 if (!pl)
556 return -ENOMEM; 557 return -ENOMEM;
557 558
@@ -567,7 +568,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
567 struct nd_poison *pl; 568 struct nd_poison *pl;
568 569
569 if (list_empty(&nvdimm_bus->poison_list)) 570 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);
571 572
572 /* 573 /*
573 * There is a chance this is a duplicate, check for those first. 574 * 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)
587 * as any overlapping ranges will get resolved when the list is consumed 588 * as any overlapping ranges will get resolved when the list is consumed
588 * and converted to badblocks 589 * and converted to badblocks
589 */ 590 */
590 return add_poison(nvdimm_bus, addr, length); 591 return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
591} 592}
592 593
593int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) 594int 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)
602} 603}
603EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison); 604EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison);
604 605
606void 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}
668EXPORT_SYMBOL_GPL(nvdimm_clear_from_poison_list);
669
605#ifdef CONFIG_BLK_DEV_INTEGRITY 670#ifdef CONFIG_BLK_DEV_INTEGRITY
606int nd_integrity_init(struct gendisk *disk, unsigned long meta_size) 671int nd_integrity_init(struct gendisk *disk, unsigned long meta_size)
607{ 672{
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c
index 71d12bb67339..619834e144d1 100644
--- a/drivers/nvdimm/dimm.c
+++ b/drivers/nvdimm/dimm.c
@@ -26,6 +26,14 @@ static int nvdimm_probe(struct device *dev)
26 struct nvdimm_drvdata *ndd; 26 struct nvdimm_drvdata *ndd;
27 int rc; 27 int rc;
28 28
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
29 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL); 37 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
30 if (!ndd) 38 if (!ndd)
31 return -ENOMEM; 39 return -ENOMEM;
@@ -72,6 +80,9 @@ static int nvdimm_remove(struct device *dev)
72{ 80{
73 struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); 81 struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
74 82
83 if (!ndd)
84 return 0;
85
75 nvdimm_bus_lock(dev); 86 nvdimm_bus_lock(dev);
76 dev_set_drvdata(dev, NULL); 87 dev_set_drvdata(dev, NULL);
77 nvdimm_bus_unlock(dev); 88 nvdimm_bus_unlock(dev);
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index d9bba5edd8dc..d614493ad5ac 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -28,28 +28,30 @@ static DEFINE_IDA(dimm_ida);
28 * Retrieve bus and dimm handle and return if this bus supports 28 * Retrieve bus and dimm handle and return if this bus supports
29 * get_config_data commands 29 * get_config_data commands
30 */ 30 */
31static int __validate_dimm(struct nvdimm_drvdata *ndd) 31int nvdimm_check_config_data(struct device *dev)
32{ 32{
33 struct nvdimm *nvdimm; 33 struct nvdimm *nvdimm = to_nvdimm(dev);
34
35 if (!ndd)
36 return -EINVAL;
37
38 nvdimm = to_nvdimm(ndd->dev);
39 34
40 if (!nvdimm->cmd_mask) 35 if (!nvdimm->cmd_mask ||
41 return -ENXIO; 36 !test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) {
42 if (!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) 37 if (nvdimm->flags & NDD_ALIASING)
43 return -ENXIO; 38 return -ENXIO;
39 else
40 return -ENOTTY;
41 }
44 42
45 return 0; 43 return 0;
46} 44}
47 45
48static int validate_dimm(struct nvdimm_drvdata *ndd) 46static int validate_dimm(struct nvdimm_drvdata *ndd)
49{ 47{
50 int rc = __validate_dimm(ndd); 48 int rc;
51 49
52 if (rc && ndd) 50 if (!ndd)
51 return -EINVAL;
52
53 rc = nvdimm_check_config_data(ndd->dev);
54 if (rc)
53 dev_dbg(ndd->dev, "%pf: %s error: %d\n", 55 dev_dbg(ndd->dev, "%pf: %s error: %d\n",
54 __builtin_return_address(0), __func__, rc); 56 __builtin_return_address(0), __func__, rc);
55 return rc; 57 return rc;
@@ -263,6 +265,12 @@ const char *nvdimm_name(struct nvdimm *nvdimm)
263} 265}
264EXPORT_SYMBOL_GPL(nvdimm_name); 266EXPORT_SYMBOL_GPL(nvdimm_name);
265 267
268struct kobject *nvdimm_kobj(struct nvdimm *nvdimm)
269{
270 return &nvdimm->dev.kobj;
271}
272EXPORT_SYMBOL_GPL(nvdimm_kobj);
273
266unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm) 274unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm)
267{ 275{
268 return nvdimm->cmd_mask; 276 return nvdimm->cmd_mask;
@@ -378,40 +386,166 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
378} 386}
379EXPORT_SYMBOL_GPL(nvdimm_create); 387EXPORT_SYMBOL_GPL(nvdimm_create);
380 388
389int 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
471static 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
381/** 512/**
382 * nd_blk_available_dpa - account the unused dpa of BLK region 513 * nd_blk_available_dpa - account the unused dpa of BLK region
383 * @nd_mapping: container of dpa-resource-root + labels 514 * @nd_mapping: container of dpa-resource-root + labels
384 * 515 *
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.
386 */ 519 */
387resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping) 520resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
388{ 521{
522 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
523 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
389 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 524 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 };
391 struct resource *res; 530 struct resource *res;
392 531
393 if (!ndd) 532 if (!ndd)
394 return 0; 533 return 0;
395 534
396 map_end = nd_mapping->start + nd_mapping->size - 1; 535 device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
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);
400 536
401 busy += end - res->start + 1; 537 /* now account for busy blk allocations in unaliased dpa */
402 } else if (res->end >= nd_mapping->start 538 for_each_dpa_resource(ndd, res) {
403 && res->end <= map_end) { 539 if (strncmp(res->name, "blk", 3) != 0)
404 busy += res->end - nd_mapping->start; 540 continue;
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 }
410 541
411 available = map_end - nd_mapping->start + 1; 542 info.res = res;
412 if (busy < available) 543 info.busy = resource_size(res);
413 return available - busy; 544 device_for_each_child(&nvdimm_bus->dev, &info, blk_dpa_busy);
414 return 0; 545 info.available -= info.busy;
546 }
547
548 return info.available;
415} 549}
416 550
417/** 551/**
@@ -443,21 +577,16 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
443 map_start = nd_mapping->start; 577 map_start = nd_mapping->start;
444 map_end = map_start + nd_mapping->size - 1; 578 map_end = map_start + nd_mapping->size - 1;
445 blk_start = max(map_start, map_end + 1 - *overlap); 579 blk_start = max(map_start, map_end + 1 - *overlap);
446 for_each_dpa_resource(ndd, res) 580 for_each_dpa_resource(ndd, res) {
447 if (res->start >= map_start && res->start < map_end) { 581 if (res->start >= map_start && res->start < map_end) {
448 if (strncmp(res->name, "blk", 3) == 0) 582 if (strncmp(res->name, "blk", 3) == 0)
449 blk_start = min(blk_start, res->start); 583 blk_start = min(blk_start,
450 else if (res->start != map_start) { 584 max(map_start, res->start));
585 else if (res->end > map_end) {
451 reason = "misaligned to iset"; 586 reason = "misaligned to iset";
452 goto err; 587 goto err;
453 } else { 588 } else
454 if (busy) {
455 reason = "duplicate overlapping PMEM reservations?";
456 goto err;
457 }
458 busy += resource_size(res); 589 busy += resource_size(res);
459 continue;
460 }
461 } else if (res->end >= map_start && res->end <= map_end) { 590 } else if (res->end >= map_start && res->end <= map_end) {
462 if (strncmp(res->name, "blk", 3) == 0) { 591 if (strncmp(res->name, "blk", 3) == 0) {
463 /* 592 /*
@@ -466,15 +595,14 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
466 * be used for BLK. 595 * be used for BLK.
467 */ 596 */
468 blk_start = map_start; 597 blk_start = map_start;
469 } else { 598 } else
470 reason = "misaligned to iset"; 599 busy += resource_size(res);
471 goto err;
472 }
473 } else if (map_start > res->start && map_start < res->end) { 600 } else if (map_start > res->start && map_start < res->end) {
474 /* total eclipse of the mapping */ 601 /* total eclipse of the mapping */
475 busy += nd_mapping->size; 602 busy += nd_mapping->size;
476 blk_start = map_start; 603 blk_start = map_start;
477 } 604 }
605 }
478 606
479 *overlap = map_end + 1 - blk_start; 607 *overlap = map_end + 1 - blk_start;
480 available = blk_start - map_start; 608 available = blk_start - map_start;
@@ -483,10 +611,6 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
483 return 0; 611 return 0;
484 612
485 err: 613 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 */
490 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason); 614 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason);
491 return 0; 615 return 0;
492} 616}
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 96526dcfdd37..fac7cabe8f56 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -494,11 +494,13 @@ static int __pmem_label_update(struct nd_region *nd_region,
494 struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm, 494 struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm,
495 int pos) 495 int pos)
496{ 496{
497 u64 cookie = nd_region_interleave_set_cookie(nd_region), rawsize; 497 u64 cookie = nd_region_interleave_set_cookie(nd_region);
498 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 498 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
499 struct nd_namespace_label *victim_label; 499 struct nd_label_ent *label_ent, *victim = NULL;
500 struct nd_namespace_label *nd_label; 500 struct nd_namespace_label *nd_label;
501 struct nd_namespace_index *nsindex; 501 struct nd_namespace_index *nsindex;
502 struct nd_label_id label_id;
503 struct resource *res;
502 unsigned long *free; 504 unsigned long *free;
503 u32 nslot, slot; 505 u32 nslot, slot;
504 size_t offset; 506 size_t offset;
@@ -507,6 +509,16 @@ static int __pmem_label_update(struct nd_region *nd_region,
507 if (!preamble_next(ndd, &nsindex, &free, &nslot)) 509 if (!preamble_next(ndd, &nsindex, &free, &nslot))
508 return -ENXIO; 510 return -ENXIO;
509 511
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
510 /* allocate and write the label to the staging (next) index */ 522 /* allocate and write the label to the staging (next) index */
511 slot = nd_label_alloc_slot(ndd); 523 slot = nd_label_alloc_slot(ndd);
512 if (slot == UINT_MAX) 524 if (slot == UINT_MAX)
@@ -522,11 +534,10 @@ static int __pmem_label_update(struct nd_region *nd_region,
522 nd_label->nlabel = __cpu_to_le16(nd_region->ndr_mappings); 534 nd_label->nlabel = __cpu_to_le16(nd_region->ndr_mappings);
523 nd_label->position = __cpu_to_le16(pos); 535 nd_label->position = __cpu_to_le16(pos);
524 nd_label->isetcookie = __cpu_to_le64(cookie); 536 nd_label->isetcookie = __cpu_to_le64(cookie);
525 rawsize = div_u64(resource_size(&nspm->nsio.res), 537 nd_label->rawsize = __cpu_to_le64(resource_size(res));
526 nd_region->ndr_mappings); 538 nd_label->dpa = __cpu_to_le64(res->start);
527 nd_label->rawsize = __cpu_to_le64(rawsize);
528 nd_label->dpa = __cpu_to_le64(nd_mapping->start);
529 nd_label->slot = __cpu_to_le32(slot); 539 nd_label->slot = __cpu_to_le32(slot);
540 nd_dbg_dpa(nd_region, ndd, res, "%s\n", __func__);
530 541
531 /* update label */ 542 /* update label */
532 offset = nd_label_offset(ndd, nd_label); 543 offset = nd_label_offset(ndd, nd_label);
@@ -536,38 +547,43 @@ static int __pmem_label_update(struct nd_region *nd_region,
536 return rc; 547 return rc;
537 548
538 /* Garbage collect the previous label */ 549 /* Garbage collect the previous label */
539 victim_label = nd_mapping->labels[0]; 550 mutex_lock(&nd_mapping->lock);
540 if (victim_label) { 551 list_for_each_entry(label_ent, &nd_mapping->labels, list) {
541 slot = to_slot(ndd, victim_label); 552 if (!label_ent->label)
542 nd_label_free_slot(ndd, slot); 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) {
543 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); 562 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;
544 } 566 }
545 567
546 /* update index */ 568 /* update index */
547 rc = nd_label_write_index(ndd, ndd->ns_next, 569 rc = nd_label_write_index(ndd, ndd->ns_next,
548 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); 570 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
549 if (rc < 0) 571 if (rc == 0) {
550 return rc; 572 list_for_each_entry(label_ent, &nd_mapping->labels, list)
551 573 if (!label_ent->label) {
552 nd_mapping->labels[0] = nd_label; 574 label_ent->label = nd_label;
553 575 nd_label = NULL;
554 return 0; 576 break;
555} 577 }
556 578 dev_WARN_ONCE(&nspm->nsio.common.dev, nd_label,
557static void del_label(struct nd_mapping *nd_mapping, int l) 579 "failed to track label: %d\n",
558{ 580 to_slot(ndd, nd_label));
559 struct nd_namespace_label *next_label, *nd_label; 581 if (nd_label)
560 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 582 rc = -ENXIO;
561 unsigned int slot; 583 }
562 int j; 584 mutex_unlock(&nd_mapping->lock);
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);
567 585
568 for (j = l; (next_label = nd_mapping->labels[j + 1]); j++) 586 return rc;
569 nd_mapping->labels[j] = next_label;
570 nd_mapping->labels[j] = NULL;
571} 587}
572 588
573static bool is_old_resource(struct resource *res, struct resource **list, int n) 589static 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,
607 struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk, 623 struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk,
608 int num_labels) 624 int num_labels)
609{ 625{
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;
611 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 627 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
612 struct nd_namespace_label *nd_label; 628 struct nd_namespace_label *nd_label;
629 struct nd_label_ent *label_ent, *e;
613 struct nd_namespace_index *nsindex; 630 struct nd_namespace_index *nsindex;
614 unsigned long *free, *victim_map = NULL; 631 unsigned long *free, *victim_map = NULL;
615 struct resource *res, **old_res_list; 632 struct resource *res, **old_res_list;
616 struct nd_label_id label_id; 633 struct nd_label_id label_id;
617 u8 uuid[NSLABEL_UUID_LEN]; 634 u8 uuid[NSLABEL_UUID_LEN];
635 LIST_HEAD(list);
618 u32 nslot, slot; 636 u32 nslot, slot;
619 637
620 if (!preamble_next(ndd, &nsindex, &free, &nslot)) 638 if (!preamble_next(ndd, &nsindex, &free, &nslot))
@@ -736,15 +754,22 @@ static int __blk_label_update(struct nd_region *nd_region,
736 * entries in nd_mapping->labels 754 * entries in nd_mapping->labels
737 */ 755 */
738 nlabel = 0; 756 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;
740 nlabel++; 762 nlabel++;
741 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN); 763 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
742 if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0) 764 if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
743 continue; 765 continue;
744 nlabel--; 766 nlabel--;
745 del_label(nd_mapping, l); 767 list_move(&label_ent->list, &list);
746 l--; /* retry with the new label at this index */ 768 label_ent->label = NULL;
747 } 769 }
770 list_splice_tail_init(&list, &nd_mapping->labels);
771 mutex_unlock(&nd_mapping->lock);
772
748 if (nlabel + nsblk->num_resources > num_labels) { 773 if (nlabel + nsblk->num_resources > num_labels) {
749 /* 774 /*
750 * Bug, we can't end up with more resources than 775 * Bug, we can't end up with more resources than
@@ -755,6 +780,15 @@ static int __blk_label_update(struct nd_region *nd_region,
755 goto out; 780 goto out;
756 } 781 }
757 782
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 }
758 for_each_clear_bit_le(slot, free, nslot) { 792 for_each_clear_bit_le(slot, free, nslot) {
759 nd_label = nd_label_base(ndd) + slot; 793 nd_label = nd_label_base(ndd) + slot;
760 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN); 794 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
@@ -762,11 +796,19 @@ static int __blk_label_update(struct nd_region *nd_region,
762 continue; 796 continue;
763 res = to_resource(ndd, nd_label); 797 res = to_resource(ndd, nd_label);
764 res->flags &= ~DPA_RESOURCE_ADJUSTED; 798 res->flags &= ~DPA_RESOURCE_ADJUSTED;
765 dev_vdbg(&nsblk->common.dev, "assign label[%d] slot: %d\n", 799 dev_vdbg(&nsblk->common.dev, "assign label slot: %d\n", slot);
766 l, slot); 800 list_for_each_entry_from(label_ent, &nd_mapping->labels, list) {
767 nd_mapping->labels[l++] = nd_label; 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);
768 } 810 }
769 nd_mapping->labels[l] = NULL; 811 mutex_unlock(&nd_mapping->lock);
770 812
771 out: 813 out:
772 kfree(old_res_list); 814 kfree(old_res_list);
@@ -788,32 +830,28 @@ static int __blk_label_update(struct nd_region *nd_region,
788 830
789static int init_labels(struct nd_mapping *nd_mapping, int num_labels) 831static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
790{ 832{
791 int i, l, old_num_labels = 0; 833 int i, old_num_labels = 0;
834 struct nd_label_ent *label_ent;
792 struct nd_namespace_index *nsindex; 835 struct nd_namespace_index *nsindex;
793 struct nd_namespace_label *nd_label;
794 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 836 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
795 size_t size = (num_labels + 1) * sizeof(struct nd_namespace_label *);
796 837
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)
798 old_num_labels++; 840 old_num_labels++;
841 mutex_unlock(&nd_mapping->lock);
799 842
800 /* 843 /*
801 * We need to preserve all the old labels for the mapping so 844 * We need to preserve all the old labels for the mapping so
802 * they can be garbage collected after writing the new labels. 845 * they can be garbage collected after writing the new labels.
803 */ 846 */
804 if (num_labels > old_num_labels) { 847 for (i = old_num_labels; i < num_labels; i++) {
805 struct nd_namespace_label **labels; 848 label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
806 849 if (!label_ent)
807 labels = krealloc(nd_mapping->labels, size, GFP_KERNEL);
808 if (!labels)
809 return -ENOMEM; 850 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);
811 } 854 }
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;
817 855
818 if (ndd->ns_current == -1 || ndd->ns_next == -1) 856 if (ndd->ns_current == -1 || ndd->ns_next == -1)
819 /* pass */; 857 /* pass */;
@@ -837,42 +875,45 @@ static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
837static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) 875static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid)
838{ 876{
839 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 877 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
840 struct nd_namespace_label *nd_label; 878 struct nd_label_ent *label_ent, *e;
841 struct nd_namespace_index *nsindex; 879 struct nd_namespace_index *nsindex;
842 u8 label_uuid[NSLABEL_UUID_LEN]; 880 u8 label_uuid[NSLABEL_UUID_LEN];
843 int l, num_freed = 0;
844 unsigned long *free; 881 unsigned long *free;
882 LIST_HEAD(list);
845 u32 nslot, slot; 883 u32 nslot, slot;
884 int active = 0;
846 885
847 if (!uuid) 886 if (!uuid)
848 return 0; 887 return 0;
849 888
850 /* no index || no labels == nothing to delete */ 889 /* no index || no labels == nothing to delete */
851 if (!preamble_next(ndd, &nsindex, &free, &nslot) 890 if (!preamble_next(ndd, &nsindex, &free, &nslot))
852 || !nd_mapping->labels)
853 return 0; 891 return 0;
854 892
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++;
856 memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN); 900 memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN);
857 if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0) 901 if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0)
858 continue; 902 continue;
903 active--;
859 slot = to_slot(ndd, nd_label); 904 slot = to_slot(ndd, nd_label);
860 nd_label_free_slot(ndd, slot); 905 nd_label_free_slot(ndd, slot);
861 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); 906 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot);
862 del_label(nd_mapping, l); 907 list_move_tail(&label_ent->list, &list);
863 num_freed++; 908 label_ent->label = NULL;
864 l--; /* retry with new label at this index */
865 } 909 }
910 list_splice_tail_init(&list, &nd_mapping->labels);
866 911
867 if (num_freed > l) { 912 if (active == 0) {
868 /* 913 nd_mapping_free_labels(nd_mapping);
869 * num_freed will only ever be > l when we delete the last 914 dev_dbg(ndd->dev, "%s: no more active labels\n", __func__);
870 * label
871 */
872 kfree(nd_mapping->labels);
873 nd_mapping->labels = NULL;
874 dev_dbg(ndd->dev, "%s: no more labels\n", __func__);
875 } 915 }
916 mutex_unlock(&nd_mapping->lock);
876 917
877 return nd_label_write_index(ndd, ndd->ns_next, 918 return nd_label_write_index(ndd, ndd->ns_next,
878 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); 919 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
@@ -885,7 +926,9 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region,
885 926
886 for (i = 0; i < nd_region->ndr_mappings; i++) { 927 for (i = 0; i < nd_region->ndr_mappings; i++) {
887 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 928 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;
889 932
890 if (size == 0) { 933 if (size == 0) {
891 rc = del_labels(nd_mapping, nspm->uuid); 934 rc = del_labels(nd_mapping, nspm->uuid);
@@ -894,7 +937,12 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region,
894 continue; 937 continue;
895 } 938 }
896 939
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);
898 if (rc < 0) 946 if (rc < 0)
899 return rc; 947 return rc;
900 948
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index c5e3196c45b0..3509cff68ef9 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -12,8 +12,10 @@
12 */ 12 */
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/sort.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/pmem.h> 17#include <linux/pmem.h>
18#include <linux/list.h>
17#include <linux/nd.h> 19#include <linux/nd.h>
18#include "nd-core.h" 20#include "nd-core.h"
19#include "nd.h" 21#include "nd.h"
@@ -28,7 +30,10 @@ static void namespace_io_release(struct device *dev)
28static void namespace_pmem_release(struct device *dev) 30static void namespace_pmem_release(struct device *dev)
29{ 31{
30 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); 32 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
33 struct nd_region *nd_region = to_nd_region(dev->parent);
31 34
35 if (nspm->id >= 0)
36 ida_simple_remove(&nd_region->ns_ida, nspm->id);
32 kfree(nspm->alt_name); 37 kfree(nspm->alt_name);
33 kfree(nspm->uuid); 38 kfree(nspm->uuid);
34 kfree(nspm); 39 kfree(nspm);
@@ -62,17 +67,17 @@ static struct device_type namespace_blk_device_type = {
62 .release = namespace_blk_release, 67 .release = namespace_blk_release,
63}; 68};
64 69
65static bool is_namespace_pmem(struct device *dev) 70static bool is_namespace_pmem(const struct device *dev)
66{ 71{
67 return dev ? dev->type == &namespace_pmem_device_type : false; 72 return dev ? dev->type == &namespace_pmem_device_type : false;
68} 73}
69 74
70static bool is_namespace_blk(struct device *dev) 75static bool is_namespace_blk(const struct device *dev)
71{ 76{
72 return dev ? dev->type == &namespace_blk_device_type : false; 77 return dev ? dev->type == &namespace_blk_device_type : false;
73} 78}
74 79
75static bool is_namespace_io(struct device *dev) 80static bool is_namespace_io(const struct device *dev)
76{ 81{
77 return dev ? dev->type == &namespace_io_device_type : false; 82 return dev ? dev->type == &namespace_io_device_type : false;
78} 83}
@@ -168,7 +173,21 @@ const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
168 suffix = "s"; 173 suffix = "s";
169 174
170 if (is_namespace_pmem(&ndns->dev) || is_namespace_io(&ndns->dev)) { 175 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 : "");
172 } else if (is_namespace_blk(&ndns->dev)) { 191 } else if (is_namespace_blk(&ndns->dev)) {
173 struct nd_namespace_blk *nsblk; 192 struct nd_namespace_blk *nsblk;
174 193
@@ -294,7 +313,7 @@ static bool __nd_namespace_blk_validate(struct nd_namespace_blk *nsblk)
294 if (strcmp(res->name, label_id.id) != 0) 313 if (strcmp(res->name, label_id.id) != 0)
295 continue; 314 continue;
296 /* 315 /*
297 * Resources with unacknoweldged adjustments indicate a 316 * Resources with unacknowledged adjustments indicate a
298 * failure to update labels 317 * failure to update labels
299 */ 318 */
300 if (res->flags & DPA_RESOURCE_ADJUSTED) 319 if (res->flags & DPA_RESOURCE_ADJUSTED)
@@ -510,19 +529,68 @@ static resource_size_t init_dpa_allocation(struct nd_label_id *label_id,
510 return rc ? n : 0; 529 return rc ? n : 0;
511} 530}
512 531
513static bool space_valid(bool is_pmem, bool is_reserve, 532
514 struct nd_label_id *label_id, struct resource *res) 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 */
549static 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)
515{ 553{
516 /* 554 bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
517 * For BLK-space any space is valid, for PMEM-space, it must be 555 bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
518 * contiguous with an existing allocation unless we are 556
519 * reserving pmem. 557 if (valid->start >= valid->end)
520 */ 558 goto invalid;
521 if (is_reserve || !is_pmem) 559
522 return true; 560 if (is_reserve)
523 if (!res || strcmp(res->name, label_id->id) == 0) 561 return;
524 return true; 562
525 return false; 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;
526} 594}
527 595
528enum alloc_loc { 596enum alloc_loc {
@@ -534,18 +602,24 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
534 resource_size_t n) 602 resource_size_t n)
535{ 603{
536 resource_size_t mapping_end = nd_mapping->start + nd_mapping->size - 1; 604 resource_size_t mapping_end = nd_mapping->start + nd_mapping->size - 1;
537 bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
538 bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0; 605 bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
539 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 606 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
607 struct resource *res, *exist = NULL, valid;
540 const resource_size_t to_allocate = n; 608 const resource_size_t to_allocate = n;
541 struct resource *res;
542 int first; 609 int first;
543 610
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";
544 retry: 618 retry:
545 first = 0; 619 first = 0;
546 for_each_dpa_resource(ndd, res) { 620 for_each_dpa_resource(ndd, res) {
547 resource_size_t allocate, available = 0, free_start, free_end;
548 struct resource *next = res->sibling, *new_res = NULL; 621 struct resource *next = res->sibling, *new_res = NULL;
622 resource_size_t allocate, available = 0;
549 enum alloc_loc loc = ALLOC_ERR; 623 enum alloc_loc loc = ALLOC_ERR;
550 const char *action; 624 const char *action;
551 int rc = 0; 625 int rc = 0;
@@ -558,32 +632,35 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
558 632
559 /* space at the beginning of the mapping */ 633 /* space at the beginning of the mapping */
560 if (!first++ && res->start > nd_mapping->start) { 634 if (!first++ && res->start > nd_mapping->start) {
561 free_start = nd_mapping->start; 635 valid.start = nd_mapping->start;
562 available = res->start - free_start; 636 valid.end = res->start - 1;
563 if (space_valid(is_pmem, is_reserve, label_id, NULL)) 637 space_valid(nd_region, ndd, label_id, NULL, next, exist,
638 to_allocate, &valid);
639 available = resource_size(&valid);
640 if (available)
564 loc = ALLOC_BEFORE; 641 loc = ALLOC_BEFORE;
565 } 642 }
566 643
567 /* space between allocations */ 644 /* space between allocations */
568 if (!loc && next) { 645 if (!loc && next) {
569 free_start = res->start + resource_size(res); 646 valid.start = res->start + resource_size(res);
570 free_end = min(mapping_end, next->start - 1); 647 valid.end = min(mapping_end, next->start - 1);
571 if (space_valid(is_pmem, is_reserve, label_id, res) 648 space_valid(nd_region, ndd, label_id, res, next, exist,
572 && free_start < free_end) { 649 to_allocate, &valid);
573 available = free_end + 1 - free_start; 650 available = resource_size(&valid);
651 if (available)
574 loc = ALLOC_MID; 652 loc = ALLOC_MID;
575 }
576 } 653 }
577 654
578 /* space at the end of the mapping */ 655 /* space at the end of the mapping */
579 if (!loc && !next) { 656 if (!loc && !next) {
580 free_start = res->start + resource_size(res); 657 valid.start = res->start + resource_size(res);
581 free_end = mapping_end; 658 valid.end = mapping_end;
582 if (space_valid(is_pmem, is_reserve, label_id, res) 659 space_valid(nd_region, ndd, label_id, res, next, exist,
583 && free_start < free_end) { 660 to_allocate, &valid);
584 available = free_end + 1 - free_start; 661 available = resource_size(&valid);
662 if (available)
585 loc = ALLOC_AFTER; 663 loc = ALLOC_AFTER;
586 }
587 } 664 }
588 665
589 if (!loc || !available) 666 if (!loc || !available)
@@ -593,8 +670,6 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
593 case ALLOC_BEFORE: 670 case ALLOC_BEFORE:
594 if (strcmp(res->name, label_id->id) == 0) { 671 if (strcmp(res->name, label_id->id) == 0) {
595 /* adjust current resource up */ 672 /* adjust current resource up */
596 if (is_pmem && !is_reserve)
597 return n;
598 rc = adjust_resource(res, res->start - allocate, 673 rc = adjust_resource(res, res->start - allocate,
599 resource_size(res) + allocate); 674 resource_size(res) + allocate);
600 action = "cur grow up"; 675 action = "cur grow up";
@@ -604,8 +679,6 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
604 case ALLOC_MID: 679 case ALLOC_MID:
605 if (strcmp(next->name, label_id->id) == 0) { 680 if (strcmp(next->name, label_id->id) == 0) {
606 /* adjust next resource up */ 681 /* adjust next resource up */
607 if (is_pmem && !is_reserve)
608 return n;
609 rc = adjust_resource(next, next->start 682 rc = adjust_resource(next, next->start
610 - allocate, resource_size(next) 683 - allocate, resource_size(next)
611 + allocate); 684 + allocate);
@@ -629,12 +702,10 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
629 if (strcmp(action, "allocate") == 0) { 702 if (strcmp(action, "allocate") == 0) {
630 /* BLK allocate bottom up */ 703 /* BLK allocate bottom up */
631 if (!is_pmem) 704 if (!is_pmem)
632 free_start += available - allocate; 705 valid.start += available - allocate;
633 else if (!is_reserve && free_start != nd_mapping->start)
634 return n;
635 706
636 new_res = nvdimm_allocate_dpa(ndd, label_id, 707 new_res = nvdimm_allocate_dpa(ndd, label_id,
637 free_start, allocate); 708 valid.start, allocate);
638 if (!new_res) 709 if (!new_res)
639 rc = -EBUSY; 710 rc = -EBUSY;
640 } else if (strcmp(action, "grow down") == 0) { 711 } else if (strcmp(action, "grow down") == 0) {
@@ -832,13 +903,45 @@ static int grow_dpa_allocation(struct nd_region *nd_region,
832 return 0; 903 return 0;
833} 904}
834 905
835static void nd_namespace_pmem_set_size(struct nd_region *nd_region, 906static void nd_namespace_pmem_set_resource(struct nd_region *nd_region,
836 struct nd_namespace_pmem *nspm, resource_size_t size) 907 struct nd_namespace_pmem *nspm, resource_size_t size)
837{ 908{
838 struct resource *res = &nspm->nsio.res; 909 struct resource *res = &nspm->nsio.res;
910 resource_size_t offset = 0;
839 911
840 res->start = nd_region->ndr_start; 912 if (size && !nspm->uuid) {
841 res->end = nd_region->ndr_start + size - 1; 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;
842} 945}
843 946
844static bool uuid_not_set(const u8 *uuid, struct device *dev, const char *where) 947static 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)
929 if (is_namespace_pmem(dev)) { 1032 if (is_namespace_pmem(dev)) {
930 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); 1033 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
931 1034
932 nd_namespace_pmem_set_size(nd_region, nspm, 1035 nd_namespace_pmem_set_resource(nd_region, nspm,
933 val * nd_region->ndr_mappings); 1036 val * nd_region->ndr_mappings);
934 } else if (is_namespace_blk(dev)) { 1037 } else if (is_namespace_blk(dev)) {
935 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); 1038 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
@@ -1031,22 +1134,27 @@ static ssize_t size_show(struct device *dev,
1031} 1134}
1032static DEVICE_ATTR(size, S_IRUGO, size_show, size_store); 1135static DEVICE_ATTR(size, S_IRUGO, size_show, size_store);
1033 1136
1034static ssize_t uuid_show(struct device *dev, 1137static u8 *namespace_to_uuid(struct device *dev)
1035 struct device_attribute *attr, char *buf)
1036{ 1138{
1037 u8 *uuid;
1038
1039 if (is_namespace_pmem(dev)) { 1139 if (is_namespace_pmem(dev)) {
1040 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); 1140 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
1041 1141
1042 uuid = nspm->uuid; 1142 return nspm->uuid;
1043 } else if (is_namespace_blk(dev)) { 1143 } else if (is_namespace_blk(dev)) {
1044 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); 1144 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
1045 1145
1046 uuid = nsblk->uuid; 1146 return nsblk->uuid;
1047 } else 1147 } else
1048 return -ENXIO; 1148 return ERR_PTR(-ENXIO);
1149}
1049 1150
1151static 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);
1050 if (uuid) 1158 if (uuid)
1051 return sprintf(buf, "%pUb\n", uuid); 1159 return sprintf(buf, "%pUb\n", uuid);
1052 return sprintf(buf, "\n"); 1160 return sprintf(buf, "\n");
@@ -1089,7 +1197,7 @@ static int namespace_update_uuid(struct nd_region *nd_region,
1089 * 1197 *
1090 * FIXME: can we delete uuid with zero dpa allocated? 1198 * FIXME: can we delete uuid with zero dpa allocated?
1091 */ 1199 */
1092 if (nd_mapping->labels) 1200 if (list_empty(&nd_mapping->labels))
1093 return -EBUSY; 1201 return -EBUSY;
1094 } 1202 }
1095 1203
@@ -1491,14 +1599,19 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid,
1491 1599
1492 for (i = 0; i < nd_region->ndr_mappings; i++) { 1600 for (i = 0; i < nd_region->ndr_mappings; i++) {
1493 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1601 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1494 struct nd_namespace_label *nd_label; 1602 struct nd_label_ent *label_ent;
1495 bool found_uuid = false; 1603 bool found_uuid = false;
1496 int l;
1497 1604
1498 for_each_label(l, nd_label, nd_mapping->labels) { 1605 list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1499 u64 isetcookie = __le64_to_cpu(nd_label->isetcookie); 1606 struct nd_namespace_label *nd_label = label_ent->label;
1500 u16 position = __le16_to_cpu(nd_label->position); 1607 u16 position, nlabel;
1501 u16 nlabel = __le16_to_cpu(nd_label->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);
1502 1615
1503 if (isetcookie != cookie) 1616 if (isetcookie != cookie)
1504 continue; 1617 continue;
@@ -1528,7 +1641,6 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid,
1528 1641
1529static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id) 1642static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1530{ 1643{
1531 struct nd_namespace_label *select = NULL;
1532 int i; 1644 int i;
1533 1645
1534 if (!pmem_id) 1646 if (!pmem_id)
@@ -1536,90 +1648,106 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1536 1648
1537 for (i = 0; i < nd_region->ndr_mappings; i++) { 1649 for (i = 0; i < nd_region->ndr_mappings; i++) {
1538 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1650 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;
1540 u64 hw_start, hw_end, pmem_start, pmem_end; 1653 u64 hw_start, hw_end, pmem_start, pmem_end;
1541 int l; 1654 struct nd_label_ent *label_ent;
1542 1655
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;
1544 if (memcmp(nd_label->uuid, pmem_id, NSLABEL_UUID_LEN) == 0) 1661 if (memcmp(nd_label->uuid, pmem_id, NSLABEL_UUID_LEN) == 0)
1545 break; 1662 break;
1663 nd_label = NULL;
1664 }
1546 1665
1547 if (!nd_label) { 1666 if (!nd_label) {
1548 WARN_ON(1); 1667 WARN_ON(1);
1549 return -EINVAL; 1668 return -EINVAL;
1550 } 1669 }
1551 1670
1552 select = nd_label;
1553 /* 1671 /*
1554 * Check that this label is compliant with the dpa 1672 * Check that this label is compliant with the dpa
1555 * range published in NFIT 1673 * range published in NFIT
1556 */ 1674 */
1557 hw_start = nd_mapping->start; 1675 hw_start = nd_mapping->start;
1558 hw_end = hw_start + nd_mapping->size; 1676 hw_end = hw_start + nd_mapping->size;
1559 pmem_start = __le64_to_cpu(select->dpa); 1677 pmem_start = __le64_to_cpu(nd_label->dpa);
1560 pmem_end = pmem_start + __le64_to_cpu(select->rawsize); 1678 pmem_end = pmem_start + __le64_to_cpu(nd_label->rawsize);
1561 if (pmem_start == hw_start && pmem_end <= hw_end) 1679 if (pmem_start >= hw_start && pmem_start < hw_end
1680 && pmem_end <= hw_end && pmem_end > hw_start)
1562 /* pass */; 1681 /* 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);
1564 return -EINVAL; 1685 return -EINVAL;
1686 }
1565 1687
1566 nd_mapping->labels[0] = select; 1688 /* move recently validated label to the front of the list */
1567 nd_mapping->labels[1] = NULL; 1689 list_move(&label_ent->list, &nd_mapping->labels);
1568 } 1690 }
1569 return 0; 1691 return 0;
1570} 1692}
1571 1693
1572/** 1694/**
1573 * find_pmem_label_set - validate interleave set labelling, retrieve label0 1695 * create_namespace_pmem - validate interleave set labelling, retrieve label0
1574 * @nd_region: region with mappings to validate 1696 * @nd_region: region with mappings to validate
1697 * @nspm: target namespace to create
1698 * @nd_label: target pmem namespace label to evaluate
1575 */ 1699 */
1576static int find_pmem_label_set(struct nd_region *nd_region, 1700struct device *create_namespace_pmem(struct nd_region *nd_region,
1577 struct nd_namespace_pmem *nspm) 1701 struct nd_namespace_label *nd_label)
1578{ 1702{
1579 u64 cookie = nd_region_interleave_set_cookie(nd_region); 1703 u64 cookie = nd_region_interleave_set_cookie(nd_region);
1580 struct nd_namespace_label *nd_label; 1704 struct nd_label_ent *label_ent;
1581 u8 select_id[NSLABEL_UUID_LEN]; 1705 struct nd_namespace_pmem *nspm;
1706 struct nd_mapping *nd_mapping;
1582 resource_size_t size = 0; 1707 resource_size_t size = 0;
1583 u8 *pmem_id = NULL; 1708 struct resource *res;
1584 int rc = -ENODEV, l; 1709 struct device *dev;
1710 int rc = 0;
1585 u16 i; 1711 u16 i;
1586 1712
1587 if (cookie == 0) 1713 if (cookie == 0) {
1588 return -ENXIO; 1714 dev_dbg(&nd_region->dev, "invalid interleave-set-cookie\n");
1715 return ERR_PTR(-ENXIO);
1716 }
1589 1717
1590 /* 1718 if (__le64_to_cpu(nd_label->isetcookie) != cookie) {
1591 * Find a complete set of labels by uuid. By definition we can start 1719 dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n",
1592 * with any mapping as the reference label 1720 nd_label->uuid);
1593 */ 1721 return ERR_PTR(-EAGAIN);
1594 for_each_label(l, nd_label, nd_region->mapping[0].labels) { 1722 }
1595 u64 isetcookie = __le64_to_cpu(nd_label->isetcookie);
1596 1723
1597 if (isetcookie != cookie) 1724 nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
1598 continue; 1725 if (!nspm)
1726 return ERR_PTR(-ENOMEM);
1599 1727
1600 for (i = 0; nd_region->ndr_mappings; i++) 1728 nspm->id = -1;
1601 if (!has_uuid_at_pos(nd_region, nd_label->uuid, 1729 dev = &nspm->nsio.common.dev;
1602 cookie, i)) 1730 dev->type = &namespace_pmem_device_type;
1603 break; 1731 dev->parent = &nd_region->dev;
1604 if (i < nd_region->ndr_mappings) { 1732 res = &nspm->nsio.res;
1605 /* 1733 res->name = dev_name(&nd_region->dev);
1606 * Give up if we don't find an instance of a 1734 res->flags = IORESOURCE_MEM;
1607 * uuid at each position (from 0 to 1735
1608 * nd_region->ndr_mappings - 1), or if we find a 1736 for (i = 0; i < nd_region->ndr_mappings; i++)
1609 * dimm with two instances of the same uuid. 1737 if (!has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
1610 */ 1738 break;
1611 rc = -EINVAL; 1739 if (i < nd_region->ndr_mappings) {
1612 goto err; 1740 struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]);
1613 } else if (pmem_id) { 1741
1614 /* 1742 /*
1615 * If there is more than one valid uuid set, we 1743 * Give up if we don't find an instance of a uuid at each
1616 * need userspace to clean this up. 1744 * position (from 0 to nd_region->ndr_mappings - 1), or if we
1617 */ 1745 * find a dimm with two instances of the same uuid.
1618 rc = -EBUSY; 1746 */
1619 goto err; 1747 dev_err(&nd_region->dev, "%s missing label for %pUb\n",
1620 } 1748 dev_name(ndd->dev), nd_label->uuid);
1621 memcpy(select_id, nd_label->uuid, NSLABEL_UUID_LEN); 1749 rc = -EINVAL;
1622 pmem_id = select_id; 1750 goto err;
1623 } 1751 }
1624 1752
1625 /* 1753 /*
@@ -1630,14 +1758,23 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1630 * the dimm being enabled (i.e. nd_label_reserve_dpa() 1758 * the dimm being enabled (i.e. nd_label_reserve_dpa()
1631 * succeeded). 1759 * succeeded).
1632 */ 1760 */
1633 rc = select_pmem_id(nd_region, pmem_id); 1761 rc = select_pmem_id(nd_region, nd_label->uuid);
1634 if (rc) 1762 if (rc)
1635 goto err; 1763 goto err;
1636 1764
1637 /* Calculate total size and populate namespace properties from label0 */ 1765 /* Calculate total size and populate namespace properties from label0 */
1638 for (i = 0; i < nd_region->ndr_mappings; i++) { 1766 for (i = 0; i < nd_region->ndr_mappings; i++) {
1639 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1767 struct nd_namespace_label *label0;
1640 struct nd_namespace_label *label0 = nd_mapping->labels[0]; 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 }
1641 1778
1642 size += __le64_to_cpu(label0->rawsize); 1779 size += __le64_to_cpu(label0->rawsize);
1643 if (__le16_to_cpu(label0->position) != 0) 1780 if (__le16_to_cpu(label0->position) != 0)
@@ -1654,10 +1791,11 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1654 goto err; 1791 goto err;
1655 } 1792 }
1656 1793
1657 nd_namespace_pmem_set_size(nd_region, nspm, size); 1794 nd_namespace_pmem_set_resource(nd_region, nspm, size);
1658 1795
1659 return 0; 1796 return dev;
1660 err: 1797 err:
1798 namespace_pmem_release(dev);
1661 switch (rc) { 1799 switch (rc) {
1662 case -EINVAL: 1800 case -EINVAL:
1663 dev_dbg(&nd_region->dev, "%s: invalid label(s)\n", __func__); 1801 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,
1670 __func__, rc); 1808 __func__, rc);
1671 break; 1809 break;
1672 } 1810 }
1673 return rc; 1811 return ERR_PTR(rc);
1674}
1675
1676static 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;
1722} 1812}
1723 1813
1724struct resource *nsblk_add_resource(struct nd_region *nd_region, 1814struct 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)
1770 return &nsblk->common.dev; 1860 return &nsblk->common.dev;
1771} 1861}
1772 1862
1773void nd_region_create_blk_seed(struct nd_region *nd_region) 1863static 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
1896void nd_region_create_ns_seed(struct nd_region *nd_region)
1774{ 1897{
1775 WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); 1898 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
1777 /* 1908 /*
1778 * Seed creation failures are not fatal, provisioning is simply 1909 * Seed creation failures are not fatal, provisioning is simply
1779 * disabled until memory becomes available 1910 * disabled until memory becomes available
1780 */ 1911 */
1781 if (!nd_region->ns_seed) 1912 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");
1783 else 1915 else
1784 nd_device_register(nd_region->ns_seed); 1916 nd_device_register(nd_region->ns_seed);
1785} 1917}
@@ -1820,43 +1952,137 @@ void nd_region_create_btt_seed(struct nd_region *nd_region)
1820 dev_err(&nd_region->dev, "failed to create btt namespace\n"); 1952 dev_err(&nd_region->dev, "failed to create btt namespace\n");
1821} 1953}
1822 1954
1823static struct device **create_namespace_blk(struct nd_region *nd_region) 1955static int add_namespace_resource(struct nd_region *nd_region,
1956 struct nd_namespace_label *nd_label, struct device **devs,
1957 int count)
1824{ 1958{
1825 struct nd_mapping *nd_mapping = &nd_region->mapping[0]; 1959 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1826 struct nd_namespace_label *nd_label; 1960 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1827 struct device *dev, **devs = NULL; 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
1993struct 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);
1828 struct nd_namespace_blk *nsblk; 1999 struct nd_namespace_blk *nsblk;
1829 struct nvdimm_drvdata *ndd; 2000 char *name[NSLABEL_NAME_LEN];
1830 int i, l, count = 0; 2001 struct device *dev = NULL;
1831 struct resource *res; 2002 struct resource *res;
1832 2003
1833 if (nd_region->ndr_mappings == 0) 2004 nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
1834 return NULL; 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
2031static 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}
1835 2055
1836 ndd = to_ndd(nd_mapping); 2056static struct device **scan_labels(struct nd_region *nd_region)
1837 for_each_label(l, nd_label, nd_mapping->labels) { 2057{
1838 u32 flags = __le32_to_cpu(nd_label->flags); 2058 int i, count = 0;
1839 char *name[NSLABEL_NAME_LEN]; 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;
1840 struct device **__devs; 2067 struct device **__devs;
2068 u32 flags;
1841 2069
1842 if (flags & NSLABEL_FLAG_LOCAL) 2070 if (!nd_label)
1843 /* pass */; 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 */;
1844 else 2076 else
1845 continue; 2077 continue;
1846 2078
1847 for (i = 0; i < count; i++) { 2079 /* skip labels that describe extents outside of the region */
1848 nsblk = to_nd_namespace_blk(devs[i]); 2080 if (nd_label->dpa < nd_mapping->start || nd_label->dpa > map_end)
1849 if (memcmp(nsblk->uuid, nd_label->uuid, 2081 continue;
1850 NSLABEL_UUID_LEN) == 0) { 2082
1851 res = nsblk_add_resource(nd_region, ndd, nsblk, 2083 i = add_namespace_resource(nd_region, nd_label, devs, count);
1852 __le64_to_cpu(nd_label->dpa)); 2084 if (i < 0)
1853 if (!res) 2085 goto err;
1854 goto err;
1855 nd_dbg_dpa(nd_region, ndd, res, "%s assign\n",
1856 dev_name(&nsblk->common.dev));
1857 break;
1858 }
1859 }
1860 if (i < count) 2086 if (i < count)
1861 continue; 2087 continue;
1862 __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL); 2088 __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
@@ -1866,67 +2092,126 @@ static struct device **create_namespace_blk(struct nd_region *nd_region)
1866 kfree(devs); 2092 kfree(devs);
1867 devs = __devs; 2093 devs = __devs;
1868 2094
1869 nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL); 2095 if (is_nd_blk(&nd_region->dev)) {
1870 if (!nsblk) 2096 dev = create_namespace_blk(nd_region, nd_label, count);
1871 goto err; 2097 if (IS_ERR(dev))
1872 dev = &nsblk->common.dev; 2098 goto err;
1873 dev->type = &namespace_blk_device_type; 2099 devs[count++] = dev;
1874 dev->parent = &nd_region->dev; 2100 } else {
1875 dev_set_name(dev, "namespace%d.%d", nd_region->id, count); 2101 dev = create_namespace_pmem(nd_region, nd_label);
1876 devs[count++] = dev; 2102 if (IS_ERR(dev)) {
1877 nsblk->id = -1; 2103 switch (PTR_ERR(dev)) {
1878 nsblk->lbasize = __le64_to_cpu(nd_label->lbasize); 2104 case -EAGAIN:
1879 nsblk->uuid = kmemdup(nd_label->uuid, NSLABEL_UUID_LEN, 2105 /* skip invalid labels */
1880 GFP_KERNEL); 2106 continue;
1881 if (!nsblk->uuid) 2107 case -ENODEV:
1882 goto err; 2108 /* fallthrough to seed creation */
1883 memcpy(name, nd_label->name, NSLABEL_NAME_LEN); 2109 break;
1884 if (name[0]) 2110 default:
1885 nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN, 2111 goto err;
1886 GFP_KERNEL); 2112 }
1887 res = nsblk_add_resource(nd_region, ndd, nsblk, 2113 } else
1888 __le64_to_cpu(nd_label->dpa)); 2114 devs[count++] = dev;
1889 if (!res) 2115 }
1890 goto err;
1891 nd_dbg_dpa(nd_region, ndd, res, "%s assign\n",
1892 dev_name(&nsblk->common.dev));
1893 } 2116 }
1894 2117
1895 dev_dbg(&nd_region->dev, "%s: discovered %d blk namespace%s\n", 2118 dev_dbg(&nd_region->dev, "%s: discovered %d %s namespace%s\n",
1896 __func__, count, count == 1 ? "" : "s"); 2119 __func__, count, is_nd_blk(&nd_region->dev)
2120 ? "blk" : "pmem", count == 1 ? "" : "s");
1897 2121
1898 if (count == 0) { 2122 if (count == 0) {
1899 /* Publish a zero-sized namespace for userspace to configure. */ 2123 /* Publish a zero-sized namespace for userspace to configure. */
1900 for (i = 0; i < nd_region->ndr_mappings; i++) { 2124 nd_mapping_free_labels(nd_mapping);
1901 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1902
1903 kfree(nd_mapping->labels);
1904 nd_mapping->labels = NULL;
1905 }
1906 2125
1907 devs = kcalloc(2, sizeof(dev), GFP_KERNEL); 2126 devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
1908 if (!devs) 2127 if (!devs)
1909 goto err; 2128 goto err;
1910 nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL); 2129 if (is_nd_blk(&nd_region->dev)) {
1911 if (!nsblk) 2130 struct nd_namespace_blk *nsblk;
1912 goto err; 2131
1913 dev = &nsblk->common.dev; 2132 nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL);
1914 dev->type = &namespace_blk_device_type; 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 }
1915 dev->parent = &nd_region->dev; 2147 dev->parent = &nd_region->dev;
1916 devs[count++] = dev; 2148 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 }
1917 } 2171 }
1918 2172
2173 if (count > 1)
2174 sort(devs, count, sizeof(struct device *), cmp_dpa, NULL);
2175
1919 return devs; 2176 return devs;
1920 2177
1921err: 2178 err:
1922 for (i = 0; i < count; i++) { 2179 for (i = 0; devs[i]; i++)
1923 nsblk = to_nd_namespace_blk(devs[i]); 2180 if (is_nd_blk(&nd_region->dev))
1924 namespace_blk_release(&nsblk->common.dev); 2181 namespace_blk_release(devs[i]);
1925 } 2182 else
2183 namespace_pmem_release(devs[i]);
1926 kfree(devs); 2184 kfree(devs);
1927 return NULL; 2185 return NULL;
1928} 2186}
1929 2187
2188static 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
1930static int init_active_labels(struct nd_region *nd_region) 2215static int init_active_labels(struct nd_region *nd_region)
1931{ 2216{
1932 int i; 2217 int i;
@@ -1935,6 +2220,7 @@ static int init_active_labels(struct nd_region *nd_region)
1935 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 2220 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1936 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 2221 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1937 struct nvdimm *nvdimm = nd_mapping->nvdimm; 2222 struct nvdimm *nvdimm = nd_mapping->nvdimm;
2223 struct nd_label_ent *label_ent;
1938 int count, j; 2224 int count, j;
1939 2225
1940 /* 2226 /*
@@ -1956,16 +2242,27 @@ static int init_active_labels(struct nd_region *nd_region)
1956 dev_dbg(ndd->dev, "%s: %d\n", __func__, count); 2242 dev_dbg(ndd->dev, "%s: %d\n", __func__, count);
1957 if (!count) 2243 if (!count)
1958 continue; 2244 continue;
1959 nd_mapping->labels = kcalloc(count + 1, sizeof(void *),
1960 GFP_KERNEL);
1961 if (!nd_mapping->labels)
1962 return -ENOMEM;
1963 for (j = 0; j < count; j++) { 2245 for (j = 0; j < count; j++) {
1964 struct nd_namespace_label *label; 2246 struct nd_namespace_label *label;
1965 2247
2248 label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
2249 if (!label_ent)
2250 break;
1966 label = nd_label_active(ndd, j); 2251 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);
1968 } 2257 }
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;
1969 } 2266 }
1970 2267
1971 return 0; 2268 return 0;
@@ -1990,10 +2287,8 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
1990 devs = create_namespace_io(nd_region); 2287 devs = create_namespace_io(nd_region);
1991 break; 2288 break;
1992 case ND_DEVICE_NAMESPACE_PMEM: 2289 case ND_DEVICE_NAMESPACE_PMEM:
1993 devs = create_namespace_pmem(nd_region);
1994 break;
1995 case ND_DEVICE_NAMESPACE_BLK: 2290 case ND_DEVICE_NAMESPACE_BLK:
1996 devs = create_namespace_blk(nd_region); 2291 devs = create_namespaces(nd_region);
1997 break; 2292 break;
1998 default: 2293 default:
1999 break; 2294 break;
@@ -2014,6 +2309,13 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
2014 id = ida_simple_get(&nd_region->ns_ida, 0, 0, 2309 id = ida_simple_get(&nd_region->ns_ida, 0, 0,
2015 GFP_KERNEL); 2310 GFP_KERNEL);
2016 nsblk->id = id; 2311 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;
2017 } else 2319 } else
2018 id = i; 2320 id = i;
2019 2321
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index 38ce6bbbc170..8623e57c2ce3 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -44,6 +44,23 @@ struct nvdimm {
44 struct resource *flush_wpq; 44 struct resource *flush_wpq;
45}; 45};
46 46
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 */
58struct blk_alloc_info {
59 struct nd_mapping *nd_mapping;
60 resource_size_t available, busy;
61 struct resource *res;
62};
63
47bool is_nvdimm(struct device *dev); 64bool is_nvdimm(struct device *dev);
48bool is_nd_pmem(struct device *dev); 65bool is_nd_pmem(struct device *dev);
49bool is_nd_blk(struct device *dev); 66bool is_nd_blk(struct device *dev);
@@ -54,7 +71,7 @@ void nvdimm_devs_exit(void);
54void nd_region_devs_exit(void); 71void nd_region_devs_exit(void);
55void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev); 72void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev);
56struct nd_region; 73struct nd_region;
57void nd_region_create_blk_seed(struct nd_region *nd_region); 74void nd_region_create_ns_seed(struct nd_region *nd_region);
58void nd_region_create_btt_seed(struct nd_region *nd_region); 75void nd_region_create_btt_seed(struct nd_region *nd_region);
59void nd_region_create_pfn_seed(struct nd_region *nd_region); 76void nd_region_create_pfn_seed(struct nd_region *nd_region);
60void nd_region_create_dax_seed(struct nd_region *nd_region); 77void nd_region_create_dax_seed(struct nd_region *nd_region);
@@ -73,13 +90,14 @@ bool nd_is_uuid_unique(struct device *dev, u8 *uuid);
73struct nd_region; 90struct nd_region;
74struct nvdimm_drvdata; 91struct nvdimm_drvdata;
75struct nd_mapping; 92struct nd_mapping;
93void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
76resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, 94resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
77 struct nd_mapping *nd_mapping, resource_size_t *overlap); 95 struct nd_mapping *nd_mapping, resource_size_t *overlap);
78resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping); 96resource_size_t nd_blk_available_dpa(struct nd_region *nd_region);
79resource_size_t nd_region_available_dpa(struct nd_region *nd_region); 97resource_size_t nd_region_available_dpa(struct nd_region *nd_region);
80resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd, 98resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
81 struct nd_label_id *label_id); 99 struct nd_label_id *label_id);
82struct nd_mapping; 100int alias_dpa_busy(struct device *dev, void *data);
83struct resource *nsblk_add_resource(struct nd_region *nd_region, 101struct resource *nsblk_add_resource(struct nd_region *nd_region,
84 struct nvdimm_drvdata *ndd, struct nd_namespace_blk *nsblk, 102 struct nvdimm_drvdata *ndd, struct nd_namespace_blk *nsblk,
85 resource_size_t start); 103 resource_size_t start);
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 0b78a8211f4a..d3b2fca8deec 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -101,9 +101,6 @@ static inline struct nd_namespace_index *to_next_namespace_index(
101 (unsigned long long) (res ? resource_size(res) : 0), \ 101 (unsigned long long) (res ? resource_size(res) : 0), \
102 (unsigned long long) (res ? res->start : 0), ##arg) 102 (unsigned long long) (res ? res->start : 0), ##arg)
103 103
104#define for_each_label(l, label, labels) \
105 for (l = 0; (label = labels ? labels[l] : NULL); l++)
106
107#define for_each_dpa_resource(ndd, res) \ 104#define for_each_dpa_resource(ndd, res) \
108 for (res = (ndd)->dpa.child; res; res = res->sibling) 105 for (res = (ndd)->dpa.child; res; res = res->sibling)
109 106
@@ -116,6 +113,31 @@ struct nd_percpu_lane {
116 spinlock_t lock; 113 spinlock_t lock;
117}; 114};
118 115
116struct nd_label_ent {
117 struct list_head list;
118 struct nd_namespace_label *label;
119};
120
121enum nd_mapping_lock_class {
122 ND_MAPPING_CLASS0,
123 ND_MAPPING_UUID_SCAN,
124};
125
126struct 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
119struct nd_region { 141struct nd_region {
120 struct device dev; 142 struct device dev;
121 struct ida ns_ida; 143 struct ida ns_ida;
@@ -209,6 +231,7 @@ void nvdimm_exit(void);
209void nd_region_exit(void); 231void nd_region_exit(void);
210struct nvdimm; 232struct nvdimm;
211struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping); 233struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping);
234int nvdimm_check_config_data(struct device *dev);
212int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd); 235int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd);
213int nvdimm_init_config_data(struct nvdimm_drvdata *ndd); 236int nvdimm_init_config_data(struct nvdimm_drvdata *ndd);
214int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, 237int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 571a6c7ee2fc..42b3a8217073 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -66,13 +66,32 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
66 invalidate_pmem(pmem->virt_addr + offset, len); 66 invalidate_pmem(pmem->virt_addr + offset, len);
67} 67}
68 68
69static 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
78static 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
69static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, 89static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
70 unsigned int len, unsigned int off, bool is_write, 90 unsigned int len, unsigned int off, bool is_write,
71 sector_t sector) 91 sector_t sector)
72{ 92{
73 int rc = 0; 93 int rc = 0;
74 bool bad_pmem = false; 94 bool bad_pmem = false;
75 void *mem = kmap_atomic(page);
76 phys_addr_t pmem_off = sector * 512 + pmem->data_offset; 95 phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
77 void *pmem_addr = pmem->virt_addr + pmem_off; 96 void *pmem_addr = pmem->virt_addr + pmem_off;
78 97
@@ -83,7 +102,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
83 if (unlikely(bad_pmem)) 102 if (unlikely(bad_pmem))
84 rc = -EIO; 103 rc = -EIO;
85 else { 104 else {
86 rc = memcpy_from_pmem(mem + off, pmem_addr, len); 105 rc = read_pmem(page, off, pmem_addr, len);
87 flush_dcache_page(page); 106 flush_dcache_page(page);
88 } 107 }
89 } else { 108 } else {
@@ -102,14 +121,13 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
102 * after clear poison. 121 * after clear poison.
103 */ 122 */
104 flush_dcache_page(page); 123 flush_dcache_page(page);
105 memcpy_to_pmem(pmem_addr, mem + off, len); 124 write_pmem(pmem_addr, page, off, len);
106 if (unlikely(bad_pmem)) { 125 if (unlikely(bad_pmem)) {
107 pmem_clear_poison(pmem, pmem_off, len); 126 pmem_clear_poison(pmem, pmem_off, len);
108 memcpy_to_pmem(pmem_addr, mem + off, len); 127 write_pmem(pmem_addr, page, off, len);
109 } 128 }
110 } 129 }
111 130
112 kunmap_atomic(mem);
113 return rc; 131 return rc;
114} 132}
115 133
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index f9d58c2b5341..6af5e629140c 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -313,9 +313,8 @@ resource_size_t nd_region_available_dpa(struct nd_region *nd_region)
313 blk_max_overlap = overlap; 313 blk_max_overlap = overlap;
314 goto retry; 314 goto retry;
315 } 315 }
316 } else if (is_nd_blk(&nd_region->dev)) { 316 } else if (is_nd_blk(&nd_region->dev))
317 available += nd_blk_available_dpa(nd_mapping); 317 available += nd_blk_available_dpa(nd_region);
318 }
319 } 318 }
320 319
321 return available; 320 return available;
@@ -506,6 +505,17 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region)
506 return 0; 505 return 0;
507} 506}
508 507
508void 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
509/* 519/*
510 * Upon successful probe/remove, take/release a reference on the 520 * Upon successful probe/remove, take/release a reference on the
511 * associated interleave set (if present), and plant new btt + namespace 521 * 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,
526 struct nvdimm_drvdata *ndd = nd_mapping->ndd; 536 struct nvdimm_drvdata *ndd = nd_mapping->ndd;
527 struct nvdimm *nvdimm = nd_mapping->nvdimm; 537 struct nvdimm *nvdimm = nd_mapping->nvdimm;
528 538
529 kfree(nd_mapping->labels); 539 mutex_lock(&nd_mapping->lock);
530 nd_mapping->labels = NULL; 540 nd_mapping_free_labels(nd_mapping);
541 mutex_unlock(&nd_mapping->lock);
542
531 put_ndd(ndd); 543 put_ndd(ndd);
532 nd_mapping->ndd = NULL; 544 nd_mapping->ndd = NULL;
533 if (ndd) 545 if (ndd)
@@ -537,11 +549,12 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
537 if (is_nd_pmem(dev)) 549 if (is_nd_pmem(dev))
538 return; 550 return;
539 } 551 }
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) {
541 nd_region = to_nd_region(dev->parent); 554 nd_region = to_nd_region(dev->parent);
542 nvdimm_bus_lock(dev); 555 nvdimm_bus_lock(dev);
543 if (nd_region->ns_seed == dev) 556 if (nd_region->ns_seed == dev)
544 nd_region_create_blk_seed(nd_region); 557 nd_region_create_ns_seed(nd_region);
545 nvdimm_bus_unlock(dev); 558 nvdimm_bus_unlock(dev);
546 } 559 }
547 if (is_nd_btt(dev) && probe) { 560 if (is_nd_btt(dev) && probe) {
@@ -551,23 +564,30 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
551 nvdimm_bus_lock(dev); 564 nvdimm_bus_lock(dev);
552 if (nd_region->btt_seed == dev) 565 if (nd_region->btt_seed == dev)
553 nd_region_create_btt_seed(nd_region); 566 nd_region_create_btt_seed(nd_region);
554 if (nd_region->ns_seed == &nd_btt->ndns->dev && 567 if (nd_region->ns_seed == &nd_btt->ndns->dev)
555 is_nd_blk(dev->parent)) 568 nd_region_create_ns_seed(nd_region);
556 nd_region_create_blk_seed(nd_region);
557 nvdimm_bus_unlock(dev); 569 nvdimm_bus_unlock(dev);
558 } 570 }
559 if (is_nd_pfn(dev) && probe) { 571 if (is_nd_pfn(dev) && probe) {
572 struct nd_pfn *nd_pfn = to_nd_pfn(dev);
573
560 nd_region = to_nd_region(dev->parent); 574 nd_region = to_nd_region(dev->parent);
561 nvdimm_bus_lock(dev); 575 nvdimm_bus_lock(dev);
562 if (nd_region->pfn_seed == dev) 576 if (nd_region->pfn_seed == dev)
563 nd_region_create_pfn_seed(nd_region); 577 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);
564 nvdimm_bus_unlock(dev); 580 nvdimm_bus_unlock(dev);
565 } 581 }
566 if (is_nd_dax(dev) && probe) { 582 if (is_nd_dax(dev) && probe) {
583 struct nd_dax *nd_dax = to_nd_dax(dev);
584
567 nd_region = to_nd_region(dev->parent); 585 nd_region = to_nd_region(dev->parent);
568 nvdimm_bus_lock(dev); 586 nvdimm_bus_lock(dev);
569 if (nd_region->dax_seed == dev) 587 if (nd_region->dax_seed == dev)
570 nd_region_create_dax_seed(nd_region); 588 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);
571 nvdimm_bus_unlock(dev); 591 nvdimm_bus_unlock(dev);
572 } 592 }
573} 593}
@@ -774,10 +794,10 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
774 int ro = 0; 794 int ro = 0;
775 795
776 for (i = 0; i < ndr_desc->num_mappings; i++) { 796 for (i = 0; i < ndr_desc->num_mappings; i++) {
777 struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i]; 797 struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
778 struct nvdimm *nvdimm = nd_mapping->nvdimm; 798 struct nvdimm *nvdimm = mapping->nvdimm;
779 799
780 if ((nd_mapping->start | nd_mapping->size) % SZ_4K) { 800 if ((mapping->start | mapping->size) % SZ_4K) {
781 dev_err(&nvdimm_bus->dev, "%s: %s mapping%d is not 4K aligned\n", 801 dev_err(&nvdimm_bus->dev, "%s: %s mapping%d is not 4K aligned\n",
782 caller, dev_name(&nvdimm->dev), i); 802 caller, dev_name(&nvdimm->dev), i);
783 803
@@ -828,11 +848,15 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
828 ndl->count = 0; 848 ndl->count = 0;
829 } 849 }
830 850
831 memcpy(nd_region->mapping, ndr_desc->nd_mapping,
832 sizeof(struct nd_mapping) * ndr_desc->num_mappings);
833 for (i = 0; i < ndr_desc->num_mappings; i++) { 851 for (i = 0; i < ndr_desc->num_mappings; i++) {
834 struct nd_mapping *nd_mapping = &ndr_desc->nd_mapping[i]; 852 struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
835 struct nvdimm *nvdimm = nd_mapping->nvdimm; 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);
836 860
837 get_device(&nvdimm->dev); 861 get_device(&nvdimm->dev);
838 } 862 }
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index b519e137b9b7..f4947fda11e7 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -50,23 +50,6 @@ typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc,
50 struct nvdimm *nvdimm, unsigned int cmd, void *buf, 50 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
51 unsigned int buf_len, int *cmd_rc); 51 unsigned int buf_len, int *cmd_rc);
52 52
53struct nd_namespace_label;
54struct nvdimm_drvdata;
55
56struct 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
70struct nvdimm_bus_descriptor { 53struct nvdimm_bus_descriptor {
71 const struct attribute_group **attr_groups; 54 const struct attribute_group **attr_groups;
72 unsigned long cmd_mask; 55 unsigned long cmd_mask;
@@ -89,9 +72,15 @@ struct nd_interleave_set {
89 u64 cookie; 72 u64 cookie;
90}; 73};
91 74
75struct nd_mapping_desc {
76 struct nvdimm *nvdimm;
77 u64 start;
78 u64 size;
79};
80
92struct nd_region_desc { 81struct nd_region_desc {
93 struct resource *res; 82 struct resource *res;
94 struct nd_mapping *nd_mapping; 83 struct nd_mapping_desc *mapping;
95 u16 num_mappings; 84 u16 num_mappings;
96 const struct attribute_group **attr_groups; 85 const struct attribute_group **attr_groups;
97 struct nd_interleave_set *nd_set; 86 struct nd_interleave_set *nd_set;
@@ -129,6 +118,8 @@ static inline struct nd_blk_region_desc *to_blk_region_desc(
129} 118}
130 119
131int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length); 120int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
121void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
122 phys_addr_t start, unsigned int len);
132struct nvdimm_bus *nvdimm_bus_register(struct device *parent, 123struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
133 struct nvdimm_bus_descriptor *nfit_desc); 124 struct nvdimm_bus_descriptor *nfit_desc);
134void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus); 125void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
@@ -139,6 +130,7 @@ struct nd_blk_region *to_nd_blk_region(struct device *dev);
139struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus); 130struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus);
140struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus); 131struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus);
141const char *nvdimm_name(struct nvdimm *nvdimm); 132const char *nvdimm_name(struct nvdimm *nvdimm);
133struct kobject *nvdimm_kobj(struct nvdimm *nvdimm);
142unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm); 134unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm);
143void *nvdimm_provider_data(struct nvdimm *nvdimm); 135void *nvdimm_provider_data(struct nvdimm *nvdimm);
144struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 136struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
diff --git a/include/linux/nd.h b/include/linux/nd.h
index f1ea426d6a5e..fa66aeed441a 100644
--- a/include/linux/nd.h
+++ b/include/linux/nd.h
@@ -77,11 +77,13 @@ struct nd_namespace_io {
77 * @nsio: device and system physical address range to drive 77 * @nsio: device and system physical address range to drive
78 * @alt_name: namespace name supplied in the dimm label 78 * @alt_name: namespace name supplied in the dimm label
79 * @uuid: namespace name supplied in the dimm label 79 * @uuid: namespace name supplied in the dimm label
80 * @id: ida allocated id
80 */ 81 */
81struct nd_namespace_pmem { 82struct nd_namespace_pmem {
82 struct nd_namespace_io nsio; 83 struct nd_namespace_io nsio;
83 char *alt_name; 84 char *alt_name;
84 u8 *uuid; 85 u8 *uuid;
86 int id;
85}; 87};
86 88
87/** 89/**
@@ -105,19 +107,19 @@ struct nd_namespace_blk {
105 struct resource **res; 107 struct resource **res;
106}; 108};
107 109
108static inline struct nd_namespace_io *to_nd_namespace_io(struct device *dev) 110static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev)
109{ 111{
110 return container_of(dev, struct nd_namespace_io, common.dev); 112 return container_of(dev, struct nd_namespace_io, common.dev);
111} 113}
112 114
113static inline struct nd_namespace_pmem *to_nd_namespace_pmem(struct device *dev) 115static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev)
114{ 116{
115 struct nd_namespace_io *nsio = to_nd_namespace_io(dev); 117 struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
116 118
117 return container_of(nsio, struct nd_namespace_pmem, nsio); 119 return container_of(nsio, struct nd_namespace_pmem, nsio);
118} 120}
119 121
120static inline struct nd_namespace_blk *to_nd_namespace_blk(struct device *dev) 122static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev)
121{ 123{
122 return container_of(dev, struct nd_namespace_blk, common.dev); 124 return container_of(dev, struct nd_namespace_blk, common.dev);
123} 125}
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index ba5a8c79652a..ede5c6a62164 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -21,14 +21,16 @@ struct nd_cmd_smart {
21} __packed; 21} __packed;
22 22
23#define ND_SMART_HEALTH_VALID (1 << 0) 23#define ND_SMART_HEALTH_VALID (1 << 0)
24#define ND_SMART_TEMP_VALID (1 << 1) 24#define ND_SMART_SPARES_VALID (1 << 1)
25#define ND_SMART_SPARES_VALID (1 << 2) 25#define ND_SMART_USED_VALID (1 << 2)
26#define ND_SMART_ALARM_VALID (1 << 3) 26#define ND_SMART_TEMP_VALID (1 << 3)
27#define ND_SMART_USED_VALID (1 << 4) 27#define ND_SMART_CTEMP_VALID (1 << 4)
28#define ND_SMART_SHUTDOWN_VALID (1 << 5) 28#define ND_SMART_ALARM_VALID (1 << 9)
29#define ND_SMART_VENDOR_VALID (1 << 6) 29#define ND_SMART_SHUTDOWN_VALID (1 << 10)
30#define ND_SMART_TEMP_TRIP (1 << 0) 30#define ND_SMART_VENDOR_VALID (1 << 11)
31#define ND_SMART_SPARE_TRIP (1 << 1) 31#define ND_SMART_SPARE_TRIP (1 << 0)
32#define ND_SMART_TEMP_TRIP (1 << 1)
33#define ND_SMART_CTEMP_TRIP (1 << 2)
32#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0) 34#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
33#define ND_SMART_CRITICAL_HEALTH (1 << 1) 35#define ND_SMART_CRITICAL_HEALTH (1 << 1)
34#define ND_SMART_FATAL_HEALTH (1 << 2) 36#define ND_SMART_FATAL_HEALTH (1 << 2)
@@ -37,14 +39,15 @@ struct nd_smart_payload {
37 __u32 flags; 39 __u32 flags;
38 __u8 reserved0[4]; 40 __u8 reserved0[4];
39 __u8 health; 41 __u8 health;
40 __u16 temperature;
41 __u8 spares; 42 __u8 spares;
42 __u8 alarm_flags;
43 __u8 life_used; 43 __u8 life_used;
44 __u8 alarm_flags;
45 __u16 temperature;
46 __u16 ctrl_temperature;
47 __u8 reserved1[15];
44 __u8 shutdown_state; 48 __u8 shutdown_state;
45 __u8 reserved1;
46 __u32 vendor_size; 49 __u32 vendor_size;
47 __u8 vendor_data[108]; 50 __u8 vendor_data[92];
48} __packed; 51} __packed;
49 52
50struct nd_cmd_smart_threshold { 53struct nd_cmd_smart_threshold {
@@ -53,7 +56,8 @@ struct nd_cmd_smart_threshold {
53} __packed; 56} __packed;
54 57
55struct nd_smart_threshold_payload { 58struct nd_smart_threshold_payload {
56 __u16 alarm_control; 59 __u8 alarm_control;
60 __u8 reserved0;
57 __u16 temperature; 61 __u16 temperature;
58 __u8 spares; 62 __u8 spares;
59 __u8 reserved[3]; 63 __u8 reserved[3];
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index ad6dd0543019..582db95127ed 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -13,6 +13,7 @@ ldflags-y += --wrap=__release_region
13ldflags-y += --wrap=devm_memremap_pages 13ldflags-y += --wrap=devm_memremap_pages
14ldflags-y += --wrap=insert_resource 14ldflags-y += --wrap=insert_resource
15ldflags-y += --wrap=remove_resource 15ldflags-y += --wrap=remove_resource
16ldflags-y += --wrap=acpi_evaluate_object
16 17
17DRIVERS := ../../../drivers 18DRIVERS := ../../../drivers
18NVDIMM_SRC := $(DRIVERS)/nvdimm 19NVDIMM_SRC := $(DRIVERS)/nvdimm
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index c29f8dca9e67..3ccef732fce9 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/pfn_t.h> 19#include <linux/pfn_t.h>
20#include <linux/acpi.h>
20#include <linux/io.h> 21#include <linux/io.h>
21#include <linux/mm.h> 22#include <linux/mm.h>
22#include "nfit_test.h" 23#include "nfit_test.h"
@@ -73,7 +74,7 @@ void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size,
73 74
74 if (nfit_res) 75 if (nfit_res)
75 return (void __iomem *) nfit_res->buf + offset 76 return (void __iomem *) nfit_res->buf + offset
76 - nfit_res->res->start; 77 - nfit_res->res.start;
77 return fallback_fn(offset, size); 78 return fallback_fn(offset, size);
78} 79}
79 80
@@ -84,7 +85,7 @@ void __iomem *__wrap_devm_ioremap_nocache(struct device *dev,
84 85
85 if (nfit_res) 86 if (nfit_res)
86 return (void __iomem *) nfit_res->buf + offset 87 return (void __iomem *) nfit_res->buf + offset
87 - nfit_res->res->start; 88 - nfit_res->res.start;
88 return devm_ioremap_nocache(dev, offset, size); 89 return devm_ioremap_nocache(dev, offset, size);
89} 90}
90EXPORT_SYMBOL(__wrap_devm_ioremap_nocache); 91EXPORT_SYMBOL(__wrap_devm_ioremap_nocache);
@@ -95,7 +96,7 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
95 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 96 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
96 97
97 if (nfit_res) 98 if (nfit_res)
98 return nfit_res->buf + offset - nfit_res->res->start; 99 return nfit_res->buf + offset - nfit_res->res.start;
99 return devm_memremap(dev, offset, size, flags); 100 return devm_memremap(dev, offset, size, flags);
100} 101}
101EXPORT_SYMBOL(__wrap_devm_memremap); 102EXPORT_SYMBOL(__wrap_devm_memremap);
@@ -107,7 +108,7 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
107 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 108 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
108 109
109 if (nfit_res) 110 if (nfit_res)
110 return nfit_res->buf + offset - nfit_res->res->start; 111 return nfit_res->buf + offset - nfit_res->res.start;
111 return devm_memremap_pages(dev, res, ref, altmap); 112 return devm_memremap_pages(dev, res, ref, altmap);
112} 113}
113EXPORT_SYMBOL(__wrap_devm_memremap_pages); 114EXPORT_SYMBOL(__wrap_devm_memremap_pages);
@@ -128,7 +129,7 @@ void *__wrap_memremap(resource_size_t offset, size_t size,
128 struct nfit_test_resource *nfit_res = get_nfit_res(offset); 129 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
129 130
130 if (nfit_res) 131 if (nfit_res)
131 return nfit_res->buf + offset - nfit_res->res->start; 132 return nfit_res->buf + offset - nfit_res->res.start;
132 return memremap(offset, size, flags); 133 return memremap(offset, size, flags);
133} 134}
134EXPORT_SYMBOL(__wrap_memremap); 135EXPORT_SYMBOL(__wrap_memremap);
@@ -174,6 +175,63 @@ void __wrap_memunmap(void *addr)
174} 175}
175EXPORT_SYMBOL(__wrap_memunmap); 176EXPORT_SYMBOL(__wrap_memunmap);
176 177
178static bool nfit_test_release_region(struct device *dev,
179 struct resource *parent, resource_size_t start,
180 resource_size_t n);
181
182static 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
190static 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
198static 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
177static struct resource *nfit_test_request_region(struct device *dev, 235static struct resource *nfit_test_request_region(struct device *dev,
178 struct resource *parent, resource_size_t start, 236 struct resource *parent, resource_size_t start,
179 resource_size_t n, const char *name, int flags) 237 resource_size_t n, const char *name, int flags)
@@ -183,21 +241,57 @@ static struct resource *nfit_test_request_region(struct device *dev,
183 if (parent == &iomem_resource) { 241 if (parent == &iomem_resource) {
184 nfit_res = get_nfit_res(start); 242 nfit_res = get_nfit_res(start);
185 if (nfit_res) { 243 if (nfit_res) {
186 struct resource *res = nfit_res->res + 1; 244 struct nfit_test_request *req;
245 struct resource *res = NULL;
187 246
188 if (start + n > nfit_res->res->start 247 if (start + n > nfit_res->res.start
189 + resource_size(nfit_res->res)) { 248 + resource_size(&nfit_res->res)) {
190 pr_debug("%s: start: %llx n: %llx overflow: %pr\n", 249 pr_debug("%s: start: %llx n: %llx overflow: %pr\n",
191 __func__, start, n, 250 __func__, start, n,
192 nfit_res->res); 251 &nfit_res->res);
193 return NULL; 252 return NULL;
194 } 253 }
195 254
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
196 res->start = start; 274 res->start = start;
197 res->end = start + n - 1; 275 res->end = start + n - 1;
198 res->name = name; 276 res->name = name;
199 res->flags = resource_type(parent); 277 res->flags = resource_type(parent);
200 res->flags |= IORESOURCE_BUSY | flags; 278 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
201 pr_debug("%s: %pr\n", __func__, res); 295 pr_debug("%s: %pr\n", __func__, res);
202 return res; 296 return res;
203 } 297 }
@@ -241,29 +335,10 @@ struct resource *__wrap___devm_request_region(struct device *dev,
241} 335}
242EXPORT_SYMBOL(__wrap___devm_request_region); 336EXPORT_SYMBOL(__wrap___devm_request_region);
243 337
244static 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
263void __wrap___release_region(struct resource *parent, resource_size_t start, 338void __wrap___release_region(struct resource *parent, resource_size_t start,
264 resource_size_t n) 339 resource_size_t n)
265{ 340{
266 if (!nfit_test_release_region(parent, start, n)) 341 if (!nfit_test_release_region(NULL, parent, start, n))
267 __release_region(parent, start, n); 342 __release_region(parent, start, n);
268} 343}
269EXPORT_SYMBOL(__wrap___release_region); 344EXPORT_SYMBOL(__wrap___release_region);
@@ -271,9 +346,25 @@ EXPORT_SYMBOL(__wrap___release_region);
271void __wrap___devm_release_region(struct device *dev, struct resource *parent, 346void __wrap___devm_release_region(struct device *dev, struct resource *parent,
272 resource_size_t start, resource_size_t n) 347 resource_size_t start, resource_size_t n)
273{ 348{
274 if (!nfit_test_release_region(parent, start, n)) 349 if (!nfit_test_release_region(dev, parent, start, n))
275 __devm_release_region(dev, parent, start, n); 350 __devm_release_region(dev, parent, start, n);
276} 351}
277EXPORT_SYMBOL(__wrap___devm_release_region); 352EXPORT_SYMBOL(__wrap___devm_release_region);
278 353
354acpi_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}
368EXPORT_SYMBOL(__wrap_acpi_evaluate_object);
369
279MODULE_LICENSE("GPL v2"); 370MODULE_LICENSE("GPL v2");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index f64c57bf1d4b..c9a6458cb63e 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -132,6 +132,8 @@ static u32 handle[NUM_DCR] = {
132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0), 132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
133}; 133};
134 134
135static unsigned long dimm_fail_cmd_flags[NUM_DCR];
136
135struct nfit_test { 137struct nfit_test {
136 struct acpi_nfit_desc acpi_desc; 138 struct acpi_nfit_desc acpi_desc;
137 struct platform_device pdev; 139 struct platform_device pdev;
@@ -154,11 +156,14 @@ struct nfit_test {
154 int (*alloc)(struct nfit_test *t); 156 int (*alloc)(struct nfit_test *t);
155 void (*setup)(struct nfit_test *t); 157 void (*setup)(struct nfit_test *t);
156 int setup_hotplug; 158 int setup_hotplug;
159 union acpi_object **_fit;
160 dma_addr_t _fit_dma;
157 struct ars_state { 161 struct ars_state {
158 struct nd_cmd_ars_status *ars_status; 162 struct nd_cmd_ars_status *ars_status;
159 unsigned long deadline; 163 unsigned long deadline;
160 spinlock_t lock; 164 spinlock_t lock;
161 } ars_state; 165 } ars_state;
166 struct device *dimm_dev[NUM_DCR];
162}; 167};
163 168
164static struct nfit_test *to_nfit_test(struct device *dev) 169static struct nfit_test *to_nfit_test(struct device *dev)
@@ -411,6 +416,9 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
411 if (i >= ARRAY_SIZE(handle)) 416 if (i >= ARRAY_SIZE(handle))
412 return -ENXIO; 417 return -ENXIO;
413 418
419 if ((1 << func) & dimm_fail_cmd_flags[i])
420 return -EIO;
421
414 switch (func) { 422 switch (func) {
415 case ND_CMD_GET_CONFIG_SIZE: 423 case ND_CMD_GET_CONFIG_SIZE:
416 rc = nfit_test_cmd_get_config_size(buf, buf_len); 424 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,
428 break; 436 break;
429 case ND_CMD_SMART_THRESHOLD: 437 case ND_CMD_SMART_THRESHOLD:
430 rc = nfit_test_cmd_smart_threshold(buf, buf_len); 438 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);
431 break; 442 break;
432 default: 443 default:
433 return -ENOTTY; 444 return -ENOTTY;
@@ -467,14 +478,12 @@ static struct nfit_test *instances[NUM_NFITS];
467static void release_nfit_res(void *data) 478static void release_nfit_res(void *data)
468{ 479{
469 struct nfit_test_resource *nfit_res = data; 480 struct nfit_test_resource *nfit_res = data;
470 struct resource *res = nfit_res->res;
471 481
472 spin_lock(&nfit_test_lock); 482 spin_lock(&nfit_test_lock);
473 list_del(&nfit_res->list); 483 list_del(&nfit_res->list);
474 spin_unlock(&nfit_test_lock); 484 spin_unlock(&nfit_test_lock);
475 485
476 vfree(nfit_res->buf); 486 vfree(nfit_res->buf);
477 kfree(res);
478 kfree(nfit_res); 487 kfree(nfit_res);
479} 488}
480 489
@@ -482,12 +491,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
482 void *buf) 491 void *buf)
483{ 492{
484 struct device *dev = &t->pdev.dev; 493 struct device *dev = &t->pdev.dev;
485 struct resource *res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
486 struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res), 494 struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res),
487 GFP_KERNEL); 495 GFP_KERNEL);
488 int rc; 496 int rc;
489 497
490 if (!res || !buf || !nfit_res) 498 if (!buf || !nfit_res)
491 goto err; 499 goto err;
492 rc = devm_add_action(dev, release_nfit_res, nfit_res); 500 rc = devm_add_action(dev, release_nfit_res, nfit_res);
493 if (rc) 501 if (rc)
@@ -496,10 +504,11 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
496 memset(buf, 0, size); 504 memset(buf, 0, size);
497 nfit_res->dev = dev; 505 nfit_res->dev = dev;
498 nfit_res->buf = buf; 506 nfit_res->buf = buf;
499 nfit_res->res = res; 507 nfit_res->res.start = *dma;
500 res->start = *dma; 508 nfit_res->res.end = *dma + size - 1;
501 res->end = *dma + size - 1; 509 nfit_res->res.name = "NFIT";
502 res->name = "NFIT"; 510 spin_lock_init(&nfit_res->lock);
511 INIT_LIST_HEAD(&nfit_res->requests);
503 spin_lock(&nfit_test_lock); 512 spin_lock(&nfit_test_lock);
504 list_add(&nfit_res->list, &t->resources); 513 list_add(&nfit_res->list, &t->resources);
505 spin_unlock(&nfit_test_lock); 514 spin_unlock(&nfit_test_lock);
@@ -508,7 +517,6 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
508 err: 517 err:
509 if (buf) 518 if (buf)
510 vfree(buf); 519 vfree(buf);
511 kfree(res);
512 kfree(nfit_res); 520 kfree(nfit_res);
513 return NULL; 521 return NULL;
514} 522}
@@ -533,13 +541,13 @@ static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
533 continue; 541 continue;
534 spin_lock(&nfit_test_lock); 542 spin_lock(&nfit_test_lock);
535 list_for_each_entry(n, &t->resources, list) { 543 list_for_each_entry(n, &t->resources, list) {
536 if (addr >= n->res->start && (addr < n->res->start 544 if (addr >= n->res.start && (addr < n->res.start
537 + resource_size(n->res))) { 545 + resource_size(&n->res))) {
538 nfit_res = n; 546 nfit_res = n;
539 break; 547 break;
540 } else if (addr >= (unsigned long) n->buf 548 } else if (addr >= (unsigned long) n->buf
541 && (addr < (unsigned long) n->buf 549 && (addr < (unsigned long) n->buf
542 + resource_size(n->res))) { 550 + resource_size(&n->res))) {
543 nfit_res = n; 551 nfit_res = n;
544 break; 552 break;
545 } 553 }
@@ -564,6 +572,86 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state)
564 return 0; 572 return 0;
565} 573}
566 574
575static 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
585static struct class *nfit_test_dimm;
586
587static 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
598static 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}
608DEVICE_ATTR_RO(handle);
609
610static 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
621static 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}
638static DEVICE_ATTR_RW(fail_cmd);
639
640static struct attribute *nfit_test_dimm_attributes[] = {
641 &dev_attr_fail_cmd.attr,
642 &dev_attr_handle.attr,
643 NULL,
644};
645
646static struct attribute_group nfit_test_dimm_attribute_group = {
647 .attrs = nfit_test_dimm_attributes,
648};
649
650static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
651 &nfit_test_dimm_attribute_group,
652 NULL,
653};
654
567static int nfit_test0_alloc(struct nfit_test *t) 655static int nfit_test0_alloc(struct nfit_test *t)
568{ 656{
569 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA 657 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)
616 return -ENOMEM; 704 return -ENOMEM;
617 } 705 }
618 706
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
619 return ars_state_init(&t->pdev.dev, &t->ars_state); 722 return ars_state_init(&t->pdev.dev, &t->ars_state);
620} 723}
621 724
@@ -1409,6 +1512,8 @@ static int nfit_test_probe(struct platform_device *pdev)
1409 struct acpi_nfit_desc *acpi_desc; 1512 struct acpi_nfit_desc *acpi_desc;
1410 struct device *dev = &pdev->dev; 1513 struct device *dev = &pdev->dev;
1411 struct nfit_test *nfit_test; 1514 struct nfit_test *nfit_test;
1515 struct nfit_mem *nfit_mem;
1516 union acpi_object *obj;
1412 int rc; 1517 int rc;
1413 1518
1414 nfit_test = to_nfit_test(&pdev->dev); 1519 nfit_test = to_nfit_test(&pdev->dev);
@@ -1476,14 +1581,30 @@ static int nfit_test_probe(struct platform_device *pdev)
1476 if (nfit_test->setup != nfit_test0_setup) 1581 if (nfit_test->setup != nfit_test0_setup)
1477 return 0; 1582 return 0;
1478 1583
1479 flush_work(&acpi_desc->work);
1480 nfit_test->setup_hotplug = 1; 1584 nfit_test->setup_hotplug = 1;
1481 nfit_test->setup(nfit_test); 1585 nfit_test->setup(nfit_test);
1482 1586
1483 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf, 1587 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1484 nfit_test->nfit_size); 1588 if (!obj)
1485 if (rc) 1589 return -ENOMEM;
1486 return rc; 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);
1487 1608
1488 return 0; 1609 return 0;
1489} 1610}
@@ -1518,6 +1639,10 @@ static __init int nfit_test_init(void)
1518{ 1639{
1519 int rc, i; 1640 int rc, i;
1520 1641
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
1521 nfit_test_setup(nfit_test_lookup); 1646 nfit_test_setup(nfit_test_lookup);
1522 1647
1523 for (i = 0; i < NUM_NFITS; i++) { 1648 for (i = 0; i < NUM_NFITS; i++) {
@@ -1584,6 +1709,7 @@ static __exit void nfit_test_exit(void)
1584 for (i = 0; i < NUM_NFITS; i++) 1709 for (i = 0; i < NUM_NFITS; i++)
1585 platform_device_unregister(&instances[i]->pdev); 1710 platform_device_unregister(&instances[i]->pdev);
1586 nfit_test_teardown(); 1711 nfit_test_teardown();
1712 class_destroy(nfit_test_dimm);
1587} 1713}
1588 1714
1589module_init(nfit_test_init); 1715module_init(nfit_test_init);
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 9f18e2a4a862..c281dd2e5e2d 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -13,11 +13,21 @@
13#ifndef __NFIT_TEST_H__ 13#ifndef __NFIT_TEST_H__
14#define __NFIT_TEST_H__ 14#define __NFIT_TEST_H__
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/ioport.h>
17#include <linux/spinlock_types.h>
18
19struct nfit_test_request {
20 struct list_head list;
21 struct resource res;
22};
16 23
17struct nfit_test_resource { 24struct nfit_test_resource {
25 struct list_head requests;
18 struct list_head list; 26 struct list_head list;
19 struct resource *res; 27 struct resource res;
20 struct device *dev; 28 struct device *dev;
29 spinlock_t lock;
30 int req_count;
21 void *buf; 31 void *buf;
22}; 32};
23 33