Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm, dax: Make sure dm_dax_flush() is called if device supports it

Currently dm_dax_flush() is not being called, even if underlying dax
device supports write cache, because DAXDEV_WRITE_CACHE is not being
propagated up to the DM dax device.

If the underlying dax device supports write cache, set
DAXDEV_WRITE_CACHE on the DM dax device. This will cause dm_dax_flush()
to be called.

Fixes: abebfbe2f7 ("dm: add ->flush() dax operation support")
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Vivek Goyal and committed by
Mike Snitzer
273752c9 34c96507

+42
+6
drivers/dax/super.c
··· 278 278 } 279 279 EXPORT_SYMBOL_GPL(dax_write_cache); 280 280 281 + bool dax_write_cache_enabled(struct dax_device *dax_dev) 282 + { 283 + return test_bit(DAXDEV_WRITE_CACHE, &dax_dev->flags); 284 + } 285 + EXPORT_SYMBOL_GPL(dax_write_cache_enabled); 286 + 281 287 bool dax_alive(struct dax_device *dax_dev) 282 288 { 283 289 lockdep_assert_held(&dax_srcu);
+35
drivers/md/dm-table.c
··· 20 20 #include <linux/atomic.h> 21 21 #include <linux/blk-mq.h> 22 22 #include <linux/mount.h> 23 + #include <linux/dax.h> 23 24 24 25 #define DM_MSG_PREFIX "table" 25 26 ··· 1631 1630 return false; 1632 1631 } 1633 1632 1633 + static int device_dax_write_cache_enabled(struct dm_target *ti, 1634 + struct dm_dev *dev, sector_t start, 1635 + sector_t len, void *data) 1636 + { 1637 + struct dax_device *dax_dev = dev->dax_dev; 1638 + 1639 + if (!dax_dev) 1640 + return false; 1641 + 1642 + if (dax_write_cache_enabled(dax_dev)) 1643 + return true; 1644 + return false; 1645 + } 1646 + 1647 + static int dm_table_supports_dax_write_cache(struct dm_table *t) 1648 + { 1649 + struct dm_target *ti; 1650 + unsigned i; 1651 + 1652 + for (i = 0; i < dm_table_get_num_targets(t); i++) { 1653 + ti = dm_table_get_target(t, i); 1654 + 1655 + if (ti->type->iterate_devices && 1656 + ti->type->iterate_devices(ti, 1657 + device_dax_write_cache_enabled, NULL)) 1658 + return true; 1659 + } 1660 + 1661 + return false; 1662 + } 1663 + 1634 1664 static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev, 1635 1665 sector_t start, sector_t len, void *data) 1636 1666 { ··· 1816 1784 fua = true; 1817 1785 } 1818 1786 blk_queue_write_cache(q, wc, fua); 1787 + 1788 + if (dm_table_supports_dax_write_cache(t)) 1789 + dax_write_cache(t->md->dax_dev, true); 1819 1790 1820 1791 /* Ensure that all underlying devices are non-rotational. */ 1821 1792 if (dm_table_all_devices_attribute(t, device_is_nonrot))
+1
include/linux/dax.h
··· 87 87 void dax_flush(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, 88 88 size_t size); 89 89 void dax_write_cache(struct dax_device *dax_dev, bool wc); 90 + bool dax_write_cache_enabled(struct dax_device *dax_dev); 90 91 91 92 /* 92 93 * We use lowest available bit in exceptional entry for locking, one bit for