Commit f8c3500c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libnvdimm updates from Dan Williams:
 "Primarily just the virtio_pmem driver:

   - virtio_pmem

     The new virtio_pmem facility introduces a paravirtualized
     persistent memory device that allows a guest VM to use DAX
     mechanisms to access a host-file with host-page-cache. It arranges
     for MAP_SYNC to be disabled and instead triggers a host fsync()
     when a 'write-cache flush' command is sent to the virtual disk
     device.

   - Miscellaneous small fixups"

* tag 'libnvdimm-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  virtio_pmem: fix sparse warning
  xfs: disable map_sync for async flush
  ext4: disable map_sync for async flush
  dax: check synchronous mapping is supported
  dm: enable synchronous dax
  libnvdimm: add dax_dev sync flag
  virtio-pmem: Add virtio pmem driver
  libnvdimm: nd_region flush callback support
  libnvdimm, namespace: Drop uuid_t implementation detail
parents d77e9e4e 8c2e408e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2426,7 +2426,7 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
		offset = to_interleave_offset(offset, mmio);

	writeq(cmd, mmio->addr.base + offset);
	nvdimm_flush(nfit_blk->nd_region);
	nvdimm_flush(nfit_blk->nd_region, NULL);

	if (nfit_blk->dimm_flags & NFIT_BLK_DCR_LATCH)
		readq(mmio->addr.base + offset);
@@ -2475,7 +2475,7 @@ static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
	}

	if (rw)
		nvdimm_flush(nfit_blk->nd_region);
		nvdimm_flush(nfit_blk->nd_region, NULL);

	rc = read_blk_stat(nfit_blk, lane) ? -EIO : 0;
	return rc;
+1 −1
Original line number Diff line number Diff line
@@ -388,7 +388,7 @@ struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id,
	 * No 'host' or dax_operations since there is no access to this
	 * device outside of mmap of the resulting character device.
	 */
	dax_dev = alloc_dax(dev_dax, NULL, NULL);
	dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC);
	if (!dax_dev)
		goto err;

+18 −1
Original line number Diff line number Diff line
@@ -195,6 +195,8 @@ enum dax_device_flags {
	DAXDEV_ALIVE,
	/* gate whether dax_flush() calls the low level flush routine */
	DAXDEV_WRITE_CACHE,
	/* flag to check if device supports synchronous flush */
	DAXDEV_SYNC,
};

/**
@@ -372,6 +374,18 @@ bool dax_write_cache_enabled(struct dax_device *dax_dev)
}
EXPORT_SYMBOL_GPL(dax_write_cache_enabled);

bool __dax_synchronous(struct dax_device *dax_dev)
{
	return test_bit(DAXDEV_SYNC, &dax_dev->flags);
}
EXPORT_SYMBOL_GPL(__dax_synchronous);

void __set_dax_synchronous(struct dax_device *dax_dev)
{
	set_bit(DAXDEV_SYNC, &dax_dev->flags);
}
EXPORT_SYMBOL_GPL(__set_dax_synchronous);

bool dax_alive(struct dax_device *dax_dev)
{
	lockdep_assert_held(&dax_srcu);
@@ -526,7 +540,7 @@ static void dax_add_host(struct dax_device *dax_dev, const char *host)
}

struct dax_device *alloc_dax(void *private, const char *__host,
		const struct dax_operations *ops)
		const struct dax_operations *ops, unsigned long flags)
{
	struct dax_device *dax_dev;
	const char *host;
@@ -549,6 +563,9 @@ struct dax_device *alloc_dax(void *private, const char *__host,
	dax_add_host(dax_dev, host);
	dax_dev->ops = ops;
	dax_dev->private = private;
	if (flags & DAXDEV_F_SYNC)
		set_dax_synchronous(dax_dev);

	return dax_dev;

 err_dev:
+18 −6
Original line number Diff line number Diff line
@@ -881,7 +881,7 @@ void dm_table_set_type(struct dm_table *t, enum dm_queue_mode type)
EXPORT_SYMBOL_GPL(dm_table_set_type);

/* validate the dax capability of the target device span */
static int device_supports_dax(struct dm_target *ti, struct dm_dev *dev,
int device_supports_dax(struct dm_target *ti, struct dm_dev *dev,
				       sector_t start, sector_t len, void *data)
{
	int blocksize = *(int *) data;
@@ -890,7 +890,15 @@ static int device_supports_dax(struct dm_target *ti, struct dm_dev *dev,
			start, len);
}

bool dm_table_supports_dax(struct dm_table *t, int blocksize)
/* Check devices support synchronous DAX */
static int device_synchronous(struct dm_target *ti, struct dm_dev *dev,
				       sector_t start, sector_t len, void *data)
{
	return dax_synchronous(dev->dax_dev);
}

bool dm_table_supports_dax(struct dm_table *t,
			  iterate_devices_callout_fn iterate_fn, int *blocksize)
{
	struct dm_target *ti;
	unsigned i;
@@ -903,8 +911,7 @@ bool dm_table_supports_dax(struct dm_table *t, int blocksize)
			return false;

		if (!ti->type->iterate_devices ||
		    !ti->type->iterate_devices(ti, device_supports_dax,
			    &blocksize))
			!ti->type->iterate_devices(ti, iterate_fn, blocksize))
			return false;
	}

