forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									199c847176
								
							
						
					
					
						commit
						33dd70752c
					
				
					 8 changed files with 46 additions and 11 deletions
				
			
		| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								include/linux/memregion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								include/linux/memregion.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								lib/memregion.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lib/memregion.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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 a new issue