Commit 8759957b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libnvdimm updates from Dan Williams:

 - Asynchronous address range scrub:

     Given the capacities of next generation persistent memory devices a
     scrub operation to find all poison may take 10s of seconds.  We
     want this scrub work to be done asynchronously with the rest of
     system initialization, so we move it out of line from the NFIT
     probing, i.e. acpi_nfit_add().

 - Clear poison:

     ACPI 6.1 introduces the ability to send "clear error" commands to
     the ACPI0012:00 device representing the root of an "nvdimm bus".
     Similar to relocating a bad block on a disk, this support clears
     media errors in response to a write.

 - Persistent memory resource tracking:

     A persistent memory range may be designated as simply "reserved" by
     platform firmware in the efi/e820 memory map.  Later when the NFIT
     driver loads it discovers that the range is "Persistent Memory".

     The NFIT bus driver inserts a resource to advertise that
     "persistent" attribute in the system resource tree for /proc/iomem
     and kernel-internal usages.

 - Miscellaneous cleanups and fixes:

     Workaround section misaligned pmem ranges when allocating a struct
     page memmap, fix handling of the read-only case in the ioctl path,
     and clean up block device major number allocation.

* tag 'libnvdimm-for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (26 commits)
  libnvdimm, pmem: clear poison on write
  libnvdimm, pmem: fix kmap_atomic() leak in error path
  nvdimm/btt: don't allocate unused major device number
  nvdimm/blk: don't allocate unused major device number
  pmem: don't allocate unused major device number
  ACPI: Change NFIT driver to insert new resource
  resource: Export insert_resource and remove_resource
  resource: Add remove_resource interface
  resource: Change __request_region to inherit from immediate parent
  libnvdimm, pmem: fix ia64 build, use PHYS_PFN
  nfit, libnvdimm: clear poison command support
  libnvdimm, pfn: 'resource'-address and 'size' attributes for pfn devices
  libnvdimm, pmem: adjust for section collisions with 'System RAM'
  libnvdimm, pmem: fix 'pfn' support for section-misaligned namespaces
  libnvdimm: Fix security issue with DSM IOCTL.
  libnvdimm: Clean-up access mode check.
  tools/testing/nvdimm: expand ars unit testing
  nfit: disable userspace initiated ars during scrub
  nfit: scrub and register regions in a workqueue
  nfit, libnvdimm: async region scrub workqueue
  ...
parents 6968e6f8 48901165
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -137,6 +137,11 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size)
	arch_wb_cache_pmem(addr, size);
}

static inline void arch_invalidate_pmem(void __pmem *addr, size_t size)
{
	clflush_cache_range((void __force *) addr, size);
}

