forked from mirrors/linux
		
	device-dax: Add /sys/class/dax backwards compatibility
On the expectation that some environments may not upgrade libdaxctl (userspace component that depends on the /sys/class/dax hierarchy), provide a default / legacy dax_pmem_compat driver. The dax_pmem_compat driver implements the original /sys/class/dax sysfs layout rather than /sys/bus/dax. When userspace is upgraded it can blacklist this module and switch to the dax_pmem driver going forward. CONFIG_DEV_DAX_PMEM_COMPAT and supporting code will be deleted according to the dax_pmem entry in Documentation/ABI/obsolete/. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
		
							parent
							
								
									d200781ef2
								
							
						
					
					
						commit
						730926c3b0
					
				
					 11 changed files with 229 additions and 50 deletions
				
			
		
							
								
								
									
										22
									
								
								Documentation/ABI/obsolete/sysfs-class-dax
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Documentation/ABI/obsolete/sysfs-class-dax
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					What:           /sys/class/dax/
 | 
				
			||||||
 | 
					Date:           May, 2016
 | 
				
			||||||
 | 
					KernelVersion:  v4.7
 | 
				
			||||||
 | 
					Contact:        linux-nvdimm@lists.01.org
 | 
				
			||||||
 | 
					Description:	Device DAX is the device-centric analogue of Filesystem
 | 
				
			||||||
 | 
							DAX (CONFIG_FS_DAX).  It allows memory ranges to be
 | 
				
			||||||
 | 
							allocated and mapped without need of an intervening file
 | 
				
			||||||
 | 
							system.  Device DAX is strict, precise and predictable.
 | 
				
			||||||
 | 
							Specifically this interface:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							1/ Guarantees fault granularity with respect to a given
 | 
				
			||||||
 | 
							page size (pte, pmd, or pud) set at configuration time.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							2/ Enforces deterministic behavior by being strict about
 | 
				
			||||||
 | 
							what fault scenarios are supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							The /sys/class/dax/ interface enumerates all the
 | 
				
			||||||
 | 
							device-dax instances in the system. The ABI is
 | 
				
			||||||
 | 
							deprecated and will be removed after 2020. It is
 | 
				
			||||||
 | 
							replaced with the DAX bus interface /sys/bus/dax/ where
 | 
				
			||||||
 | 
							device-dax instances can be found under
 | 
				
			||||||
 | 
							/sys/bus/dax/devices/
 | 
				
			||||||
| 
						 | 
					@ -23,12 +23,22 @@ config DEV_DAX
 | 
				
			||||||
config DEV_DAX_PMEM
 | 
					config DEV_DAX_PMEM
 | 
				
			||||||
	tristate "PMEM DAX: direct access to persistent memory"
 | 
						tristate "PMEM DAX: direct access to persistent memory"
 | 
				
			||||||
	depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX
 | 
						depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX
 | 
				
			||||||
 | 
						depends on m # until we can kill DEV_DAX_PMEM_COMPAT
 | 
				
			||||||
	default DEV_DAX
 | 
						default DEV_DAX
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Support raw access to persistent memory.  Note that this
 | 
						  Support raw access to persistent memory.  Note that this
 | 
				
			||||||
	  driver consumes memory ranges allocated and exported by the
 | 
						  driver consumes memory ranges allocated and exported by the
 | 
				
			||||||
	  libnvdimm sub-system.
 | 
						  libnvdimm sub-system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  Say Y if unsure
 | 
						  Say M if unsure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config DEV_DAX_PMEM_COMPAT
 | 
				
			||||||
 | 
						tristate "PMEM DAX: support the deprecated /sys/class/dax interface"
 | 
				
			||||||
 | 
						depends on DEV_DAX_PMEM
 | 
				
			||||||
 | 
						default DEV_DAX_PMEM
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Older versions of the libdaxctl library expect to find all
 | 
				
			||||||
 | 
						  device-dax instances under /sys/class/dax. If libdaxctl in
 | 
				
			||||||
 | 
						  your distribution is older than v58 say M, otherwise say N.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,9 @@
 | 
				
			||||||
# SPDX-License-Identifier: GPL-2.0
 | 
					# SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
obj-$(CONFIG_DAX) += dax.o
 | 
					obj-$(CONFIG_DAX) += dax.o
 | 
				
			||||||
