Lines Matching +full:slot +full:- +full:size
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
11 #include "nd-core.h"
47 return ndd->nslabel_size; in sizeof_namespace_label()
59 return (ndd->nsarea.config_size - index_size * 2) / in __nvdimm_num_label_slots()
67 tmp_nslot = ndd->nsarea.config_size / sizeof_namespace_label(ndd); in nvdimm_num_label_slots()
75 u32 nslot, space, size; in sizeof_namespace_index() local
78 * Per UEFI 2.7, the minimum size of the Label Storage Area is large in sizeof_namespace_index()
80 * block size is 256 bytes. The label size is 128 for namespaces in sizeof_namespace_index()
84 space = ndd->nsarea.config_size - nslot * sizeof_namespace_label(ndd); in sizeof_namespace_index()
85 size = __sizeof_namespace_index(nslot) * 2; in sizeof_namespace_index()
86 if (size <= space && nslot >= 2) in sizeof_namespace_index()
87 return size / 2; in sizeof_namespace_index()
89 dev_err(ndd->dev, "label area (%d) too small to host (%d byte) labels\n", in sizeof_namespace_index()
90 ndd->nsarea.config_size, sizeof_namespace_label(ndd)); in sizeof_namespace_index()
103 * +------------+ in __nd_label_validate()
107 * +------------+ in __nd_label_validate()
111 * +------------+ in __nd_label_validate()
113 * +------------+ in __nd_label_validate()
115 * +------------+ in __nd_label_validate()
119 * +------------+ in __nd_label_validate()
121 * +------------+ in __nd_label_validate()
128 struct device *dev = ndd->dev; in __nd_label_validate()
136 u64 sum_save, sum, size; in __nd_label_validate() local
139 memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN); in __nd_label_validate()
146 version = __le16_to_cpu(nsindex[i]->major) * 100 in __nd_label_validate()
147 + __le16_to_cpu(nsindex[i]->minor); in __nd_label_validate()
149 labelsize = 1 << (7 + nsindex[i]->labelsize); in __nd_label_validate()
155 i, nsindex[i]->labelsize); in __nd_label_validate()
159 sum_save = __le64_to_cpu(nsindex[i]->checksum); in __nd_label_validate()
160 nsindex[i]->checksum = __cpu_to_le64(0); in __nd_label_validate()
162 nsindex[i]->checksum = __cpu_to_le64(sum_save); in __nd_label_validate()
168 seq = __le32_to_cpu(nsindex[i]->seq); in __nd_label_validate()
175 if (__le64_to_cpu(nsindex[i]->myoff) in __nd_label_validate()
179 __le64_to_cpu(nsindex[i]->myoff)); in __nd_label_validate()
182 if (__le64_to_cpu(nsindex[i]->otheroff) in __nd_label_validate()
186 __le64_to_cpu(nsindex[i]->otheroff)); in __nd_label_validate()
189 if (__le64_to_cpu(nsindex[i]->labeloff) in __nd_label_validate()
193 __le64_to_cpu(nsindex[i]->labeloff)); in __nd_label_validate()
197 size = __le64_to_cpu(nsindex[i]->mysize); in __nd_label_validate()
198 if (size > sizeof_namespace_index(ndd) in __nd_label_validate()
199 || size < sizeof(struct nd_namespace_index)) { in __nd_label_validate()
200 dev_dbg(dev, "nsindex%d mysize: %#llx invalid\n", i, size); in __nd_label_validate()
204 nslot = __le32_to_cpu(nsindex[i]->nslot); in __nd_label_validate()
207 > ndd->nsarea.config_size) { in __nd_label_validate()
209 i, nslot, ndd->nsarea.config_size); in __nd_label_validate()
228 seq = best_seq(__le32_to_cpu(nsindex[0]->seq), in __nd_label_validate()
229 __le32_to_cpu(nsindex[1]->seq)); in __nd_label_validate()
230 if (seq == (__le32_to_cpu(nsindex[1]->seq) & NSINDEX_SEQ_MASK)) in __nd_label_validate()
237 return -1; in __nd_label_validate()
244 * need to know the size of the labels, and we can't trust the in nd_label_validate()
245 * size of the labels until we validate the index blocks. in nd_label_validate()
247 * sizes, but default to v1.2 256-byte namespace labels if in nd_label_validate()
254 ndd->nslabel_size = label_size[i]; in nd_label_validate()
260 return -1; in nd_label_validate()
289 return (label - base) / sizeof_namespace_label(ndd); in to_slot()
292 static struct nd_namespace_label *to_label(struct nvdimm_drvdata *ndd, int slot) in to_label() argument
297 label = base + sizeof_namespace_label(ndd) * slot; in to_label()
302 #define for_each_clear_bit_le(bit, addr, size) \ argument
303 for ((bit) = find_next_zero_bit_le((addr), (size), 0); \
304 (bit) < (size); \
305 (bit) = find_next_zero_bit_le((addr), (size), (bit) + 1))
308 * preamble_index - common variable initialization for nd_label_* routines
325 *free = (unsigned long *) nsindex->free; in preamble_index()
326 *nslot = __le32_to_cpu(nsindex->nslot); in preamble_index()
337 snprintf(label_id->id, ND_LABEL_ID_SIZE, "pmem-%pUb", uuid); in nd_label_gen_id()
338 return label_id->id; in nd_label_gen_id()
345 return preamble_index(ndd, ndd->ns_current, nsindex, in preamble_current()
353 return preamble_index(ndd, ndd->ns_next, nsindex, in preamble_next()
362 if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum)) in nsl_validate_checksum()
377 if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum)) in nsl_calculate_checksum()
385 struct nd_namespace_label *nd_label, u32 slot) in slot_valid() argument
390 if (slot != nsl_get_slot(ndd, nd_label)) in slot_valid()
394 dev_dbg(ndd->dev, "fail checksum. slot: %d\n", slot); in slot_valid()
402 u32 nslot, slot; in nd_label_reserve_dpa() local
407 for_each_clear_bit_le(slot, free, nslot) { in nd_label_reserve_dpa()
415 nd_label = to_label(ndd, slot); in nd_label_reserve_dpa()
417 if (!slot_valid(ndd, nd_label, slot)) in nd_label_reserve_dpa()
428 return -EBUSY; in nd_label_reserve_dpa()
442 if (ndd->data) in nd_label_data_init()
445 if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0 || in nd_label_data_init()
446 ndd->nsarea.config_size == 0) { in nd_label_data_init()
447 dev_dbg(ndd->dev, "failed to init config data area: (%u:%u)\n", in nd_label_data_init()
448 ndd->nsarea.max_xfer, ndd->nsarea.config_size); in nd_label_data_init()
449 return -ENXIO; in nd_label_data_init()
459 * Start at a label size of 128 as this should result in the largest in nd_label_data_init()
460 * possible namespace index size. in nd_label_data_init()
462 ndd->nslabel_size = 128; in nd_label_data_init()
465 return -ENXIO; in nd_label_data_init()
468 config_size = ndd->nsarea.config_size; in nd_label_data_init()
469 ndd->data = kvzalloc(config_size, GFP_KERNEL); in nd_label_data_init()
470 if (!ndd->data) in nd_label_data_init()
471 return -ENOMEM; in nd_label_data_init()
477 * going to take given our maximum transfer size, and then reduce our in nd_label_data_init()
478 * maximum transfer size based on that result. in nd_label_data_init()
480 max_xfer = min_t(size_t, ndd->nsarea.max_xfer, config_size); in nd_label_data_init()
483 max_xfer -= ((max_xfer - 1) - (config_size - 1) % max_xfer) / in nd_label_data_init()
490 /* Make our initial read size a multiple of max_xfer size */ in nd_label_data_init()
495 rc = nvdimm_get_config_data(ndd, ndd->data, 0, read_size); in nd_label_data_init()
500 ndd->ns_current = nd_label_validate(ndd); in nd_label_data_init()
501 if (ndd->ns_current < 0) in nd_label_data_init()
505 ndd->ns_next = nd_label_next_nsindex(ndd->ns_current); in nd_label_data_init()
512 offset = __le64_to_cpu(nsindex->labeloff); in nd_label_data_init()
513 nslot = __le32_to_cpu(nsindex->nslot); in nd_label_data_init()
516 for (i = 0; i < nslot; i++, offset += ndd->nslabel_size) { in nd_label_data_init()
520 if (test_bit_le(i, nsindex->free)) { in nd_label_data_init()
521 memset(ndd->data + offset, 0, ndd->nslabel_size); in nd_label_data_init()
526 if (offset + ndd->nslabel_size <= read_size) in nd_label_data_init()
534 label_read_size = offset + ndd->nslabel_size - read_size; in nd_label_data_init()
540 label_read_size = config_size - read_size; in nd_label_data_init()
543 rc = nvdimm_get_config_data(ndd, ndd->data + read_size, in nd_label_data_init()
552 dev_dbg(ndd->dev, "len: %zu rc: %d\n", offset, rc); in nd_label_data_init()
561 u32 nslot, slot; in nd_label_active_count() local
567 for_each_clear_bit_le(slot, free, nslot) { in nd_label_active_count()
570 nd_label = to_label(ndd, slot); in nd_label_active_count()
572 if (!slot_valid(ndd, nd_label, slot)) { in nd_label_active_count()
574 u64 size = nsl_get_rawsize(ndd, nd_label); in nd_label_active_count() local
577 dev_dbg(ndd->dev, in nd_label_active_count()
578 "slot%d invalid slot: %d dpa: %llx size: %llx\n", in nd_label_active_count()
579 slot, label_slot, dpa, size); in nd_label_active_count()
591 u32 nslot, slot; in nd_label_active() local
596 for_each_clear_bit_le(slot, free, nslot) { in nd_label_active()
599 nd_label = to_label(ndd, slot); in nd_label_active()
600 if (!slot_valid(ndd, nd_label, slot)) in nd_label_active()
603 if (n-- == 0) in nd_label_active()
604 return to_label(ndd, slot); in nd_label_active()
614 u32 nslot, slot; in nd_label_alloc_slot() local
619 WARN_ON(!is_nvdimm_bus_locked(ndd->dev)); in nd_label_alloc_slot()
621 slot = find_next_bit_le(free, nslot, 0); in nd_label_alloc_slot()
622 if (slot == nslot) in nd_label_alloc_slot()
625 clear_bit_le(slot, free); in nd_label_alloc_slot()
627 return slot; in nd_label_alloc_slot()
630 bool nd_label_free_slot(struct nvdimm_drvdata *ndd, u32 slot) in nd_label_free_slot() argument
639 WARN_ON(!is_nvdimm_bus_locked(ndd->dev)); in nd_label_free_slot()
641 if (slot < nslot) in nd_label_free_slot()
642 return !test_and_set_bit_le(slot, free); in nd_label_free_slot()
652 WARN_ON(!is_nvdimm_bus_locked(ndd->dev)); in nd_label_nfree()
673 nslot = __le32_to_cpu(nsindex->nslot); in nd_label_write_index()
675 memcpy(nsindex->sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN); in nd_label_write_index()
676 memset(&nsindex->flags, 0, 3); in nd_label_write_index()
677 nsindex->labelsize = sizeof_namespace_label(ndd) >> 8; in nd_label_write_index()
678 nsindex->seq = __cpu_to_le32(seq); in nd_label_write_index()
680 - (unsigned long) to_namespace_index(ndd, 0); in nd_label_write_index()
681 nsindex->myoff = __cpu_to_le64(offset); in nd_label_write_index()
682 nsindex->mysize = __cpu_to_le64(sizeof_namespace_index(ndd)); in nd_label_write_index()
685 - (unsigned long) to_namespace_index(ndd, 0); in nd_label_write_index()
686 nsindex->otheroff = __cpu_to_le64(offset); in nd_label_write_index()
688 - (unsigned long) to_namespace_index(ndd, 0); in nd_label_write_index()
689 nsindex->labeloff = __cpu_to_le64(offset); in nd_label_write_index()
690 nsindex->nslot = __cpu_to_le32(nslot); in nd_label_write_index()
691 nsindex->major = __cpu_to_le16(1); in nd_label_write_index()
693 nsindex->minor = __cpu_to_le16(1); in nd_label_write_index()
695 nsindex->minor = __cpu_to_le16(2); in nd_label_write_index()
696 nsindex->checksum = __cpu_to_le64(0); in nd_label_write_index()
698 unsigned long *free = (unsigned long *) nsindex->free; in nd_label_write_index()
702 memset(nsindex->free, 0xff, nfree / 8); in nd_label_write_index()
703 for (i = 0, last_bits = nfree - nslot; i < last_bits; i++) in nd_label_write_index()
707 nsindex->checksum = __cpu_to_le64(checksum); in nd_label_write_index()
708 rc = nvdimm_set_config_data(ndd, __le64_to_cpu(nsindex->myoff), in nd_label_write_index()
717 WARN_ON(index != ndd->ns_next); in nd_label_write_index()
719 ndd->ns_current = nd_label_next_nsindex(ndd->ns_current); in nd_label_write_index()
720 ndd->ns_next = nd_label_next_nsindex(ndd->ns_next); in nd_label_write_index()
721 WARN_ON(ndd->ns_current == ndd->ns_next); in nd_label_write_index()
730 - (unsigned long) to_namespace_index(ndd, 0); in nd_label_offset()
813 u32 slot = to_slot(ndd, victim->label); in reap_victim() local
815 dev_dbg(ndd->dev, "free: %d\n", slot); in reap_victim()
816 nd_label_free_slot(ndd, slot); in reap_victim()
817 victim->label = NULL; in reap_victim()
824 guid_copy(&nd_label->efi.type_guid, guid); in nsl_set_type_guid()
830 if (ndd->cxl || !efi_namespace_label_has(ndd, type_guid)) in nsl_validate_type_guid()
832 if (!guid_equal(&nd_label->efi.type_guid, guid)) { in nsl_validate_type_guid()
833 dev_dbg(ndd->dev, "expect type_guid %pUb got %pUb\n", guid, in nsl_validate_type_guid()
834 &nd_label->efi.type_guid); in nsl_validate_type_guid()
844 if (ndd->cxl) { in nsl_set_claim_class()
847 import_uuid(&uuid, nd_label->cxl.abstraction_uuid); in nsl_set_claim_class()
848 export_uuid(nd_label->cxl.abstraction_uuid, in nsl_set_claim_class()
855 guid_copy(&nd_label->efi.abstraction_guid, in nsl_set_claim_class()
857 &nd_label->efi.abstraction_guid)); in nsl_set_claim_class()
863 if (ndd->cxl) { in nsl_get_claim_class()
866 import_uuid(&uuid, nd_label->cxl.abstraction_uuid); in nsl_get_claim_class()
871 return guid_to_nvdimm_cclass(&nd_label->efi.abstraction_guid); in nsl_get_claim_class()
878 struct nd_namespace_common *ndns = &nspm->nsio.common; in __pmem_label_update()
879 struct nd_interleave_set *nd_set = nd_region->nd_set; in __pmem_label_update()
887 u32 nslot, slot; in __pmem_label_update() local
893 return -ENXIO; in __pmem_label_update()
896 nd_label_gen_id(&label_id, nspm->uuid, 0); in __pmem_label_update()
898 if (strcmp(res->name, label_id.id) == 0) in __pmem_label_update()
903 return -ENXIO; in __pmem_label_update()
907 slot = nd_label_alloc_slot(ndd); in __pmem_label_update()
908 if (slot == UINT_MAX) in __pmem_label_update()
909 return -ENXIO; in __pmem_label_update()
910 dev_dbg(ndd->dev, "allocated: %d\n", slot); in __pmem_label_update()
912 nd_label = to_label(ndd, slot); in __pmem_label_update()
914 nsl_set_uuid(ndd, nd_label, nspm->uuid); in __pmem_label_update()
915 nsl_set_name(ndd, nd_label, nspm->alt_name); in __pmem_label_update()
917 nsl_set_nlabel(ndd, nd_label, nd_region->ndr_mappings); in __pmem_label_update()
922 nsl_set_lbasize(ndd, nd_label, nspm->lbasize); in __pmem_label_update()
923 nsl_set_dpa(ndd, nd_label, res->start); in __pmem_label_update()
924 nsl_set_slot(ndd, nd_label, slot); in __pmem_label_update()
925 nsl_set_type_guid(ndd, nd_label, &nd_set->type_guid); in __pmem_label_update()
926 nsl_set_claim_class(ndd, nd_label, ndns->claim_class); in __pmem_label_update()
938 mutex_lock(&nd_mapping->lock); in __pmem_label_update()
939 list_for_each_entry(label_ent, &nd_mapping->labels, list) { in __pmem_label_update()
940 if (!label_ent->label) in __pmem_label_update()
942 if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags) || in __pmem_label_update()
943 nsl_uuid_equal(ndd, label_ent->label, nspm->uuid)) in __pmem_label_update()
948 rc = nd_label_write_index(ndd, ndd->ns_next, in __pmem_label_update()
949 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); in __pmem_label_update()
951 list_for_each_entry(label_ent, &nd_mapping->labels, list) in __pmem_label_update()
952 if (!label_ent->label) { in __pmem_label_update()
953 label_ent->label = nd_label; in __pmem_label_update()
957 dev_WARN_ONCE(&nspm->nsio.common.dev, nd_label, in __pmem_label_update()
961 rc = -ENXIO; in __pmem_label_update()
963 mutex_unlock(&nd_mapping->lock); in __pmem_label_update()
975 mutex_lock(&nd_mapping->lock); in init_labels()
976 list_for_each_entry(label_ent, &nd_mapping->labels, list) in init_labels()
978 mutex_unlock(&nd_mapping->lock); in init_labels()
987 return -ENOMEM; in init_labels()
988 mutex_lock(&nd_mapping->lock); in init_labels()
989 list_add_tail(&label_ent->list, &nd_mapping->labels); in init_labels()
990 mutex_unlock(&nd_mapping->lock); in init_labels()
993 if (ndd->ns_current == -1 || ndd->ns_next == -1) in init_labels()
999 memset(nsindex, 0, ndd->nsarea.config_size); in init_labels()
1001 int rc = nd_label_write_index(ndd, i, 3 - i, ND_NSINDEX_INIT); in init_labels()
1006 ndd->ns_next = 1; in init_labels()
1007 ndd->ns_current = 0; in init_labels()
1019 u32 nslot, slot; in del_labels() local
1029 mutex_lock(&nd_mapping->lock); in del_labels()
1030 list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { in del_labels()
1031 struct nd_namespace_label *nd_label = label_ent->label; in del_labels()
1038 active--; in del_labels()
1039 slot = to_slot(ndd, nd_label); in del_labels()
1040 nd_label_free_slot(ndd, slot); in del_labels()
1041 dev_dbg(ndd->dev, "free: %d\n", slot); in del_labels()
1042 list_move_tail(&label_ent->list, &list); in del_labels()
1043 label_ent->label = NULL; in del_labels()
1045 list_splice_tail_init(&list, &nd_mapping->labels); in del_labels()
1049 dev_dbg(ndd->dev, "no more active labels\n"); in del_labels()
1051 mutex_unlock(&nd_mapping->lock); in del_labels()
1053 return nd_label_write_index(ndd, ndd->ns_next, in del_labels()
1054 nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0); in del_labels()
1058 struct nd_namespace_pmem *nspm, resource_size_t size) in nd_pmem_namespace_label_update() argument
1062 for (i = 0; i < nd_region->ndr_mappings; i++) { in nd_pmem_namespace_label_update()
1063 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; in nd_pmem_namespace_label_update()
1068 if (size == 0) { in nd_pmem_namespace_label_update()
1069 rc = del_labels(nd_mapping, nspm->uuid); in nd_pmem_namespace_label_update()
1076 if (strncmp(res->name, "pmem", 4) == 0) in nd_pmem_namespace_label_update()
1090 if (size == 0) in nd_pmem_namespace_label_update()
1094 for (i = 0; i < nd_region->ndr_mappings; i++) { in nd_pmem_namespace_label_update()
1095 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; in nd_pmem_namespace_label_update()