diff options
author | Dan Williams <dan.j.williams@intel.com> | 2016-10-05 01:09:59 +0200 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2016-10-07 18:22:53 +0200 |
commit | 762d067dbad5f32560cb1657b7ca20034332dc56 (patch) | |
tree | 2d8b4300b38d277dfff626a067d44b1c3cf832b0 /drivers/nvdimm/dimm_devs.c | |
parent | libnvdimm, namespace: update label implementation for multi-pmem (diff) | |
download | linux-762d067dbad5f32560cb1657b7ca20034332dc56.tar.xz linux-762d067dbad5f32560cb1657b7ca20034332dc56.zip |
libnvdimm, namespace: enable allocation of multiple pmem namespaces
Now that we have nd_region_available_dpa() able to handle the presence
of multiple PMEM allocations in aliased PMEM regions, reuse that same
infrastructure to track allocations from free space. In particular
handle allocating from an aliased PMEM region in the case where there
are dis-contiguous holes. The allocation for BLK and PMEM are
documented in the space_valid() helper:
BLK-space is valid as long as it does not precede a PMEM
allocation in a given region. PMEM-space must be contiguous
and adjacent to an existing existing allocation (if one
exists).
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/dimm_devs.c')
-rw-r--r-- | drivers/nvdimm/dimm_devs.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 4b0296ccb375..d614493ad5ac 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -386,13 +386,7 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, } EXPORT_SYMBOL_GPL(nvdimm_create); -struct blk_alloc_info { - struct nd_mapping *nd_mapping; - resource_size_t available, busy; - struct resource *res; -}; - -static int alias_dpa_busy(struct device *dev, void *data) +int alias_dpa_busy(struct device *dev, void *data) { resource_size_t map_end, blk_start, new, busy; struct blk_alloc_info *info = data; @@ -418,6 +412,20 @@ static int alias_dpa_busy(struct device *dev, void *data) 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 @@ -447,7 +455,16 @@ static int alias_dpa_busy(struct device *dev, void *data) } } + /* 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 + busy; + return 0; } @@ -508,6 +525,7 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region) struct blk_alloc_info info = { .nd_mapping = nd_mapping, .available = nd_mapping->size, + .res = NULL, }; struct resource *res; |