Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dan Williams and committed by
Rafael J. Wysocki
33dd7075 199c8471

+46 -11
+1
drivers/nvdimm/Kconfig
··· 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
-1
drivers/nvdimm/core.c
··· 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
-1
drivers/nvdimm/nd-core.h
··· 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);
+4 -9
drivers/nvdimm/region_devs.c
··· 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> ··· 20 19 */ 21 20 #include <linux/io-64-nonatomic-hi-lo.h> 22 21 23 - static DEFINE_IDA(region_ida); 24 22 static DEFINE_PER_CPU(int, flush_idx); 25 23 26 24 static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm, ··· 133 133 put_device(&nvdimm->dev); 134 134 } 135 135 free_percpu(nd_region->lane); 136 - ida_simple_remove(&region_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 985 986 986 if (!region_buf) 987 987 return NULL; 988 - nd_region->id = ida_simple_get(&region_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 1044 return nd_region; 1045 1045 1046 1046 err_percpu: 1047 - ida_simple_remove(&region_ida, nd_region->id); 1047 + memregion_free(nd_region->id); 1048 1048 err_id: 1049 1049 kfree(region_buf); 1050 1050 return NULL; ··· 1215 1215 }; 1216 1216 1217 1217 return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict); 1218 - } 1219 - 1220 - void __exit nd_region_devs_exit(void) 1221 - { 1222 - ida_destroy(&region_ida); 1223 1218 }
+19
include/linux/memregion.h
··· 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_ */
+3
lib/Kconfig
··· 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
+1
lib/Makefile
··· 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
+18
lib/memregion.c
··· 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);