@@ -940,6 +947,7 @@ static int dm_table_determine_type(struct dm_table *t)
	struct dm_target *tgt;
	struct list_head *devices = dm_table_get_devices(t);
	enum dm_queue_mode live_md_type = dm_get_md_type(t->md);
	int page_size = PAGE_SIZE;

	if (t->type != DM_TYPE_NONE) {
		/* target already set the table's type */
@@ -984,7 +992,7 @@ static int dm_table_determine_type(struct dm_table *t)
verify_bio_based:
		/* We must use this table as bio-based */
		t->type = DM_TYPE_BIO_BASED;
		if (dm_table_supports_dax(t, PAGE_SIZE) ||
		if (dm_table_supports_dax(t, device_supports_dax, &page_size) ||
		    (list_empty(devices) && live_md_type == DM_TYPE_DAX_BIO_BASED)) {
			t->type = DM_TYPE_DAX_BIO_BASED;
		} else {
@@ -1883,6 +1891,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
			       struct queue_limits *limits)
{
	bool wc = false, fua = false;
	int page_size = PAGE_SIZE;

	/*
	 * Copy table's limits to the DM device's request_queue
@@ -1910,8 +1919,11 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
	}
	blk_queue_write_cache(q, wc, fua);

	if (dm_table_supports_dax(t, PAGE_SIZE))
	if (dm_table_supports_dax(t, device_supports_dax, &page_size)) {
		blk_queue_flag_set(QUEUE_FLAG_DAX, q);
		if (dm_table_supports_dax(t, device_synchronous, NULL))
			set_dax_synchronous(t->md->dax_dev);
	}
	else
		blk_queue_flag_clear(QUEUE_FLAG_DAX, q);

+3 −2
Original line number Diff line number Diff line
@@ -1117,7 +1117,7 @@ static bool dm_dax_supported(struct dax_device *dax_dev, struct block_device *bd
	if (!map)
		return false;

	ret = dm_table_supports_dax(map, blocksize);
	ret = dm_table_supports_dax(map, device_supports_dax, &blocksize);

	dm_put_live_table(md, srcu_idx);

@@ -1989,7 +1989,8 @@ static struct mapped_device *alloc_dev(int minor)
	sprintf(md->disk->disk_name, "dm-%d", minor);

	if (IS_ENABLED(CONFIG_DAX_DRIVER)) {
		md->dax_dev = alloc_dax(md, md->disk->disk_name, &dm_dax_ops);
		md->dax_dev = alloc_dax(md, md->disk->disk_name,
					&dm_dax_ops, 0);
		if (!md->dax_dev)
			goto bad;
	}
Loading