aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/namespace_devs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-09-19 19:04:21 -0400
committerDan Williams <dan.j.williams@intel.com>2016-09-30 22:13:42 -0400
commitae8219f186d8e98a3239afc6ea49bb46f2871d2f (patch)
tree8c32ce83b2e3b6d5b9a7565edd2ab305436131ef /drivers/nvdimm/namespace_devs.c
parent44c462eb9e19dfa089b454271dd2dff5eaf1ad6d (diff)
libnvdimm, label: convert label tracking to a linked list
In preparation for enabling multiple namespaces per pmem region, convert the label tracking to use a linked list. In particular this will allow select_pmem_id() to move labels from the unvalidated state to the validated state. Currently we only track one validated set per-region. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r--drivers/nvdimm/namespace_devs.c173
1 files changed, 120 insertions, 53 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 4f0a21308417..9f4188c78120 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -14,6 +14,7 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/pmem.h> 16#include <linux/pmem.h>
17#include <linux/list.h>
17#include <linux/nd.h> 18#include <linux/nd.h>
18#include "nd-core.h" 19#include "nd-core.h"
19#include "nd.h" 20#include "nd.h"
@@ -1089,7 +1090,7 @@ static int namespace_update_uuid(struct nd_region *nd_region,
1089 * 1090 *
1090 * FIXME: can we delete uuid with zero dpa allocated? 1091 * FIXME: can we delete uuid with zero dpa allocated?
1091 */ 1092 */
1092 if (nd_mapping->labels) 1093 if (list_empty(&nd_mapping->labels))
1093 return -EBUSY; 1094 return -EBUSY;
1094 } 1095 }
1095 1096
@@ -1491,14 +1492,19 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid,
1491 1492
1492 for (i = 0; i < nd_region->ndr_mappings; i++) { 1493 for (i = 0; i < nd_region->ndr_mappings; i++) {
1493 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1494 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1494 struct nd_namespace_label *nd_label; 1495 struct nd_label_ent *label_ent;
1495 bool found_uuid = false; 1496 bool found_uuid = false;
1496 int l;
1497 1497
1498 for_each_label(l, nd_label, nd_mapping->labels) { 1498 list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1499 u64 isetcookie = __le64_to_cpu(nd_label->isetcookie); 1499 struct nd_namespace_label *nd_label = label_ent->label;
1500 u16 position = __le16_to_cpu(nd_label->position); 1500 u16 position, nlabel;
1501 u16 nlabel = __le16_to_cpu(nd_label->nlabel); 1501 u64 isetcookie;
1502
1503 if (!nd_label)
1504 continue;
1505 isetcookie = __le64_to_cpu(nd_label->isetcookie);
1506 position = __le16_to_cpu(nd_label->position);
1507 nlabel = __le16_to_cpu(nd_label->nlabel);
1502 1508
1503 if (isetcookie != cookie) 1509 if (isetcookie != cookie)
1504 continue; 1510 continue;
@@ -1528,7 +1534,6 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid,
1528 1534
1529static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id) 1535static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1530{ 1536{
1531 struct nd_namespace_label *select = NULL;
1532 int i; 1537 int i;
1533 1538
1534 if (!pmem_id) 1539 if (!pmem_id)
@@ -1536,35 +1541,47 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1536 1541
1537 for (i = 0; i < nd_region->ndr_mappings; i++) { 1542 for (i = 0; i < nd_region->ndr_mappings; i++) {
1538 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1543 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1539 struct nd_namespace_label *nd_label; 1544 struct nd_namespace_label *nd_label = NULL;
1540 u64 hw_start, hw_end, pmem_start, pmem_end; 1545 u64 hw_start, hw_end, pmem_start, pmem_end;
1541 int l; 1546 struct nd_label_ent *label_ent;
1542 1547
1543 for_each_label(l, nd_label, nd_mapping->labels) 1548 mutex_lock(&nd_mapping->lock);
1549 list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1550 nd_label = label_ent->label;
1551 if (!nd_label)
1552 continue;
1544 if (memcmp(nd_label->uuid, pmem_id, NSLABEL_UUID_LEN) == 0) 1553 if (memcmp(nd_label->uuid, pmem_id, NSLABEL_UUID_LEN) == 0)
1545 break; 1554 break;
1555 nd_label = NULL;
1556 }
1557 mutex_unlock(&nd_mapping->lock);
1546 1558
1547 if (!nd_label) { 1559 if (!nd_label) {
1548 WARN_ON(1); 1560 WARN_ON(1);
1549 return -EINVAL; 1561 return -EINVAL;
1550 } 1562 }
1551 1563
1552 select = nd_label;
1553 /* 1564 /*
1554 * Check that this label is compliant with the dpa 1565 * Check that this label is compliant with the dpa
1555 * range published in NFIT 1566 * range published in NFIT
1556 */ 1567 */
1557 hw_start = nd_mapping->start; 1568 hw_start = nd_mapping->start;
1558 hw_end = hw_start + nd_mapping->size; 1569 hw_end = hw_start + nd_mapping->size;
1559 pmem_start = __le64_to_cpu(select->dpa); 1570 pmem_start = __le64_to_cpu(nd_label->dpa);
1560 pmem_end = pmem_start + __le64_to_cpu(select->rawsize); 1571 pmem_end = pmem_start + __le64_to_cpu(nd_label->rawsize);
1561 if (pmem_start == hw_start && pmem_end <= hw_end) 1572 if (pmem_start == hw_start && pmem_end <= hw_end)
1562 /* pass */; 1573 /* pass */;
1563 else 1574 else
1564 return -EINVAL; 1575 return -EINVAL;
1565 1576
1566 nd_mapping->labels[0] = select; 1577 mutex_lock(&nd_mapping->lock);
1567 nd_mapping->labels[1] = NULL; 1578 label_ent = list_first_entry(&nd_mapping->labels,
1579 typeof(*label_ent), list);
1580 label_ent->label = nd_label;
1581 list_del(&label_ent->list);
1582 nd_mapping_free_labels(nd_mapping);
1583 list_add(&label_ent->list, &nd_mapping->labels);
1584 mutex_unlock(&nd_mapping->lock);
1568 } 1585 }
1569 return 0; 1586 return 0;
1570} 1587}
@@ -1577,11 +1594,12 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1577 struct nd_namespace_pmem *nspm) 1594 struct nd_namespace_pmem *nspm)
1578{ 1595{
1579 u64 cookie = nd_region_interleave_set_cookie(nd_region); 1596 u64 cookie = nd_region_interleave_set_cookie(nd_region);
1580 struct nd_namespace_label *nd_label;
1581 u8 select_id[NSLABEL_UUID_LEN]; 1597 u8 select_id[NSLABEL_UUID_LEN];
1598 struct nd_label_ent *label_ent;
1599 struct nd_mapping *nd_mapping;
1582 resource_size_t size = 0; 1600 resource_size_t size = 0;
1583 u8 *pmem_id = NULL; 1601 u8 *pmem_id = NULL;
1584 int rc = -ENODEV, l; 1602 int rc = 0;
1585 u16 i; 1603 u16 i;
1586 1604
1587 if (cookie == 0) { 1605 if (cookie == 0) {
@@ -1593,13 +1611,19 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1593 * Find a complete set of labels by uuid. By definition we can start 1611 * Find a complete set of labels by uuid. By definition we can start
1594 * with any mapping as the reference label 1612 * with any mapping as the reference label
1595 */ 1613 */
1596 for_each_label(l, nd_label, nd_region->mapping[0].labels) { 1614 for (i = 0; i < nd_region->ndr_mappings; i++) {
1597 u64 isetcookie = __le64_to_cpu(nd_label->isetcookie); 1615 nd_mapping = &nd_region->mapping[i];
1616 mutex_lock_nested(&nd_mapping->lock, i);
1617 }
1618 list_for_each_entry(label_ent, &nd_region->mapping[0].labels, list) {
1619 struct nd_namespace_label *nd_label = label_ent->label;
1598 1620
1599 if (isetcookie != cookie) 1621 if (!nd_label)
1622 continue;
1623 if (__le64_to_cpu(nd_label->isetcookie) != cookie)
1600 continue; 1624 continue;
1601 1625
1602 for (i = 0; nd_region->ndr_mappings; i++) 1626 for (i = 0; i < nd_region->ndr_mappings; i++)
1603 if (!has_uuid_at_pos(nd_region, nd_label->uuid, 1627 if (!has_uuid_at_pos(nd_region, nd_label->uuid,
1604 cookie, i)) 1628 cookie, i))
1605 break; 1629 break;
@@ -1611,18 +1635,27 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1611 * dimm with two instances of the same uuid. 1635 * dimm with two instances of the same uuid.
1612 */ 1636 */
1613 rc = -EINVAL; 1637 rc = -EINVAL;
1614 goto err; 1638 break;
1615 } else if (pmem_id) { 1639 } else if (pmem_id) {
1616 /* 1640 /*
1617 * If there is more than one valid uuid set, we 1641 * If there is more than one valid uuid set, we
1618 * need userspace to clean this up. 1642 * need userspace to clean this up.
1619 */ 1643 */
1620 rc = -EBUSY; 1644 rc = -EBUSY;
1621 goto err; 1645 break;
1622 } 1646 }
1623 memcpy(select_id, nd_label->uuid, NSLABEL_UUID_LEN); 1647 memcpy(select_id, nd_label->uuid, NSLABEL_UUID_LEN);
1624 pmem_id = select_id; 1648 pmem_id = select_id;
1625 } 1649 }
1650 for (i = 0; i < nd_region->ndr_mappings; i++) {
1651 int reverse = nd_region->ndr_mappings - 1 - i;
1652
1653 nd_mapping = &nd_region->mapping[reverse];
1654 mutex_unlock(&nd_mapping->lock);
1655 }
1656
1657 if (rc)
1658 goto err;
1626 1659
1627 /* 1660 /*
1628 * Fix up each mapping's 'labels' to have the validated pmem label for 1661 * Fix up each mapping's 'labels' to have the validated pmem label for
@@ -1638,8 +1671,19 @@ static int find_pmem_label_set(struct nd_region *nd_region,
1638 1671
1639 /* Calculate total size and populate namespace properties from label0 */ 1672 /* Calculate total size and populate namespace properties from label0 */
1640 for (i = 0; i < nd_region->ndr_mappings; i++) { 1673 for (i = 0; i < nd_region->ndr_mappings; i++) {
1641 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1674 struct nd_namespace_label *label0;
1642 struct nd_namespace_label *label0 = nd_mapping->labels[0]; 1675
1676 nd_mapping = &nd_region->mapping[i];
1677 mutex_lock(&nd_mapping->lock);
1678 label_ent = list_first_entry_or_null(&nd_mapping->labels,
1679 typeof(*label_ent), list);
1680 label0 = label_ent ? label_ent->label : 0;
1681 mutex_unlock(&nd_mapping->lock);
1682
1683 if (!label0) {
1684 WARN_ON(1);
1685 continue;
1686 }
1643 1687
1644 size += __le64_to_cpu(label0->rawsize); 1688 size += __le64_to_cpu(label0->rawsize);
1645 if (__le16_to_cpu(label0->position) != 0) 1689 if (__le16_to_cpu(label0->position) != 0)
@@ -1700,8 +1744,9 @@ static struct device **create_namespace_pmem(struct nd_region *nd_region)
1700 for (i = 0; i < nd_region->ndr_mappings; i++) { 1744 for (i = 0; i < nd_region->ndr_mappings; i++) {
1701 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1745 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1702 1746
1703 kfree(nd_mapping->labels); 1747 mutex_lock(&nd_mapping->lock);
1704 nd_mapping->labels = NULL; 1748 nd_mapping_free_labels(nd_mapping);
1749 mutex_unlock(&nd_mapping->lock);
1705 } 1750 }
1706 1751
1707 /* Publish a zero-sized namespace for userspace to configure. */ 1752 /* Publish a zero-sized namespace for userspace to configure. */
@@ -1822,25 +1867,25 @@ void nd_region_create_btt_seed(struct nd_region *nd_region)
1822 dev_err(&nd_region->dev, "failed to create btt namespace\n"); 1867 dev_err(&nd_region->dev, "failed to create btt namespace\n");
1823} 1868}
1824 1869
1825static struct device **create_namespace_blk(struct nd_region *nd_region) 1870static struct device **scan_labels(struct nd_region *nd_region,
1871 struct nd_mapping *nd_mapping)
1826{ 1872{
1827 struct nd_mapping *nd_mapping = &nd_region->mapping[0]; 1873 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1828 struct nd_namespace_label *nd_label;
1829 struct device *dev, **devs = NULL; 1874 struct device *dev, **devs = NULL;
1830 struct nd_namespace_blk *nsblk; 1875 struct nd_namespace_blk *nsblk;
1831 struct nvdimm_drvdata *ndd; 1876 struct nd_label_ent *label_ent;
1832 int i, l, count = 0; 1877 int i, count = 0;
1833 struct resource *res;
1834
1835 if (nd_region->ndr_mappings == 0)
1836 return NULL;
1837 1878
1838 ndd = to_ndd(nd_mapping); 1879 list_for_each_entry(label_ent, &nd_mapping->labels, list) {
1839 for_each_label(l, nd_label, nd_mapping->labels) { 1880 struct nd_namespace_label *nd_label = label_ent->label;
1840 u32 flags = __le32_to_cpu(nd_label->flags);
1841 char *name[NSLABEL_NAME_LEN]; 1881 char *name[NSLABEL_NAME_LEN];
1842 struct device **__devs; 1882 struct device **__devs;
1883 struct resource *res;
1884 u32 flags;
1843 1885
1886 if (!nd_label)
1887 continue;
1888 flags = __le32_to_cpu(nd_label->flags);
1844 if (flags & NSLABEL_FLAG_LOCAL) 1889 if (flags & NSLABEL_FLAG_LOCAL)
1845 /* pass */; 1890 /* pass */;
1846 else 1891 else
@@ -1899,12 +1944,7 @@ static struct device **create_namespace_blk(struct nd_region *nd_region)
1899 1944
1900 if (count == 0) { 1945 if (count == 0) {
1901 /* Publish a zero-sized namespace for userspace to configure. */ 1946 /* Publish a zero-sized namespace for userspace to configure. */
1902 for (i = 0; i < nd_region->ndr_mappings; i++) { 1947 nd_mapping_free_labels(nd_mapping);
1903 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1904
1905 kfree(nd_mapping->labels);
1906 nd_mapping->labels = NULL;
1907 }
1908 1948
1909 devs = kcalloc(2, sizeof(dev), GFP_KERNEL); 1949 devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
1910 if (!devs) 1950 if (!devs)
@@ -1920,8 +1960,8 @@ static struct device **create_namespace_blk(struct nd_region *nd_region)
1920 1960
1921 return devs; 1961 return devs;
1922 1962
1923err: 1963 err:
1924 for (i = 0; i < count; i++) { 1964 for (i = 0; devs[i]; i++) {
1925 nsblk = to_nd_namespace_blk(devs[i]); 1965 nsblk = to_nd_namespace_blk(devs[i]);
1926 namespace_blk_release(&nsblk->common.dev); 1966 namespace_blk_release(&nsblk->common.dev);
1927 } 1967 }
@@ -1929,6 +1969,21 @@ err:
1929 return NULL; 1969 return NULL;
1930} 1970}
1931 1971
1972static struct device **create_namespace_blk(struct nd_region *nd_region)
1973{
1974 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1975 struct device **devs;
1976
1977 if (nd_region->ndr_mappings == 0)
1978 return NULL;
1979
1980 mutex_lock(&nd_mapping->lock);
1981 devs = scan_labels(nd_region, nd_mapping);
1982 mutex_unlock(&nd_mapping->lock);
1983
1984 return devs;
1985}
1986
1932static int init_active_labels(struct nd_region *nd_region) 1987static int init_active_labels(struct nd_region *nd_region)
1933{ 1988{
1934 int i; 1989 int i;
@@ -1937,6 +1992,7 @@ static int init_active_labels(struct nd_region *nd_region)
1937 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 1992 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1938 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 1993 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1939 struct nvdimm *nvdimm = nd_mapping->nvdimm; 1994 struct nvdimm *nvdimm = nd_mapping->nvdimm;
1995 struct nd_label_ent *label_ent;
1940 int count, j; 1996 int count, j;
1941 1997
1942 /* 1998 /*
@@ -1958,16 +2014,27 @@ static int init_active_labels(struct nd_region *nd_region)
1958 dev_dbg(ndd->dev, "%s: %d\n", __func__, count); 2014 dev_dbg(ndd->dev, "%s: %d\n", __func__, count);
1959 if (!count) 2015 if (!count)
1960 continue; 2016 continue;
1961 nd_mapping->labels = kcalloc(count + 1, sizeof(void *),
1962 GFP_KERNEL);
1963 if (!nd_mapping->labels)
1964 return -ENOMEM;
1965 for (j = 0; j < count; j++) { 2017 for (j = 0; j < count; j++) {
1966 struct nd_namespace_label *label; 2018 struct nd_namespace_label *label;
1967 2019
2020 label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
2021 if (!label_ent)
2022 break;
1968 label = nd_label_active(ndd, j); 2023 label = nd_label_active(ndd, j);
1969 nd_mapping->labels[j] = label; 2024 label_ent->label = label;
2025
2026 mutex_lock(&nd_mapping->lock);
2027 list_add_tail(&label_ent->list, &nd_mapping->labels);
2028 mutex_unlock(&nd_mapping->lock);
1970 } 2029 }
2030
2031 if (j >= count)
2032 continue;
2033
2034 mutex_lock(&nd_mapping->lock);
2035 nd_mapping_free_labels(nd_mapping);
2036 mutex_unlock(&nd_mapping->lock);
2037 return -ENOMEM;
1971 } 2038 }
1972 2039
1973 return 0; 2040 return 0;