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.
Unified · Split
| @@ -4,6 +4,7 @@ menuconfig LIBNVDIMM · 3 unmodified lines | ||
| 4 | 4 | depends on PHYS_ADDR_T_64BIT |
| 5 | 5 | depends on HAS_IOMEM |
| 6 | 6 | depends on BLK_DEV |
| 7 | + select MEMREGION | |
| 7 | 8 | help |
| 8 | 9 | Generic support for non-volatile memory devices including |
| 9 | 10 | ACPI-6-NFIT defined resources. On platforms that define an |
| @@ -455,7 +455,6 @@ static __exit void libnvdimm_exit(void) · 454 unmodified lines | ||
| 455 | 455 | nd_region_exit(); |
| 456 | 456 | nvdimm_exit(); |
| 457 | 457 | nvdimm_bus_exit(); |
| 458 | − nd_region_devs_exit(); | |
| 459 | 458 | nvdimm_devs_exit(); |
| 460 | 459 | } |
| 461 | 460 | |
| @@ -114,7 +114,6 @@ struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev); · 113 unmodified lines | ||
| 114 | 114 | int __init nvdimm_bus_init(void); |
| 115 | 115 | void nvdimm_bus_exit(void); |
| 116 | 116 | void nvdimm_devs_exit(void); |
| 117 | −void nd_region_devs_exit(void); | |
| 118 | 117 | struct nd_region; |
| 119 | 118 | void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev); |
| 120 | 119 | void nd_region_create_ns_seed(struct nd_region *nd_region); |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. |
| 4 | 4 | */ |
| 5 | 5 | #include <linux/scatterlist.h> |
| 6 | +#include <linux/memregion.h> | |
| 6 | 7 | #include <linux/highmem.h> |
| 7 | 8 | #include <linux/sched.h> |
| 8 | 9 | #include <linux/slab.h> |
| @@ -19,7 +20,6 @@ · 10 unmodified lines | ||
| 19 | 20 | */ |
| 20 | 21 | #include <linux/io-64-nonatomic-hi-lo.h> |
| 21 | 22 | |
| 22 | −static DEFINE_IDA(region_ida); | |
| 23 | 23 | static DEFINE_PER_CPU(int, flush_idx); |
| 24 | 24 | |
| 25 | 25 | 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) · 107 unmodified lines | ||
| 133 | 133 | put_device(&nvdimm->dev); |
| 134 | 134 | } |
| 135 | 135 | free_percpu(nd_region->lane); |
| 136 | − ida_simple_remove(®ion_ida, nd_region->id); | |
| 136 | + memregion_free(nd_region->id); | |
| 137 | 137 | if (is_nd_blk(dev)) |
| 138 | 138 | kfree(to_nd_blk_region(dev)); |
| 139 | 139 | else |
| @@ -985,7 +985,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, · 845 unmodified lines | ||
| 985 | 985 | |
| 986 | 986 | if (!region_buf) |
| 987 | 987 | return NULL; |
| 988 | − nd_region->id = ida_simple_get(®ion_ida, 0, 0, GFP_KERNEL); | |
| 988 | + nd_region->id = memregion_alloc(GFP_KERNEL); | |
| 989 | 989 | if (nd_region->id < 0) |
| 990 | 990 | goto err_id; |
| 991 | 991 | |
| @@ -1044,7 +1044,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, · 52 unmodified lines | ||
| 1044 | 1044 | return nd_region; |
| 1045 | 1045 | |
| 1046 | 1046 | err_percpu: |
| 1047 | − ida_simple_remove(®ion_ida, nd_region->id); | |
| 1047 | + memregion_free(nd_region->id); | |
| 1048 | 1048 | err_id: |
| 1049 | 1049 | kfree(region_buf); |
| 1050 | 1050 | return NULL; |
| @@ -1216,8 +1216,3 @@ int nd_region_conflict(struct nd_region *nd_region, resource_size_t start, · 165 unmodified lines | ||
| 1216 | 1216 | |
| 1217 | 1217 | return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict); |
| 1218 | 1218 | } |
| 1219 | − | |
| 1220 | −void __exit nd_region_devs_exit(void) | |
| 1221 | −{ | |
| 1222 | − ida_destroy(®ion_ida); | |
| 1223 | −} | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef _MEMREGION_H_ | |
| 3 | +#define _MEMREGION_H_ | |
| 4 | +#include <linux/types.h> | |
| 5 | +#include <linux/errno.h> | |
| 6 | + | |
| 7 | +#ifdef CONFIG_MEMREGION | |
| 8 | +int memregion_alloc(gfp_t gfp); | |
| 9 | +void memregion_free(int id); | |
| 10 | +#else | |
| 11 | +static inline int memregion_alloc(gfp_t gfp) | |
| 12 | +{ | |
| 13 | + return -ENOMEM; | |
| 14 | +} | |
| 15 | +void memregion_free(int id) | |
| 16 | +{ | |
| 17 | +} | |
| 18 | +#endif | |
| 19 | +#endif /* _MEMREGION_H_ */ | |
| @@ -606,6 +606,9 @@ config ARCH_NO_SG_CHAIN · 605 unmodified lines | ||
| 606 | 606 | config ARCH_HAS_PMEM_API |
| 607 | 607 | bool |
| 608 | 608 | |
| 609 | +config MEMREGION | |
| 610 | + bool | |
| 611 | + | |
| 609 | 612 | # use memcpy to implement user copies for nommu architectures |
| 610 | 613 | config UACCESS_MEMCPY |
| 611 | 614 | bool |
| @@ -212,6 +212,7 @@ obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o · 211 unmodified lines | ||
| 212 | 212 | |
| 213 | 213 | obj-$(CONFIG_SG_SPLIT) += sg_split.o |
| 214 | 214 | obj-$(CONFIG_SG_POOL) += sg_pool.o |
| 215 | +obj-$(CONFIG_MEMREGION) += memregion.o | |
| 215 | 216 | obj-$(CONFIG_STMP_DEVICE) += stmp_device.o |
| 216 | 217 | obj-$(CONFIG_IRQ_POLL) += irq_poll.o |
| 217 | 218 | |
| @@ -0,0 +1,18 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* identifiers for device / performance-differentiated memory regions */ | |
| 3 | +#include <linux/idr.h> | |
| 4 | +#include <linux/types.h> | |
| 5 | + | |
| 6 | +static DEFINE_IDA(memregion_ids); | |
| 7 | + | |
| 8 | +int memregion_alloc(gfp_t gfp) | |
| 9 | +{ | |
| 10 | + return ida_alloc(&memregion_ids, gfp); | |
| 11 | +} | |
| 12 | +EXPORT_SYMBOL(memregion_alloc); | |
| 13 | + | |
| 14 | +void memregion_free(int id) | |
| 15 | +{ | |
| 16 | + ida_free(&memregion_ids, id); | |
| 17 | +} | |
| 18 | +EXPORT_SYMBOL(memregion_free); | |