obj-$(CONFIG_DEV_DAX) += device_dax.o
 | 
					obj-$(CONFIG_DEV_DAX) += device_dax.o
 | 
				
			||||||
obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
dax-y := super.o
 | 
					dax-y := super.o
 | 
				
			||||||
dax-y += bus.o
 | 
					dax-y += bus.o
 | 
				
			||||||
dax_pmem-y := pmem.o
 | 
					 | 
				
			||||||
device_dax-y := device.o
 | 
					device_dax-y := device.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-y += pmem/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,8 @@
 | 
				
			||||||
#include "dax-private.h"
 | 
					#include "dax-private.h"
 | 
				
			||||||
#include "bus.h"
 | 
					#include "bus.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct class *dax_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DEFINE_MUTEX(dax_bus_lock);
 | 
					static DEFINE_MUTEX(dax_bus_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DAX_NAME_LEN 30
 | 
					#define DAX_NAME_LEN 30
 | 
				
			||||||
| 
						 | 
					@ -310,8 +312,8 @@ static void unregister_dev_dax(void *dev)
 | 
				
			||||||
	put_device(dev);
 | 
						put_device(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
					struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
				
			||||||
		struct dev_pagemap *pgmap)
 | 
							struct dev_pagemap *pgmap, enum dev_dax_subsys subsys)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct device *parent = dax_region->dev;
 | 
						struct device *parent = dax_region->dev;
 | 
				
			||||||
	struct dax_device *dax_dev;
 | 
						struct dax_device *dax_dev;
 | 
				
			||||||
| 
						 | 
					@ -350,7 +352,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inode = dax_inode(dax_dev);
 | 
						inode = dax_inode(dax_dev);
 | 
				
			||||||
	dev->devt = inode->i_rdev;
 | 
						dev->devt = inode->i_rdev;
 | 
				
			||||||
 | 
						if (subsys == DEV_DAX_BUS)
 | 
				
			||||||
		dev->bus = &dax_bus_type;
 | 
							dev->bus = &dax_bus_type;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							dev->class = dax_class;
 | 
				
			||||||
	dev->parent = parent;
 | 
						dev->parent = parent;
 | 
				
			||||||
	dev->groups = dax_attribute_groups;
 | 
						dev->groups = dax_attribute_groups;
 | 
				
			||||||
	dev->release = dev_dax_release;
 | 
						dev->release = dev_dax_release;
 | 
				
			||||||
