aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/nvdimm/label.c136
-rw-r--r--drivers/nvdimm/namespace_devs.c173
-rw-r--r--drivers/nvdimm/nd-core.h1
-rw-r--r--drivers/nvdimm/nd.h16
-rw-r--r--drivers/nvdimm/region_devs.c19
5 files changed, 225 insertions, 120 deletions
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 96526dcfdd37..c37357210428 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -499,6 +499,7 @@ static int __pmem_label_update(struct nd_region *nd_region,
499 struct nd_namespace_label *victim_label; 499 struct nd_namespace_label *victim_label;
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_ent *label_ent;
502 unsigned long *free; 503 unsigned long *free;
503 u32 nslot, slot; 504 u32 nslot, slot;
504 size_t offset; 505 size_t offset;
@@ -536,8 +537,13 @@ static int __pmem_label_update(struct nd_region *nd_region,
536 return rc; 537 return rc;
537 538
538 /* Garbage collect the previous label */ 539 /* Garbage collect the previous label */
539 victim_label = nd_mapping->labels[0]; 540 mutex_lock(&nd_mapping->lock);
541 label_ent = list_first_entry_or_null(&nd_mapping->labels,
542 typeof(*label_ent), list);
543 WARN_ON(!label_ent);
544 victim_label = label_ent ? label_ent->label : NULL;
540 if (victim_label) { 545 if (victim_label) {
546 label_ent->label = NULL;
541 slot = to_slot(ndd, victim_label); 547 slot = to_slot(ndd, victim_label);
542 nd_label_free_slot(ndd, slot); 548 nd_label_free_slot(ndd, slot);
543 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); 549 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot);
@@ -546,28 +552,11 @@ static int __pmem_label_update(struct nd_region *nd_region,
546 /* update index */ 552 /* update index */
547 rc = nd_label_write_index(ndd, ndd->ns_next, 553 rc = nd_label_write_index(ndd, ndd->ns_next,
548 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); 554 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
549 if (rc < 0) 555 if (rc == 0 && label_ent)
550 return rc; 556 label_ent->label = nd_label;
551 557 mutex_unlock(&nd_mapping->lock);
552 nd_mapping->labels[0] = nd_label;
553
554 return 0;
555}
556
557static void del_label(struct nd_mapping *nd_mapping, int l)
558{
559 struct nd_namespace_label *next_label, *nd_label;
560 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
561 unsigned int slot;
562 int j;
563 558
564 nd_label = nd_mapping->labels[l]; 559 return rc;
565 slot = to_slot(ndd, nd_label);
566 dev_vdbg(ndd->dev, "%s: clear: %d\n", __func__, slot);
567
568 for (j = l; (next_label = nd_mapping->labels[j + 1]); j++)
569 nd_mapping->labels[j] = next_label;
570 nd_mapping->labels[j] = NULL;
571} 560}
572 561
573static bool is_old_resource(struct resource *res, struct resource **list, int n) 562static bool is_old_resource(struct resource *res, struct resource **list, int n)
@@ -607,14 +596,16 @@ static int __blk_label_update(struct nd_region *nd_region,
607 struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk, 596 struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk,
608 int num_labels) 597 int num_labels)
609{ 598{
610 int i, l, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO; 599 int i, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO;
611 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 600 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
612 struct nd_namespace_label *nd_label; 601 struct nd_namespace_label *nd_label;
602 struct nd_label_ent *label_ent, *e;
613 struct nd_namespace_index *nsindex; 603 struct nd_namespace_index *nsindex;
614 unsigned long *free, *victim_map = NULL; 604 unsigned long *free, *victim_map = NULL;
615 struct resource *res, **old_res_list; 605 struct resource *res, **old_res_list;
616 struct nd_label_id label_id; 606 struct nd_label_id label_id;
617 u8 uuid[NSLABEL_UUID_LEN]; 607 u8 uuid[NSLABEL_UUID_LEN];
608 LIST_HEAD(list);
618 u32 nslot, slot; 609 u32 nslot, slot;
619 610
620 if (!preamble_next(ndd, &nsindex, &free, &nslot)) 611 if (!preamble_next(ndd, &nsindex, &free, &nslot))
@@ -736,15 +727,22 @@ static int __blk_label_update(struct nd_region *nd_region,
736 * entries in nd_mapping->labels 727 * entries in nd_mapping->labels
737 */ 728 */
738 nlabel = 0; 729 nlabel = 0;
739 for_each_label(l, nd_label, nd_mapping->labels) { 730 mutex_lock(&nd_mapping->lock);
731 list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
732 nd_label = label_ent->label;
733 if (!nd_label)
734 continue;
740 nlabel++; 735 nlabel++;
741 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN); 736 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
742 if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0) 737 if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
743 continue; 738 continue;
744 nlabel--; 739 nlabel--;
745 del_label(nd_mapping, l); 740 list_move(&label_ent->list, &list);
746 l--; /* retry with the new label at this index */ 741 label_ent->label = NULL;
747 } 742 }
743 list_splice_tail_init(&list, &nd_mapping->labels);
744 mutex_unlock(&nd_mapping->lock);
745
748 if (nlabel + nsblk->num_resources > num_labels) { 746 if (nlabel + nsblk->num_resources > num_labels) {
749 /* 747 /*
750 * Bug, we can't end up with more resources than 748 * Bug, we can't end up with more resources than
@@ -755,6 +753,15 @@ static int __blk_label_update(struct nd_region *nd_region,
755 goto out; 753 goto out;
756 } 754 }
757 755
756 mutex_lock(&nd_mapping->lock);
757 label_ent = list_first_entry_or_null(&nd_mapping->labels,
758 typeof(*label_ent), list);
759 if (!label_ent) {
760 WARN_ON(1);
761 mutex_unlock(&nd_mapping->lock);
762 rc = -ENXIO;
763 goto out;
764 }
758 for_each_clear_bit_le(slot, free, nslot) { 765 for_each_clear_bit_le(slot, free, nslot) {
759 nd_label = nd_label_base(ndd) + slot; 766 nd_label = nd_label_base(ndd) + slot;
760 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN); 767 memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
@@ -762,11 +769,19 @@ static int __blk_label_update(struct nd_region *nd_region,
762 continue; 769 continue;
763 res = to_resource(ndd, nd_label); 770 res = to_resource(ndd, nd_label);
764 res->flags &= ~DPA_RESOURCE_ADJUSTED; 771 res->flags &= ~DPA_RESOURCE_ADJUSTED;
765 dev_vdbg(&nsblk->common.dev, "assign label[%d] slot: %d\n", 772 dev_vdbg(&nsblk->common.dev, "assign label slot: %d\n", slot);
766 l, slot); 773 list_for_each_entry_from(label_ent, &nd_mapping->labels, list) {
767 nd_mapping->labels[l++] = nd_label; 774 if (label_ent->label)
775 continue;
776 label_ent->label = nd_label;
777 nd_label = NULL;
778 break;
779 }
780 if (nd_label)
781 dev_WARN(&nsblk->common.dev,
782 "failed to track label slot%d\n", slot);
768 } 783 }
769 nd_mapping->labels[l] = NULL; 784 mutex_unlock(&nd_mapping->lock);
770 785
771 out: 786 out:
772 kfree(old_res_list); 787 kfree(old_res_list);
@@ -788,32 +803,28 @@ static int __blk_label_update(struct nd_region *nd_region,
788 803
789static int init_labels(struct nd_mapping *nd_mapping, int num_labels) 804static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
790{ 805{
791 int i, l, old_num_labels = 0; 806 int i, old_num_labels = 0;
807 struct nd_label_ent *label_ent;
792 struct nd_namespace_index *nsindex; 808 struct nd_namespace_index *nsindex;
793 struct nd_namespace_label *nd_label;
794 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 809 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
795 size_t size = (num_labels + 1) * sizeof(struct nd_namespace_label *);
796 810
797 for_each_label(l, nd_label, nd_mapping->labels) 811 mutex_lock(&nd_mapping->lock);
812 list_for_each_entry(label_ent, &nd_mapping->labels, list)
798 old_num_labels++; 813 old_num_labels++;
814 mutex_unlock(&nd_mapping->lock);
799 815
800 /* 816 /*
801 * We need to preserve all the old labels for the mapping so 817 * We need to preserve all the old labels for the mapping so
802 * they can be garbage collected after writing the new labels. 818 * they can be garbage collected after writing the new labels.
803 */ 819 */
804 if (num_labels > old_num_labels) { 820 for (i = old_num_labels; i < num_labels; i++) {
805 struct nd_namespace_label **labels; 821 label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
806 822 if (!label_ent)
807 labels = krealloc(nd_mapping->labels, size, GFP_KERNEL);
808 if (!labels)
809 return -ENOMEM; 823 return -ENOMEM;
810 nd_mapping->labels = labels; 824 mutex_lock(&nd_mapping->lock);
825 list_add_tail(&label_ent->list, &nd_mapping->labels);
826 mutex_unlock(&nd_mapping->lock);
811 } 827 }
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 828
818 if (ndd->ns_current == -1 || ndd->ns_next == -1) 829 if (ndd->ns_current == -1 || ndd->ns_next == -1)
819 /* pass */; 830 /* pass */;
@@ -837,42 +848,45 @@ static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
837static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) 848static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid)
838{ 849{
839 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 850 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
840 struct nd_namespace_label *nd_label; 851 struct nd_label_ent *label_ent, *e;
841 struct nd_namespace_index *nsindex; 852 struct nd_namespace_index *nsindex;
842 u8 label_uuid[NSLABEL_UUID_LEN]; 853 u8 label_uuid[NSLABEL_UUID_LEN];
843 int l, num_freed = 0;
844 unsigned long *free; 854 unsigned long *free;
855 LIST_HEAD(list);
845 u32 nslot, slot; 856 u32 nslot, slot;
857 int active = 0;
846 858
847 if (!uuid) 859 if (!uuid)
848 return 0; 860 return 0;
849 861
850 /* no index || no labels == nothing to delete */ 862 /* no index || no labels == nothing to delete */
851 if (!preamble_next(ndd, &nsindex, &free, &nslot) 863 if (!preamble_next(ndd, &nsindex, &free, &nslot))
852 || !nd_mapping->labels)
853 return 0; 864 return 0;
854 865
855 for_each_label(l, nd_label, nd_mapping->labels) { 866 mutex_lock(&nd_mapping->lock);
867 list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
868 struct nd_namespace_label *nd_label = label_ent->label;
869
870 if (!nd_label)
871 continue;
872 active++;
856 memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN); 873 memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN);
857 if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0) 874 if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0)
858 continue; 875 continue;
876 active--;
859 slot = to_slot(ndd, nd_label); 877 slot = to_slot(ndd, nd_label);
860 nd_label_free_slot(ndd, slot); 878 nd_label_free_slot(ndd, slot);
861 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); 879 dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot);
862 del_label(nd_mapping, l); 880 list_move_tail(&label_ent->list, &list);
863 num_freed++; 881 label_ent->label = NULL;
864 l--; /* retry with new label at this index */
865 } 882 }
883 list_splice_tail_init(&list, &nd_mapping->labels);
866 884
867 if (num_freed > l) { 885 if (active == 0) {
868 /* 886 nd_mapping_free_labels(nd_mapping);
869 * num_freed will only ever be > l when we delete the last 887 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 } 888 }
889 mutex_unlock(&nd_mapping->lock);
876 890
877 return nd_label_write_index(ndd, ndd->ns_next, 891 return nd_label_write_index(ndd, ndd->ns_next,
878 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); 892 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
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;
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index 1414784c6c2b..fb3ade0d4a83 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -73,6 +73,7 @@ bool nd_is_uuid_unique(struct device *dev, u8 *uuid);
73struct nd_region; 73struct nd_region;
74struct nvdimm_drvdata; 74struct nvdimm_drvdata;
75struct nd_mapping; 75struct nd_mapping;
76void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
76resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, 77resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
77 struct nd_mapping *nd_mapping, resource_size_t *overlap); 78 struct nd_mapping *nd_mapping, resource_size_t *overlap);
78resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping); 79resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping);
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index e58c40824e1f..f67c61f1a8a4 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -83,9 +83,6 @@ static inline struct nd_namespace_index *to_next_namespace_index(
83 (unsigned long long) (res ? resource_size(res) : 0), \ 83 (unsigned long long) (res ? resource_size(res) : 0), \
84 (unsigned long long) (res ? res->start : 0), ##arg) 84 (unsigned long long) (res ? res->start : 0), ##arg)
85 85
86#define for_each_label(l, label, labels) \
87 for (l = 0; (label = labels ? labels[l] : NULL); l++)
88
89#define for_each_dpa_resource(ndd, res) \ 86#define for_each_dpa_resource(ndd, res) \
90 for (res = (ndd)->dpa.child; res; res = res->sibling) 87 for (res = (ndd)->dpa.child; res; res = res->sibling)
91 88
@@ -98,11 +95,22 @@ struct nd_percpu_lane {
98 spinlock_t lock; 95 spinlock_t lock;
99}; 96};
100 97
98struct nd_label_ent {
99 struct list_head list;
100 struct nd_namespace_label *label;
101};
102
103enum nd_mapping_lock_class {
104 ND_MAPPING_CLASS0,
105 ND_MAPPING_UUID_SCAN,
106};
107
101struct nd_mapping { 108struct nd_mapping {
102 struct nvdimm *nvdimm; 109 struct nvdimm *nvdimm;
103 struct nd_namespace_label **labels;
104 u64 start; 110 u64 start;
105 u64 size; 111 u64 size;
112 struct list_head labels;
113 struct mutex lock;
106 /* 114 /*
107 * @ndd is for private use at region enable / disable time for 115 * @ndd is for private use at region enable / disable time for
108 * get_ndd() + put_ndd(), all other nd_mapping to ndd 116 * get_ndd() + put_ndd(), all other nd_mapping to ndd
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 0ff43cbb15e3..19bcd68c4141 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -487,6 +487,17 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region)
487 return 0; 487 return 0;
488} 488}
489 489
490void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
491{
492 struct nd_label_ent *label_ent, *e;
493
494 WARN_ON(!mutex_is_locked(&nd_mapping->lock));
495 list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
496 list_del(&label_ent->list);
497 kfree(label_ent);
498 }
499}
500
490/* 501/*
491 * Upon successful probe/remove, take/release a reference on the 502 * Upon successful probe/remove, take/release a reference on the
492 * associated interleave set (if present), and plant new btt + namespace 503 * associated interleave set (if present), and plant new btt + namespace
@@ -507,8 +518,10 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus,
507 struct nvdimm_drvdata *ndd = nd_mapping->ndd; 518 struct nvdimm_drvdata *ndd = nd_mapping->ndd;
508 struct nvdimm *nvdimm = nd_mapping->nvdimm; 519 struct nvdimm *nvdimm = nd_mapping->nvdimm;
509 520
510 kfree(nd_mapping->labels); 521 mutex_lock(&nd_mapping->lock);
511 nd_mapping->labels = NULL; 522 nd_mapping_free_labels(nd_mapping);
523 mutex_unlock(&nd_mapping->lock);
524
512 put_ndd(ndd); 525 put_ndd(ndd);
513 nd_mapping->ndd = NULL; 526 nd_mapping->ndd = NULL;
514 if (ndd) 527 if (ndd)
@@ -816,6 +829,8 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
816 nd_region->mapping[i].nvdimm = nvdimm; 829 nd_region->mapping[i].nvdimm = nvdimm;
817 nd_region->mapping[i].start = mapping->start; 830 nd_region->mapping[i].start = mapping->start;
818 nd_region->mapping[i].size = mapping->size; 831 nd_region->mapping[i].size = mapping->size;
832 INIT_LIST_HEAD(&nd_region->mapping[i].labels);
833 mutex_init(&nd_region->mapping[i].lock);
819 834
820 get_device(&nvdimm->dev); 835 get_device(&nvdimm->dev);
821 } 836 }