lib: Uplevel the pmem "region" ida to a global allocator
In preparation for handling platform differentiated memory types beyond persistent memory, uplevel the "region" identifier to a global number space. This enables a device-dax instance to be registered to any memory type with guaranteed unique names. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
199c847176
commit
33dd70752c
|
@ -4,6 +4,7 @@ menuconfig LIBNVDIMM
|
||||||
depends on PHYS_ADDR_T_64BIT
|
depends on PHYS_ADDR_T_64BIT
|
||||||
depends on HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
depends on BLK_DEV
|
depends on BLK_DEV
|
||||||
|
select MEMREGION
|
||||||
help
|
help
|
||||||
Generic support for non-volatile memory devices including
|
Generic support for non-volatile memory devices including
|
||||||
ACPI-6-NFIT defined resources. On platforms that define an
|
ACPI-6-NFIT defined resources. On platforms that define an
|
||||||
|
|
|
@ -455,7 +455,6 @@ static __exit void libnvdimm_exit(void)
|
||||||
nd_region_exit();
|
nd_region_exit();
|
||||||
nvdimm_exit();
|
nvdimm_exit();
|
||||||
nvdimm_bus_exit();
|
nvdimm_bus_exit();
|
||||||
nd_region_devs_exit();
|
|
||||||
nvdimm_devs_exit();
|
nvdimm_devs_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,6 @@ struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev);
|
||||||
int __init nvdimm_bus_init(void);
|
int __init nvdimm_bus_init(void);
|
||||||
void nvdimm_bus_exit(void);
|
void nvdimm_bus_exit(void);
|
||||||
void nvdimm_devs_exit(void);
|
void nvdimm_devs_exit(void);
|
||||||
void nd_region_devs_exit(void);
|
|
||||||
struct nd_region;
|
struct nd_region;
|
||||||
void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev);
|
void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev);
|
||||||
void nd_region_create_ns_seed(struct nd_region *nd_region);
|
void nd_region_create_ns_seed(struct nd_region *nd_region);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/memregion.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/io-64-nonatomic-hi-lo.h>
|
#include <linux/io-64-nonatomic-hi-lo.h>
|
||||||
|
|
||||||
static DEFINE_IDA(region_ida);
|
|
||||||
static DEFINE_PER_CPU(int, flush_idx);
|
static DEFINE_PER_CPU(int, flush_idx);
|
||||||
|
|
||||||
static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm,
|
static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm,
|
||||||
|
@ -133,7 +133,7 @@ static void nd_region_release(struct device *dev)
|
||||||
put_device(&nvdimm->dev);
|
put_device(&nvdimm->dev);
|
||||||
}
|
}
|
||||||
free_percpu(nd_region->lane);
|
free_percpu(nd_region->lane);
|
||||||
ida_simple_remove(®ion_ida, nd_region->id);
|
memregion_free(nd_region->id);
|
||||||
if (is_nd_blk(dev))
|
if (is_nd_blk(dev))
|
||||||
kfree(to_nd_blk_region(dev));
|
kfree(to_nd_blk_region(dev));
|
||||||
else
|
else
|
||||||
|
@ -985,7 +985,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
|
||||||
|
|
||||||
if (!region_buf)
|
if (!region_buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
nd_region->id = ida_simple_get(®ion_ida, 0, 0, GFP_KERNEL);
|
nd_region->id = memregion_alloc(GFP_KERNEL);
|
||||||
if (nd_region->id < 0)
|
if (nd_region->id < 0)
|
||||||
goto err_id;
|
goto err_id;
|
||||||
|
|
||||||
|
@ -1044,7 +1044,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
|
||||||
return nd_region;
|
return nd_region;
|
||||||
|
|
||||||
err_percpu:
|
err_percpu:
|
||||||
ida_simple_remove(®ion_ida, nd_region->id);
|
memregion_free(nd_region->id);
|
||||||
err_id:
|
err_id:
|
||||||
kfree(region_buf);
|
kfree(region_buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1216,8 +1216,3 @@ int nd_region_conflict(struct nd_region *nd_region, resource_size_t start,
|
||||||
|
|
||||||
return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict);
|
return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __exit nd_region_devs_exit(void)
|
|
||||||
{
|
|
||||||
ida_destroy(®ion_ida);
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef _MEMREGION_H_
|
||||||
|
#define _MEMREGION_H_
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_MEMREGION
|
||||||
|
int memregion_alloc(gfp_t gfp);
|
||||||
|
void memregion_free(int id);
|
||||||
|
#else
|
||||||
|
static inline int memregion_alloc(gfp_t gfp)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
void memregion_free(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _MEMREGION_H_ */
|
|
@ -606,6 +606,9 @@ config ARCH_NO_SG_CHAIN
|
||||||
config ARCH_HAS_PMEM_API
|
config ARCH_HAS_PMEM_API
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config MEMREGION
|
||||||
|
bool
|
||||||
|
|
||||||
# use memcpy to implement user copies for nommu architectures
|
# use memcpy to implement user copies for nommu architectures
|
||||||
config UACCESS_MEMCPY
|
config UACCESS_MEMCPY
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -212,6 +212,7 @@ obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o
|
||||||
|
|
||||||
obj-$(CONFIG_SG_SPLIT) += sg_split.o
|
obj-$(CONFIG_SG_SPLIT) += sg_split.o
|
||||||
obj-$(CONFIG_SG_POOL) += sg_pool.o
|
obj-$(CONFIG_SG_POOL) += sg_pool.o
|
||||||
|
obj-$(CONFIG_MEMREGION) += memregion.o
|
||||||
obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
|
obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
|
||||||
obj-$(CONFIG_IRQ_POLL) += irq_poll.o
|
obj-$(CONFIG_IRQ_POLL) += irq_poll.o
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/* identifiers for device / performance-differentiated memory regions */
|
||||||
|
#include <linux/idr.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
static DEFINE_IDA(memregion_ids);
|
||||||
|
|
||||||
|
int memregion_alloc(gfp_t gfp)
|
||||||
|
{
|
||||||
|
return ida_alloc(&memregion_ids, gfp);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memregion_alloc);
|
||||||
|
|
||||||
|
void memregion_free(int id)
|
||||||
|
{
|
||||||
|
ida_free(&memregion_ids, id);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memregion_free);
|
Loading…
Reference in New Issue