| 
						 | 
					@ -374,7 +379,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ERR_PTR(rc);
 | 
						return ERR_PTR(rc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(devm_create_dev_dax);
 | 
					EXPORT_SYMBOL_GPL(__devm_create_dev_dax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int match_always_count;
 | 
					static int match_always_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -407,6 +412,7 @@ EXPORT_SYMBOL_GPL(__dax_driver_register);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dax_driver_unregister(struct dax_device_driver *dax_drv)
 | 
					void dax_driver_unregister(struct dax_device_driver *dax_drv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct device_driver *drv = &dax_drv->drv;
 | 
				
			||||||
	struct dax_id *dax_id, *_id;
 | 
						struct dax_id *dax_id, *_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&dax_bus_lock);
 | 
						mutex_lock(&dax_bus_lock);
 | 
				
			||||||
| 
						 | 
					@ -416,15 +422,28 @@ void dax_driver_unregister(struct dax_device_driver *dax_drv)
 | 
				
			||||||
		kfree(dax_id);
 | 
							kfree(dax_id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&dax_bus_lock);
 | 
						mutex_unlock(&dax_bus_lock);
 | 
				
			||||||
 | 
						driver_unregister(drv);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(dax_driver_unregister);
 | 
					EXPORT_SYMBOL_GPL(dax_driver_unregister);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int __init dax_bus_init(void)
 | 
					int __init dax_bus_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return bus_register(&dax_bus_type);
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT)) {
 | 
				
			||||||
 | 
							dax_class = class_create(THIS_MODULE, "dax");
 | 
				
			||||||
 | 
							if (IS_ERR(dax_class))
 | 
				
			||||||
 | 
								return PTR_ERR(dax_class);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = bus_register(&dax_bus_type);
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							class_destroy(dax_class);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __exit dax_bus_exit(void)
 | 
					void __exit dax_bus_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bus_unregister(&dax_bus_type);
 | 
						bus_unregister(&dax_bus_type);
 | 
				
			||||||
 | 
						class_destroy(dax_class);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,8 @@
 | 
				
			||||||
/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
 | 
					/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
 | 
				
			||||||
#ifndef __DAX_BUS_H__
 | 
					#ifndef __DAX_BUS_H__
 | 
				
			||||||
#define __DAX_BUS_H__
 | 
					#define __DAX_BUS_H__
 | 
				
			||||||
struct device;
 | 
					#include <linux/device.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dev_dax;
 | 
					struct dev_dax;
 | 
				
			||||||
struct resource;
 | 
					struct resource;
 | 
				
			||||||
struct dax_device;
 | 
					struct dax_device;
 | 
				
			||||||
| 
						 | 
					@ -10,8 +11,23 @@ struct dax_region;
 | 
				
			||||||
void dax_region_put(struct dax_region *dax_region);
 | 
					void dax_region_put(struct dax_region *dax_region);
 | 
				
			||||||
struct dax_region *alloc_dax_region(struct device *parent, int region_id,
 | 
					struct dax_region *alloc_dax_region(struct device *parent, int region_id,
 | 
				
			||||||
		struct resource *res, unsigned int align, unsigned long flags);
 | 
							struct resource *res, unsigned int align, unsigned long flags);
 | 
				
			||||||
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
					
 | 
				
			||||||
		struct dev_pagemap *pgmap);
 | 
					enum dev_dax_subsys {
 | 
				
			||||||
 | 
						DEV_DAX_BUS,
 | 
				
			||||||
 | 
						DEV_DAX_CLASS,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id,
 | 
				
			||||||
 | 
							struct dev_pagemap *pgmap, enum dev_dax_subsys subsys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
 | 
				
			||||||
 | 
							int id, struct dev_pagemap *pgmap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return __devm_create_dev_dax(dax_region, id, pgmap, DEV_DAX_BUS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* to be deleted when DEV_DAX_CLASS is removed */
 | 
				
			||||||
 | 
					struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dax_device_driver {
 | 
					struct dax_device_driver {
 | 
				
			||||||
	struct device_driver drv;
 | 
						struct device_driver drv;
 | 
				
			||||||
| 
						 | 
					@ -26,6 +42,10 @@ int __dax_driver_register(struct dax_device_driver *dax_drv,
 | 
				
			||||||
void dax_driver_unregister(struct dax_device_driver *dax_drv);
 | 
					void dax_driver_unregister(struct dax_device_driver *dax_drv);
 | 
				
			||||||
void kill_dev_dax(struct dev_dax *dev_dax);
 | 
					void kill_dev_dax(struct dev_dax *dev_dax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT)
 | 
				
			||||||
 | 
					int dev_dax_probe(struct device *dev);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * While run_dax() is potentially a generic operation that could be
 | 
					 * While run_dax() is potentially a generic operation that could be
 | 
				
			||||||
 * defined in include/linux/dax.h we don't want to grow any users
 | 
					 * defined in include/linux/dax.h we don't want to grow any users
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,7 +445,7 @@ static void dev_dax_kill(void *dev_dax)
 | 
				
			||||||
	kill_dev_dax(dev_dax);
 | 
						kill_dev_dax(dev_dax);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_dax_probe(struct device *dev)
 | 
					int dev_dax_probe(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_dax *dev_dax = to_dev_dax(dev);
 | 
						struct dev_dax *dev_dax = to_dev_dax(dev);
 | 
				
			||||||
	struct dax_device *dax_dev = dev_dax->dax_dev;
 | 
						struct dax_device *dax_dev = dev_dax->dax_dev;
 | 
				
			||||||
| 
						 | 
					@ -484,6 +484,10 @@ static int dev_dax_probe(struct device *dev)
 | 
				
			||||||
	inode = dax_inode(dax_dev);
 | 
						inode = dax_inode(dax_dev);
 | 
				
			||||||
	cdev = inode->i_cdev;
 | 
						cdev = inode->i_cdev;
 | 
				
			||||||
	cdev_init(cdev, &dax_fops);
 | 
						cdev_init(cdev, &dax_fops);
 | 
				
			||||||
 | 
						if (dev->class) {
 | 
				
			||||||
 | 
							/* for the CONFIG_DEV_DAX_PMEM_COMPAT case */
 | 
				
			||||||
 | 
							cdev->owner = dev->parent->driver->owner;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
		cdev->owner = dev->driver->owner;
 | 
							cdev->owner = dev->driver->owner;
 | 
				
			||||||
	cdev_set_parent(cdev, &dev->kobj);
 | 
						cdev_set_parent(cdev, &dev->kobj);
 | 
				
			||||||
	rc = cdev_add(cdev, dev->devt, 1);
 | 
						rc = cdev_add(cdev, dev->devt, 1);
 | 
				
			||||||
| 
						 | 
					@ -497,6 +501,7 @@ static int dev_dax_probe(struct device *dev)
 | 
				
			||||||
	run_dax(dax_dev);
 | 
						run_dax(dax_dev);
 | 
				
			||||||
	return devm_add_action_or_reset(dev, dev_dax_kill, dev_dax);
 | 
						return devm_add_action_or_reset(dev, dev_dax_kill, dev_dax);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(dev_dax_probe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dev_dax_remove(struct device *dev)
 | 
					static int dev_dax_remove(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								drivers/dax/pmem/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								drivers/dax/pmem/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_DEV_DAX_PMEM_COMPAT) += dax_pmem_compat.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dax_pmem-y := pmem.o
 | 
				
			||||||
 | 
					dax_pmem_core-y := core.o
 | 
				
			||||||
 | 
					dax_pmem_compat-y := compat.o
 | 
				
			||||||
							
								
								
									
										73
									
								
								drivers/dax/pmem/compat.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								drivers/dax/pmem/compat.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 | 
					/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
 | 
				
			||||||
 | 
					#include <linux/percpu-refcount.h>
 | 
				
			||||||
 | 
					#include <linux/memremap.h>
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/pfn_t.h>
 | 
				
			||||||
 | 
					#include <linux/nd.h>
 | 
				
			||||||
 | 
					#include "../bus.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* we need the private definitions to implement compat suport */
 | 
				
			||||||
 | 
					#include "../dax-private.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dax_pmem_compat_probe(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dev_dax *dev_dax = __dax_pmem_probe(dev, DEV_DAX_CLASS);
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_ERR(dev_dax))
 | 
				
			||||||
 | 
							return PTR_ERR(dev_dax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!devres_open_group(&dev_dax->dev, dev_dax, GFP_KERNEL))
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						device_lock(&dev_dax->dev);
 | 
				
			||||||
 | 
						rc = dev_dax_probe(&dev_dax->dev);
 | 
				
			||||||
 | 
						device_unlock(&dev_dax->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						devres_close_group(&dev_dax->dev, dev_dax);
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							devres_release_group(&dev_dax->dev, dev_dax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dax_pmem_compat_release(struct device *dev, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						device_lock(dev);
 | 
				
			||||||
 | 
						devres_release_group(dev, to_dev_dax(dev));
 | 
				
			||||||
 | 
						device_unlock(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dax_pmem_compat_remove(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						device_for_each_child(dev, NULL, dax_pmem_compat_release);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct nd_device_driver dax_pmem_compat_driver = {
 | 
				
			||||||
 | 
						.probe = dax_pmem_compat_probe,
 | 
				
			||||||
 | 
						.remove = dax_pmem_compat_remove,
 | 
				
			||||||
 | 
						.drv = {
 | 
				
			||||||
 | 
							.name = "dax_pmem_compat",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.type = ND_DRIVER_DAX_PMEM,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __init dax_pmem_compat_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return nd_driver_register(&dax_pmem_compat_driver);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module_init(dax_pmem_compat_init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __exit dax_pmem_compat_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						driver_unregister(&dax_pmem_compat_driver.drv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module_exit(dax_pmem_compat_exit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL v2");
 | 
				
			||||||
 | 
					MODULE_AUTHOR("Intel Corporation");
 | 
				
			||||||
 | 
					MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DAX_PMEM);
 | 
				
			||||||
| 
						 | 
					@ -1,24 +1,13 @@
 | 
				
			||||||
/*
 | 
					// SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 * Copyright(c) 2016 Intel Corporation. All rights reserved.
 | 
					/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of version 2 of the GNU General Public License as
 | 
					 | 
				
			||||||
 * published by the Free Software Foundation.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful, but
 | 
					 | 
				
			||||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * General Public License for more details.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include <linux/percpu-refcount.h>
 | 
					 | 
				
			||||||
#include <linux/memremap.h>
 | 
					#include <linux/memremap.h>
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/pfn_t.h>
 | 
					#include <linux/pfn_t.h>
 | 
				
			||||||
#include "../nvdimm/pfn.h"
 | 
					#include "../../nvdimm/pfn.h"
 | 
				
			||||||
#include "../nvdimm/nd.h"
 | 
					#include "../../nvdimm/nd.h"
 | 
				
			||||||
#include "bus.h"
 | 
					#include "../bus.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dax_pmem_probe(struct device *dev)
 | 
					struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct resource res;
 | 
						struct resource res;
 | 
				
			||||||
	int rc, id, region_id;
 | 
						int rc, id, region_id;
 | 
				
			||||||
| 
						 | 
					@ -34,16 +23,16 @@ static int dax_pmem_probe(struct device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ndns = nvdimm_namespace_common_probe(dev);
 | 
						ndns = nvdimm_namespace_common_probe(dev);
 | 
				
			||||||
	if (IS_ERR(ndns))
 | 
						if (IS_ERR(ndns))
 | 
				
			||||||
		return PTR_ERR(ndns);
 | 
							return ERR_CAST(ndns);
 | 
				
			||||||
	nsio = to_nd_namespace_io(&ndns->dev);
 | 
						nsio = to_nd_namespace_io(&ndns->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* parse the 'pfn' info block via ->rw_bytes */
 | 
						/* parse the 'pfn' info block via ->rw_bytes */
 | 
				
			||||||
	rc = devm_nsio_enable(dev, nsio);
 | 
						rc = devm_nsio_enable(dev, nsio);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
		return rc;
 | 
							return ERR_PTR(rc);
 | 
				
			||||||
	rc = nvdimm_setup_pfn(nd_pfn, &pgmap);
 | 
						rc = nvdimm_setup_pfn(nd_pfn, &pgmap);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
		return rc;
 | 
							return ERR_PTR(rc);
 | 
				
			||||||
	devm_nsio_disable(dev, nsio);
 | 
						devm_nsio_disable(dev, nsio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reserve the metadata area, device-dax will reserve the data */
 | 
						/* reserve the metadata area, device-dax will reserve the data */
 | 
				
			||||||
| 
						 | 
					@ -52,12 +41,12 @@ static int dax_pmem_probe(struct device *dev)
 | 
				
			||||||
	if (!devm_request_mem_region(dev, nsio->res.start, offset,
 | 
						if (!devm_request_mem_region(dev, nsio->res.start, offset,
 | 
				
			||||||
				dev_name(&ndns->dev))) {
 | 
									dev_name(&ndns->dev))) {
 | 
				
			||||||
                dev_warn(dev, "could not reserve metadata\n");
 | 
					                dev_warn(dev, "could not reserve metadata\n");
 | 
				
			||||||
                return -EBUSY;
 | 
							return ERR_PTR(-EBUSY);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", ®ion_id, &id);
 | 
						rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", ®ion_id, &id);
 | 
				
			||||||
	if (rc != 2)
 | 
						if (rc != 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return ERR_PTR(-EINVAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* adjust the dax_region resource to the start of data */
 | 
						/* adjust the dax_region resource to the start of data */
 | 
				
			||||||
	memcpy(&res, &pgmap.res, sizeof(res));
 | 
						memcpy(&res, &pgmap.res, sizeof(res));
 | 
				
			||||||
| 
						 | 
					@ -65,26 +54,16 @@ static int dax_pmem_probe(struct device *dev)
 | 
				
			||||||
	dax_region = alloc_dax_region(dev, region_id, &res,
 | 
						dax_region = alloc_dax_region(dev, region_id, &res,
 | 
				
			||||||
			le32_to_cpu(pfn_sb->align), PFN_DEV|PFN_MAP);
 | 
								le32_to_cpu(pfn_sb->align), PFN_DEV|PFN_MAP);
 | 
				
			||||||
	if (!dax_region)
 | 
						if (!dax_region)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return ERR_PTR(-ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_dax = devm_create_dev_dax(dax_region, id, &pgmap);
 | 
						dev_dax = __devm_create_dev_dax(dax_region, id, &pgmap, subsys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* child dev_dax instances now own the lifetime of the dax_region */
 | 
						/* child dev_dax instances now own the lifetime of the dax_region */
 | 
				
			||||||
	dax_region_put(dax_region);
 | 
						dax_region_put(dax_region);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return PTR_ERR_OR_ZERO(dev_dax);
 | 
						return dev_dax;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(__dax_pmem_probe);
 | 
				
			||||||
static struct nd_device_driver dax_pmem_driver = {
 | 
					 | 
				
			||||||
	.probe = dax_pmem_probe,
 | 
					 | 
				
			||||||
	.drv = {
 | 
					 | 
				
			||||||
		.name = "dax_pmem",
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	.type = ND_DRIVER_DAX_PMEM,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module_nd_driver(dax_pmem_driver);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_LICENSE("GPL v2");
 | 
					MODULE_LICENSE("GPL v2");
 | 
				
			||||||
MODULE_AUTHOR("Intel Corporation");
 | 
					MODULE_AUTHOR("Intel Corporation");
 | 
				
			||||||
MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DAX_PMEM);
 | 
					 | 
				
			||||||
							
								
								
									
										40
									
								
								drivers/dax/pmem/pmem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								drivers/dax/pmem/pmem.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 | 
					/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
 | 
				
			||||||
 | 
					#include <linux/percpu-refcount.h>
 | 
				
			||||||
 | 
					#include <linux/memremap.h>
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/pfn_t.h>
 | 
				
			||||||
 | 
					#include <linux/nd.h>
 | 
				
			||||||
 | 
					#include "../bus.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dax_pmem_probe(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PTR_ERR_OR_ZERO(__dax_pmem_probe(dev, DEV_DAX_BUS));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct nd_device_driver dax_pmem_driver = {
 | 
				
			||||||
 | 
						.probe = dax_pmem_probe,
 | 
				
			||||||
 | 
						.drv = {
 | 
				
			||||||
 | 
							.name = "dax_pmem",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.type = ND_DRIVER_DAX_PMEM,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __init dax_pmem_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return nd_driver_register(&dax_pmem_driver);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module_init(dax_pmem_init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __exit dax_pmem_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						driver_unregister(&dax_pmem_driver.drv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module_exit(dax_pmem_exit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL v2");
 | 
				
			||||||
 | 
					MODULE_AUTHOR("Intel Corporation");
 | 
				
			||||||
 | 
					#if !IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT)
 | 
				
			||||||
 | 
					/* For compat builds, don't load this module by default */
 | 
				
			||||||
 | 
					MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DAX_PMEM);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,8 @@ obj-$(CONFIG_DAX) += dax.o
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
obj-$(CONFIG_DEV_DAX) += device_dax.o
 | 
					obj-$(CONFIG_DEV_DAX) += device_dax.o
 | 
				
			||||||
obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
 | 
					obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_DEV_DAX_PMEM_COMPAT) += dax_pmem_compat.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nfit-y := $(ACPI_SRC)/core.o
 | 
					nfit-y := $(ACPI_SRC)/core.o
 | 
				
			||||||
nfit-y += $(ACPI_SRC)/intel.o
 | 
					nfit-y += $(ACPI_SRC)/intel.o
 | 
				
			||||||
| 
						 | 
					@ -65,7 +67,9 @@ device_dax-y += dax-dev.o
 | 
				
			||||||
device_dax-y += device_dax_test.o
 | 
					device_dax-y += device_dax_test.o
 | 
				
			||||||
device_dax-y += config_check.o
 | 
					device_dax-y += config_check.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dax_pmem-y := $(DAX_SRC)/pmem.o
 | 
					dax_pmem-y := $(DAX_SRC)/pmem/pmem.o
 | 
				
			||||||
 | 
					dax_pmem_core-y := $(DAX_SRC)/pmem/core.o
 | 
				
			||||||
 | 
					dax_pmem_compat-y := $(DAX_SRC)/pmem/compat.o
 | 
				
			||||||
dax_pmem-y += config_check.o
 | 
					dax_pmem-y += config_check.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libnvdimm-y := $(NVDIMM_SRC)/core.o
 | 
					libnvdimm-y := $(NVDIMM_SRC)/core.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue