Skip to content

Commit

Permalink
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
 "Incremental fixes and a small feature addition on top of the main
  libnvdimm 4.12 pull request:

   - Geert noticed that tinyconfig was bloated by BLOCK selecting DAX.
     The size regression is fixed by moving all dax helpers into the
     dax-core and only specifying "select DAX" for FS_DAX and
     dax-capable drivers. He also asked for clarification of the
     NR_DEV_DAX config option which, on closer look, does not need to be
     a config option at all. Mike also throws in a DEV_DAX_PMEM fixup
     for good measure.

   - Ben's attention to detail on -stable patch submissions caught a
     case where the recent fixes to arch_copy_from_iter_pmem() missed a
     condition where we strand dirty data in the cache. This is tagged
     for -stable and will also be included in the rework of the pmem api
     to a proposed {memcpy,copy_user}_flushcache() interface for 4.13.

   - Vishal adds a feature that missed the initial pull due to pending
     review feedback. It allows the kernel to clear media errors when
     initializing a BTT (atomic sector update driver) instance on a pmem
     namespace.

   - Ross noticed that the dax_device + dax_operations conversion broke
     __dax_zero_page_range(). The nvdimm unit tests fail to check this
     path, but xfstests immediately trips over it. No excuse for missing
     this before submitting the 4.12 pull request.

  These all pass the nvdimm unit tests and an xfstests spot check. The
  set has received a build success notification from the kbuild robot"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  filesystem-dax: fix broken __dax_zero_page_range() conversion
  libnvdimm, btt: ensure that initializing metadata clears poison
  libnvdimm: add an atomic vs process context flag to rw_bytes
  x86, pmem: Fix cache flushing for iovec write < 8 bytes
  device-dax: kill NR_DEV_DAX
  block, dax: move "select DAX" from BLOCK to FS_DAX
  device-dax: Tell kbuild DEV_DAX_PMEM depends on DEV_DAX
  • Loading branch information
torvalds committed May 12, 2017
2 parents deac842 + e84b83b commit 0fcc3ab
Show file tree
Hide file tree
Showing 19 changed files with 208 additions and 136 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/pmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes,

if (bytes < 8) {
if (!IS_ALIGNED(dest, 4) || (bytes != 4))
arch_wb_cache_pmem(addr, 1);
arch_wb_cache_pmem(addr, bytes);
} else {
if (!IS_ALIGNED(dest, 8)) {
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
Expand Down
1 change: 0 additions & 1 deletion block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ menuconfig BLOCK
default y
select SBITMAP
select SRCU
select DAX
help
Provide block layer support for the kernel.

Expand Down
7 changes: 1 addition & 6 deletions drivers/dax/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ config DEV_DAX

config DEV_DAX_PMEM
tristate "PMEM DAX: direct access to persistent memory"
depends on LIBNVDIMM && NVDIMM_DAX
depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX
default DEV_DAX
help
Support raw access to persistent memory. Note that this
Expand All @@ -28,9 +28,4 @@ config DEV_DAX_PMEM

Say Y if unsure

config NR_DEV_DAX
int "Maximum number of Device-DAX instances"
default 32768
range 256 2147483647

endif
81 changes: 73 additions & 8 deletions drivers/dax/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,13 @@
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/magic.h>
#include <linux/genhd.h>
#include <linux/cdev.h>
#include <linux/hash.h>
#include <linux/slab.h>
#include <linux/dax.h>
#include <linux/fs.h>

static int nr_dax = CONFIG_NR_DEV_DAX;
module_param(nr_dax, int, S_IRUGO);
MODULE_PARM_DESC(nr_dax, "max number of dax device instances");

static dev_t dax_devt;
DEFINE_STATIC_SRCU(dax_srcu);
static struct vfsmount *dax_mnt;
Expand All @@ -47,6 +44,75 @@ void dax_read_unlock(int id)
}
EXPORT_SYMBOL_GPL(dax_read_unlock);

int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
pgoff_t *pgoff)
{
phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;

if (pgoff)
*pgoff = PHYS_PFN(phys_off);
if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
return -EINVAL;
return 0;
}
EXPORT_SYMBOL(bdev_dax_pgoff);

/**
* __bdev_dax_supported() - Check if the device supports dax for filesystem
* @sb: The superblock of the device
* @blocksize: The block size of the device
*
* This is a library function for filesystems to check if the block device
* can be mounted with dax option.
*
* Return: negative errno if unsupported, 0 if supported.
*/
int __bdev_dax_supported(struct super_block *sb, int blocksize)
{
struct block_device *bdev = sb->s_bdev;
struct dax_device *dax_dev;
pgoff_t pgoff;
int err, id;
void *kaddr;
pfn_t pfn;
long len;

if (blocksize != PAGE_SIZE) {
pr_err("VFS (%s): error: unsupported blocksize for dax\n",
sb->s_id);
return -EINVAL;
}

err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
if (err) {
pr_err("VFS (%s): error: unaligned partition for dax\n",
sb->s_id);
return err;
}

dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
if (!dax_dev) {
pr_err("VFS (%s): error: device does not support dax\n",
sb->s_id);
return -EOPNOTSUPP;
}

id = dax_read_lock();
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
dax_read_unlock(id);

put_dax(dax_dev);

if (len < 1) {
pr_err("VFS (%s): error: dax access failed (%ld)",
sb->s_id, len);
return len < 0 ? len : -EIO;
}

return 0;
}
EXPORT_SYMBOL_GPL(__bdev_dax_supported);

/**
* struct dax_device - anchor object for dax services
* @inode: core vfs
Expand Down Expand Up @@ -261,7 +327,7 @@ struct dax_device *alloc_dax(void *private, const char *__host,
if (__host && !host)
return NULL;

minor = ida_simple_get(&dax_minor_ida, 0, nr_dax, GFP_KERNEL);
minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
if (minor < 0)
goto err_minor;

Expand Down Expand Up @@ -405,16 +471,15 @@ static int __init dax_fs_init(void)
if (rc)
return rc;

nr_dax = max(nr_dax, 256);
rc = alloc_chrdev_region(&dax_devt, 0, nr_dax, "dax");
rc = alloc_chrdev_region(&dax_devt, 0, MINORMASK+1, "dax");
if (rc)
__dax_fs_exit();
return rc;
}

static void __exit dax_fs_exit(void)
{
unregister_chrdev_region(dax_devt, nr_dax);
unregister_chrdev_region(dax_devt, MINORMASK+1);
ida_destroy(&dax_minor_ida);
__dax_fs_exit();
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/nvdimm/blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio)
}

static int nsblk_rw_bytes(struct nd_namespace_common *ndns,
resource_size_t offset, void *iobuf, size_t n, int rw)
resource_size_t offset, void *iobuf, size_t n, int rw,
unsigned long flags)
{
struct nd_namespace_blk *nsblk = to_nd_namespace_blk(&ndns->dev);
struct nd_blk_region *ndbr = to_ndbr(nsblk);
Expand Down
Loading

0 comments on commit 0fcc3ab

Please sign in to comment.