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 | depends on PHYS_ADDR_T_64BIT | 4 | depends on PHYS_ADDR_T_64BIT |
| 5 | depends on HAS_IOMEM | 5 | depends on HAS_IOMEM |
| 6 | depends on BLK_DEV | 6 | depends on BLK_DEV |
| 7 | select MEMREGION | ||
| 7 | help | 8 | help |
| 8 | Generic support for non-volatile memory devices including | 9 | Generic support for non-volatile memory devices including |
| 9 | ACPI-6-NFIT defined resources. On platforms that define an | 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 | nd_region_exit(); | 455 | nd_region_exit(); |
| 456 | nvdimm_exit(); | 456 | nvdimm_exit(); |
| 457 | nvdimm_bus_exit(); | 457 | nvdimm_bus_exit(); |
| 458 | nd_region_devs_exit(); | ||
| 459 | nvdimm_devs_exit(); | 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 | int __init nvdimm_bus_init(void); | 114 | int __init nvdimm_bus_init(void); |
| 115 | void nvdimm_bus_exit(void); | 115 | void nvdimm_bus_exit(void); |
| 116 | void nvdimm_devs_exit(void); | 116 | void nvdimm_devs_exit(void); |
| 117 | void nd_region_devs_exit(void); | ||
| 118 | struct nd_region; | 117 | struct nd_region; |
| 119 | void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev); | 118 | void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev); |
| 120 | void nd_region_create_ns_seed(struct nd_region *nd_region); | 119 | void nd_region_create_ns_seed(struct nd_region *nd_region); |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. |
| 4 | */ | 4 | */ |
| 5 | #include <linux/scatterlist.h> | 5 | #include <linux/scatterlist.h> |
| 6 | #include <linux/memregion.h> | ||
| 6 | #include <linux/highmem.h> | 7 | #include <linux/highmem.h> |
| 7 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
| 8 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
| @@ -19,7 +20,6 @@ · 10 unmodified lines | |||
| 19 | */ | 20 | */ |
| 20 | #include <linux/io-64-nonatomic-hi-lo.h> | 21 | #include <linux/io-64-nonatomic-hi-lo.h> |
| 21 | 22 | ||
| 22 | static DEFINE_IDA(region_ida); | ||
| 23 | static DEFINE_PER_CPU(int, flush_idx); | 23 | static DEFINE_PER_CPU(int, flush_idx); |
| 24 | 24 | ||
| 25 | static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm, | 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 | put_device(&nvdimm->dev); | 133 | put_device(&nvdimm->dev); |
| 134 | } | 134 | } |
| 135 | free_percpu(nd_region->lane); | 135 | free_percpu(nd_region->lane); |
| 136 | ida_simple_remove(®ion_ida, nd_region->id); | 136 | memregion_free(nd_region->id); |
| 137 | if (is_nd_blk(dev)) | 137 | if (is_nd_blk(dev)) |
| 138 | kfree(to_nd_blk_region(dev)); | 138 | kfree(to_nd_blk_region(dev)); |
| 139 | else | 139 | else |
| @@ -985,7 +985,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, · 845 unmodified lines | |||
| 985 | 985 | ||
| 986 | if (!region_buf) | 986 | if (!region_buf) |
| 987 | return NULL; | 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 | if (nd_region->id < 0) | 989 | if (nd_region->id < 0) |
| 990 | goto err_id; | 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 | return nd_region; | 1044 | return nd_region; |
| 1045 | 1045 | ||
| 1046 | err_percpu: | 1046 | err_percpu: |
| 1047 | ida_simple_remove(®ion_ida, nd_region->id); | 1047 | memregion_free(nd_region->id); |
| 1048 | err_id: | 1048 | err_id: |
| 1049 | kfree(region_buf); | 1049 | kfree(region_buf); |
| 1050 | return NULL; | 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 | return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict); | 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 | config ARCH_HAS_PMEM_API | 606 | config ARCH_HAS_PMEM_API |
| 607 | bool | 607 | bool |
| 608 | 608 | ||
| 609 | config MEMREGION | ||
| 610 | bool | ||
| 611 | |||
| 609 | # use memcpy to implement user copies for nommu architectures | 612 | # use memcpy to implement user copies for nommu architectures |
| 610 | config UACCESS_MEMCPY | 613 | config UACCESS_MEMCPY |
| 611 | bool | 614 | bool |
| @@ -212,6 +212,7 @@ obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o · 211 unmodified lines | |||
| 212 | 212 | ||
| 213 | obj-$(CONFIG_SG_SPLIT) += sg_split.o | 213 | obj-$(CONFIG_SG_SPLIT) += sg_split.o |
| 214 | obj-$(CONFIG_SG_POOL) += sg_pool.o | 214 | obj-$(CONFIG_SG_POOL) += sg_pool.o |
| 215 | obj-$(CONFIG_MEMREGION) += memregion.o | ||
| 215 | obj-$(CONFIG_STMP_DEVICE) += stmp_device.o | 216 | obj-$(CONFIG_STMP_DEVICE) += stmp_device.o |
| 216 | obj-$(CONFIG_IRQ_POLL) += irq_poll.o | 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); | ||