static inline bool __arch_has_wmb_pmem(void)
{
	/*
+585 −213

File changed.

Preview size limit exceeded, changes collapsed.

+26 −4
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 */
#ifndef __NFIT_H__
#define __NFIT_H__
#include <linux/workqueue.h>
#include <linux/libnvdimm.h>
#include <linux/types.h>
#include <linux/uuid.h>
@@ -40,15 +41,32 @@ enum nfit_uuids {
	NFIT_UUID_MAX,
};

enum nfit_fic {
	NFIT_FIC_BYTE = 0x101, /* byte-addressable energy backed */
	NFIT_FIC_BLK = 0x201, /* block-addressable non-energy backed */
	NFIT_FIC_BYTEN = 0x301, /* byte-addressable non-energy backed */
};

enum {
	ND_BLK_READ_FLUSH = 1,
	ND_BLK_DCR_LATCH = 2,
	NFIT_BLK_READ_FLUSH = 1,
	NFIT_BLK_DCR_LATCH = 2,
	NFIT_ARS_STATUS_DONE = 0,
	NFIT_ARS_STATUS_BUSY = 1 << 16,
	NFIT_ARS_STATUS_NONE = 2 << 16,
	NFIT_ARS_STATUS_INTR = 3 << 16,
	NFIT_ARS_START_BUSY = 6,
	NFIT_ARS_CAP_NONE = 1,
	NFIT_ARS_F_OVERFLOW = 1,
	NFIT_ARS_TIMEOUT = 90,
};

struct nfit_spa {
	struct acpi_nfit_system_address *spa;
	struct list_head list;
	int is_registered;
	struct nd_region *nd_region;
	unsigned int ars_done:1;
	u32 clear_err_unit;
	u32 max_ars;
};

struct nfit_dcr {
@@ -110,6 +128,10 @@ struct acpi_nfit_desc {
	struct list_head idts;
	struct nvdimm_bus *nvdimm_bus;
	struct device *dev;
	struct nd_cmd_ars_status *ars_status;
	size_t ars_status_size;
	struct work_struct work;
	unsigned int cancel:1;
	unsigned long dimm_dsm_force_en;
	unsigned long bus_dsm_force_en;
	int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
@@ -182,5 +204,5 @@ static inline struct acpi_nfit_desc *to_acpi_desc(

const u8 *to_nfit_uuid(enum nfit_uuids id);
int acpi_nfit_init(struct acpi_nfit_desc *nfit, acpi_size sz);
extern const struct attribute_group *acpi_nfit_attribute_groups[];
void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
#endif /* __NFIT_H__ */
+1 −17
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ struct nd_blk_device {
	u32 internal_lbasize;
};

static int nd_blk_major;

static u32 nd_blk_meta_size(struct nd_blk_device *blk_dev)
{
	return blk_dev->nsblk->lbasize - blk_dev->sector_size;
@@ -264,7 +262,6 @@ static int nd_blk_attach_disk(struct nd_namespace_common *ndns,
	}

	disk->driverfs_dev	= &ndns->dev;
	disk->major		= nd_blk_major;
	disk->first_minor	= 0;
	disk->fops		= &nd_blk_fops;
	disk->private_data	= blk_dev;
@@ -358,25 +355,12 @@ static struct nd_device_driver nd_blk_driver = {

static int __init nd_blk_init(void)
{
	int rc;

	rc = register_blkdev(0, "nd_blk");
	if (rc < 0)
		return rc;

	nd_blk_major = rc;
	rc = nd_driver_register(&nd_blk_driver);

	if (rc < 0)
		unregister_blkdev(nd_blk_major, "nd_blk");

	return rc;
	return nd_driver_register(&nd_blk_driver);
}

static void __exit nd_blk_exit(void)
{
	driver_unregister(&nd_blk_driver.drv);
	unregister_blkdev(nd_blk_major, "nd_blk");
}

MODULE_AUTHOR("Ross Zwisler <ross.zwisler@linux.intel.com>");
+2 −17
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ enum log_ent_request {
	LOG_OLD_ENT
};

static int btt_major;

static int arena_read_bytes(struct arena_info *arena, resource_size_t offset,
		void *buf, size_t n)
{
@@ -1246,7 +1244,6 @@ static int btt_blk_init(struct btt *btt)

	nvdimm_namespace_disk_name(ndns, btt->btt_disk->disk_name);
	btt->btt_disk->driverfs_dev = &btt->nd_btt->dev;
	btt->btt_disk->major = btt_major;
	btt->btt_disk->first_minor = 0;
	btt->btt_disk->fops = &btt_fops;
	btt->btt_disk->private_data = btt;
@@ -1423,22 +1420,11 @@ EXPORT_SYMBOL(nvdimm_namespace_detach_btt);

static int __init nd_btt_init(void)
{
	int rc;

	btt_major = register_blkdev(0, "btt");
	if (btt_major < 0)
		return btt_major;
	int rc = 0;

	debugfs_root = debugfs_create_dir("btt", NULL);
	if (IS_ERR_OR_NULL(debugfs_root)) {
	if (IS_ERR_OR_NULL(debugfs_root))
		rc = -ENXIO;
		goto err_debugfs;
	}

	return 0;

 err_debugfs:
	unregister_blkdev(btt_major, "btt");

	return rc;
}
@@ -1446,7 +1432,6 @@ static int __init nd_btt_init(void)
static void __exit nd_btt_exit(void)
{
	debugfs_remove_recursive(debugfs_root);
	unregister_blkdev(btt_major, "btt");
}

MODULE_ALIAS_ND_DEVICE(ND_DEVICE_BTT);
Loading