Commit 3b6c6c03 authored by Dan Williams's avatar Dan Williams
Browse files

nvdimm/region: Delete nd_blk_region infrastructure



Now that the nd_namespace_blk infrastructure is removed, delete all the
region machinery to coordinate provisioning aliased capacity between
PMEM and BLK.

Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/164688418803.2879318.1302315202397235855.stgit@dwillia2-desk3.amr.corp.intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent a4b96046
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -2036,10 +2036,6 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
			cmd_mask |= nfit_mem->dsm_mask & NVDIMM_STANDARD_CMDMASK;
		}

		/* Quirk to ignore LOCAL for labels on HYPERV DIMMs */
		if (nfit_mem->family == NVDIMM_FAMILY_HYPERV)
			set_bit(NDD_NOBLK, &flags);

		if (test_bit(NFIT_MEM_LSR, &nfit_mem->flags)) {
			set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask);
			set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask);
@@ -2602,8 +2598,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
{
	static struct nd_mapping_desc mappings[ND_MAX_MAPPINGS];
	struct acpi_nfit_system_address *spa = nfit_spa->spa;
	struct nd_blk_region_desc ndbr_desc;
	struct nd_region_desc *ndr_desc;
	struct nd_region_desc *ndr_desc, _ndr_desc;
	struct nfit_memdev *nfit_memdev;
	struct nvdimm_bus *nvdimm_bus;
	struct resource res;
@@ -2619,10 +2614,10 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,

	memset(&res, 0, sizeof(res));
	memset(&mappings, 0, sizeof(mappings));
	memset(&ndbr_desc, 0, sizeof(ndbr_desc));
	memset(&_ndr_desc, 0, sizeof(_ndr_desc));
	res.start = spa->address;
	res.end = res.start + spa->length - 1;
	ndr_desc = &ndbr_desc.ndr_desc;
	ndr_desc = &_ndr_desc;
	ndr_desc->res = &res;
	ndr_desc->provider_data = nfit_spa;
	ndr_desc->attr_groups = acpi_nfit_region_attribute_groups;
+0 −2
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@ static int to_nd_device_type(struct device *dev)
		return ND_DEVICE_DIMM;
	else if (is_memory(dev))
		return ND_DEVICE_REGION_PMEM;
	else if (is_nd_blk(dev))
		return ND_DEVICE_REGION_BLK;
	else if (is_nd_dax(dev))
		return ND_DEVICE_DAX_PMEM;
	else if (is_nd_region(dev->parent))
+14 −190
Original line number Diff line number Diff line
@@ -18,10 +18,6 @@

static DEFINE_IDA(dimm_ida);

static bool noblk;
module_param(noblk, bool, 0444);
MODULE_PARM_DESC(noblk, "force disable BLK / local alias support");

/*
 * Retrieve bus and dimm handle and return if this bus supports
 * get_config_data commands
@@ -211,22 +207,6 @@ struct nvdimm *to_nvdimm(struct device *dev)
}
EXPORT_SYMBOL_GPL(to_nvdimm);

struct nvdimm *nd_blk_region_to_dimm(struct nd_blk_region *ndbr)
{
	struct nd_region *nd_region = &ndbr->nd_region;
	struct nd_mapping *nd_mapping = &nd_region->mapping[0];

	return nd_mapping->nvdimm;
}
EXPORT_SYMBOL_GPL(nd_blk_region_to_dimm);

unsigned long nd_blk_memremap_flags(struct nd_blk_region *ndbr)
{
	/* pmem mapping properties are private to libnvdimm */
	return ARCH_MEMREMAP_PMEM;
}
EXPORT_SYMBOL_GPL(nd_blk_memremap_flags);

struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping)
{
	struct nvdimm *nvdimm = nd_mapping->nvdimm;
@@ -312,8 +292,7 @@ static ssize_t flags_show(struct device *dev,
{
	struct nvdimm *nvdimm = to_nvdimm(dev);

	return sprintf(buf, "%s%s%s\n",
			test_bit(NDD_ALIASING, &nvdimm->flags) ? "alias " : "",
	return sprintf(buf, "%s%s\n",
			test_bit(NDD_LABELING, &nvdimm->flags) ? "label " : "",
			test_bit(NDD_LOCKED, &nvdimm->flags) ? "lock " : "");
}
@@ -612,8 +591,6 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,

	nvdimm->dimm_id = dimm_id;
	nvdimm->provider_data = provider_data;
	if (noblk)
		flags |= 1 << NDD_NOBLK;
	nvdimm->flags = flags;
	nvdimm->cmd_mask = cmd_mask;
	nvdimm->num_flush = num_flush;
@@ -726,133 +703,6 @@ static unsigned long dpa_align(struct nd_region *nd_region)
	return nd_region->align / nd_region->ndr_mappings;
}

int alias_dpa_busy(struct device *dev, void *data)
{
	resource_size_t map_end, blk_start, new;
	struct blk_alloc_info *info = data;
	struct nd_mapping *nd_mapping;
	struct nd_region *nd_region;
	struct nvdimm_drvdata *ndd;
	struct resource *res;
	unsigned long align;
	int i;

	if (!is_memory(dev))
		return 0;

	nd_region = to_nd_region(dev);
	for (i = 0; i < nd_region->ndr_mappings; i++) {
		nd_mapping  = &nd_region->mapping[i];
		if (nd_mapping->nvdimm == info->nd_mapping->nvdimm)
			break;
	}

	if (i >= nd_region->ndr_mappings)
		return 0;

	ndd = to_ndd(nd_mapping);
	map_end = nd_mapping->start + nd_mapping->size - 1;
	blk_start = nd_mapping->start;

	/*
	 * In the allocation case ->res is set to free space that we are
	 * looking to validate against PMEM aliasing collision rules
	 * (i.e. BLK is allocated after all aliased PMEM).
	 */
	if (info->res) {
		if (info->res->start >= nd_mapping->start
				&& info->res->start < map_end)
			/* pass */;
		else
			return 0;
	}

 retry:
	/*
	 * Find the free dpa from the end of the last pmem allocation to
	 * the end of the interleave-set mapping.
	 */
	align = dpa_align(nd_region);
	if (!align)
		return 0;

	for_each_dpa_resource(ndd, res) {
		resource_size_t start, end;

		if (strncmp(res->name, "pmem", 4) != 0)
			continue;

		start = ALIGN_DOWN(res->start, align);
		end = ALIGN(res->end + 1, align) - 1;
		if ((start >= blk_start && start < map_end)
				|| (end >= blk_start && end <= map_end)) {
			new = max(blk_start, min(map_end, end) + 1);
			if (new != blk_start) {
				blk_start = new;
				goto retry;
			}
		}
	}

	/* update the free space range with the probed blk_start */
	if (info->res && blk_start > info->res->start) {
		info->res->start = max(info->res->start, blk_start);
		if (info->res->start > info->res->end)
			info->res->end = info->res->start - 1;
		return 1;
	}

	info->available -= blk_start - nd_mapping->start;

	return 0;
}

/**
 * nd_blk_available_dpa - account the unused dpa of BLK region
 * @nd_mapping: container of dpa-resource-root + labels
 *
 * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges, but
 * we arrange for them to never start at an lower dpa than the last
 * PMEM allocation in an aliased region.
 */
resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
{
	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
	struct nd_mapping *nd_mapping = &nd_region->mapping[0];
	struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
	struct blk_alloc_info info = {
		.nd_mapping = nd_mapping,
		.available = nd_mapping->size,
		.res = NULL,
	};
	struct resource *res;
	unsigned long align;

	if (!ndd)
		return 0;

	device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);

	/* now account for busy blk allocations in unaliased dpa */
	align = dpa_align(nd_region);
	if (!align)
		return 0;
	for_each_dpa_resource(ndd, res) {
		resource_size_t start, end, size;

		if (strncmp(res->name, "blk", 3) != 0)
			continue;
		start = ALIGN_DOWN(res->start, align);
		end = ALIGN(res->end + 1, align) - 1;
		size = end - start + 1;
		if (size >= info.available)
			return 0;
		info.available -= size;
	}

	return info.available;
}

/**
 * nd_pmem_max_contiguous_dpa - For the given dimm+region, return the max
 *			   contiguous unallocated dpa range.
@@ -900,24 +750,16 @@ resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
 * nd_pmem_available_dpa - for the given dimm+region account unallocated dpa
 * @nd_mapping: container of dpa-resource-root + labels
 * @nd_region: constrain available space check to this reference region
 * @overlap: calculate available space assuming this level of overlap
 *
 * Validate that a PMEM label, if present, aligns with the start of an
 * interleave set and truncate the available size at the lowest BLK
 * overlap point.
 *
 * The expectation is that this routine is called multiple times as it
 * probes for the largest BLK encroachment for any single member DIMM of
 * the interleave set.  Once that value is determined the PMEM-limit for
 * the set can be established.
 * interleave set.
 */
resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
		struct nd_mapping *nd_mapping, resource_size_t *overlap)
				      struct nd_mapping *nd_mapping)
{
	resource_size_t map_start, map_end, busy = 0, available, blk_start;
	struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
	resource_size_t map_start, map_end, busy = 0;
	struct resource *res;
	const char *reason;
	unsigned long align;

	if (!ndd)
@@ -929,46 +771,28 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,

	map_start = nd_mapping->start;
	map_end = map_start + nd_mapping->size - 1;
	blk_start = max(map_start, map_end + 1 - *overlap);
	for_each_dpa_resource(ndd, res) {
		resource_size_t start, end;

		start = ALIGN_DOWN(res->start, align);
		end = ALIGN(res->end + 1, align) - 1;
		if (start >= map_start && start < map_end) {
			if (strncmp(res->name, "blk", 3) == 0)
				blk_start = min(blk_start,
						max(map_start, start));
			else if (end > map_end) {
				reason = "misaligned to iset";
				goto err;
			} else
			if (end > map_end) {
				nd_dbg_dpa(nd_region, ndd, res,
					   "misaligned to iset\n");
				return 0;
			}
			busy += end - start + 1;
		} else if (end >= map_start && end <= map_end) {
			if (strncmp(res->name, "blk", 3) == 0) {
				/*
				 * If a BLK allocation overlaps the start of
				 * PMEM the entire interleave set may now only
				 * be used for BLK.
				 */
				blk_start = map_start;
			} else
			busy += end - start + 1;
		} else if (map_start > start && map_start < end) {
			/* total eclipse of the mapping */
			busy += nd_mapping->size;
			blk_start = map_start;
		}
	}

	*overlap = map_end + 1 - blk_start;
	available = blk_start - map_start;
	if (busy < available)
		return ALIGN_DOWN(available - busy, align);
	return 0;

 err:
	nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason);
	if (busy < nd_mapping->size)
		return ALIGN_DOWN(nd_mapping->size - busy, align);
	return 0;
}

@@ -999,7 +823,7 @@ struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
/**
 * nvdimm_allocated_dpa - sum up the dpa currently allocated to this label_id
 * @nvdimm: container of dpa-resource-root + labels
 * @label_id: dpa resource name of the form {pmem|blk}-<human readable uuid>
 * @label_id: dpa resource name of the form pmem-<human readable uuid>
 */
resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
		struct nd_label_id *label_id)
+1 −5
Original line number Diff line number Diff line
@@ -334,8 +334,7 @@ char *nd_label_gen_id(struct nd_label_id *label_id, const uuid_t *uuid,
{
	if (!label_id || !uuid)
		return NULL;
	snprintf(label_id->id, ND_LABEL_ID_SIZE, "%s-%pUb",
			flags & NSLABEL_FLAG_LOCAL ? "blk" : "pmem", uuid);
	snprintf(label_id->id, ND_LABEL_ID_SIZE, "pmem-%pUb", uuid);
	return label_id->id;
}

@@ -406,7 +405,6 @@ int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd)
		return 0; /* no label, nothing to reserve */

	for_each_clear_bit_le(slot, free, nslot) {
		struct nvdimm *nvdimm = to_nvdimm(ndd->dev);
		struct nd_namespace_label *nd_label;
		struct nd_region *nd_region = NULL;
		struct nd_label_id label_id;
@@ -421,8 +419,6 @@ int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd)

		nsl_get_uuid(ndd, nd_label, &label_uuid);
		flags = nsl_get_flags(ndd, nd_label);
		if (test_bit(NDD_NOBLK, &nvdimm->flags))
			flags &= ~NSLABEL_FLAG_LOCAL;
		nd_label_gen_id(&label_id, &label_uuid, flags);
		res = nvdimm_allocate_dpa(ndd, &label_id,
					  nsl_get_dpa(ndd, nd_label),
+1 −1
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ struct nd_namespace_label {

/**
 * struct nd_label_id - identifier string for dpa allocation
 * @id: "{blk|pmem}-<namespace uuid>"
 * @id: "pmem-<namespace uuid>"
 */
struct nd_label_id {
	char id[ND_LABEL_ID_SIZE];
Loading