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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'libnvdimm-fixes-5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:

- Fix a regression that disabled device-mapper dax support

- Remove unnecessary hardened-user-copy overhead (>30%) for dax
read(2)/write(2).

- Fix some compilation warnings.

* tag 'libnvdimm-fixes-5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
libnvdimm/pmem: Bypass CONFIG_HARDENED_USERCOPY overhead
dax: Arrange for dax_supported check to span multiple devices
libnvdimm: Fix compilation warnings with W=1

+129 -43
+57 -31
drivers/dax/super.c
··· 73 73 EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev); 74 74 #endif 75 75 76 - /** 77 - * __bdev_dax_supported() - Check if the device supports dax for filesystem 78 - * @bdev: block device to check 79 - * @blocksize: The block size of the device 80 - * 81 - * This is a library function for filesystems to check if the block device 82 - * can be mounted with dax option. 83 - * 84 - * Return: true if supported, false if unsupported 85 - */ 86 - bool __bdev_dax_supported(struct block_device *bdev, int blocksize) 76 + bool __generic_fsdax_supported(struct dax_device *dax_dev, 77 + struct block_device *bdev, int blocksize, sector_t start, 78 + sector_t sectors) 87 79 { 88 - struct dax_device *dax_dev; 89 80 bool dax_enabled = false; 90 81 pgoff_t pgoff, pgoff_end; 91 - struct request_queue *q; 92 82 char buf[BDEVNAME_SIZE]; 93 83 void *kaddr, *end_kaddr; 94 84 pfn_t pfn, end_pfn; ··· 92 102 return false; 93 103 } 94 104 95 - q = bdev_get_queue(bdev); 96 - if (!q || !blk_queue_dax(q)) { 97 - pr_debug("%s: error: request queue doesn't support dax\n", 98 - bdevname(bdev, buf)); 99 - return false; 100 - } 101 - 102 - err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff); 105 + err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff); 103 106 if (err) { 104 107 pr_debug("%s: error: unaligned partition for dax\n", 105 108 bdevname(bdev, buf)); 106 109 return false; 107 110 } 108 111 109 - last_page = PFN_DOWN(i_size_read(bdev->bd_inode) - 1) * 8; 112 + last_page = PFN_DOWN((start + sectors - 1) * 512) * PAGE_SIZE / 512; 110 113 err = bdev_dax_pgoff(bdev, last_page, PAGE_SIZE, &pgoff_end); 111 114 if (err) { 112 115 pr_debug("%s: error: unaligned partition for dax\n", 113 - bdevname(bdev, buf)); 114 - return false; 115 - } 116 - 117 - dax_dev = dax_get_by_host(bdev->bd_disk->disk_name); 118 - if (!dax_dev) { 119 - pr_debug("%s: error: device does not support dax\n", 120 116 bdevname(bdev, buf)); 121 117 return false; 122 118 } ··· 111 135 len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn); 112 136 len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn); 113 137 dax_read_unlock(id); 114 - 115 - put_dax(dax_dev); 116 138 117 139 if (len < 1 || len2 < 1) { 118 140 pr_debug("%s: error: dax access failed (%ld)\n", ··· 151 177 return false; 152 178 } 153 179 return true; 180 + } 181 + EXPORT_SYMBOL_GPL(__generic_fsdax_supported); 182 + 183 + /** 184 + * __bdev_dax_supported() - Check if the device supports dax for filesystem 185 + * @bdev: block device to check 186 + * @blocksize: The block size of the device 187 + * 188 + * This is a library function for filesystems to check if the block device 189 + * can be mounted with dax option. 190 + * 191 + * Return: true if supported, false if unsupported 192 + */ 193 + bool __bdev_dax_supported(struct block_device *bdev, int blocksize) 194 + { 195 + struct dax_device *dax_dev; 196 + struct request_queue *q; 197 + char buf[BDEVNAME_SIZE]; 198 + bool ret; 199 + int id; 200 + 201 + q = bdev_get_queue(bdev); 202 + if (!q || !blk_queue_dax(q)) { 203 + pr_debug("%s: error: request queue doesn't support dax\n", 204 + bdevname(bdev, buf)); 205 + return false; 206 + } 207 + 208 + dax_dev = dax_get_by_host(bdev->bd_disk->disk_name); 209 + if (!dax_dev) { 210 + pr_debug("%s: error: device does not support dax\n", 211 + bdevname(bdev, buf)); 212 + return false; 213 + } 214 + 215 + id = dax_read_lock(); 216 + ret = dax_supported(dax_dev, bdev, blocksize, 0, 217 + i_size_read(bdev->bd_inode) / 512); 218 + dax_read_unlock(id); 219 + 220 + put_dax(dax_dev); 221 + 222 + return ret; 154 223 } 155 224 EXPORT_SYMBOL_GPL(__bdev_dax_supported); 156 225 #endif ··· 319 302 return min(avail, nr_pages); 320 303 } 321 304 EXPORT_SYMBOL_GPL(dax_direct_access); 305 + 306 + bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev, 307 + int blocksize, sector_t start, sector_t len) 308 + { 309 + if (!dax_alive(dax_dev)) 310 + return false; 311 + 312 + return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len); 313 + } 322 314 323 315 size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, 324 316 size_t bytes, struct iov_iter *i)
+11 -6
drivers/md/dm-table.c
··· 880 880 } 881 881 EXPORT_SYMBOL_GPL(dm_table_set_type); 882 882 883 + /* validate the dax capability of the target device span */ 883 884 static int device_supports_dax(struct dm_target *ti, struct dm_dev *dev, 884 - sector_t start, sector_t len, void *data) 885 + sector_t start, sector_t len, void *data) 885 886 { 886 - return bdev_dax_supported(dev->bdev, PAGE_SIZE); 887 + int blocksize = *(int *) data; 888 + 889 + return generic_fsdax_supported(dev->dax_dev, dev->bdev, blocksize, 890 + start, len); 887 891 } 888 892 889 - static bool dm_table_supports_dax(struct dm_table *t) 893 + bool dm_table_supports_dax(struct dm_table *t, int blocksize) 890 894 { 891 895 struct dm_target *ti; 892 896 unsigned i; ··· 903 899 return false; 904 900 905 901 if (!ti->type->iterate_devices || 906 - !ti->type->iterate_devices(ti, device_supports_dax, NULL)) 902 + !ti->type->iterate_devices(ti, device_supports_dax, 903 + &blocksize)) 907 904 return false; 908 905 } 909 906 ··· 984 979 verify_bio_based: 985 980 /* We must use this table as bio-based */ 986 981 t->type = DM_TYPE_BIO_BASED; 987 - if (dm_table_supports_dax(t) || 982 + if (dm_table_supports_dax(t, PAGE_SIZE) || 988 983 (list_empty(devices) && live_md_type == DM_TYPE_DAX_BIO_BASED)) { 989 984 t->type = DM_TYPE_DAX_BIO_BASED; 990 985 } else { ··· 1910 1905 } 1911 1906 blk_queue_write_cache(q, wc, fua); 1912 1907 1913 - if (dm_table_supports_dax(t)) 1908 + if (dm_table_supports_dax(t, PAGE_SIZE)) 1914 1909 blk_queue_flag_set(QUEUE_FLAG_DAX, q); 1915 1910 else 1916 1911 blk_queue_flag_clear(QUEUE_FLAG_DAX, q);
+20
drivers/md/dm.c
··· 1107 1107 return ret; 1108 1108 } 1109 1109 1110 + static bool dm_dax_supported(struct dax_device *dax_dev, struct block_device *bdev, 1111 + int blocksize, sector_t start, sector_t len) 1112 + { 1113 + struct mapped_device *md = dax_get_private(dax_dev); 1114 + struct dm_table *map; 1115 + int srcu_idx; 1116 + bool ret; 1117 + 1118 + map = dm_get_live_table(md, &srcu_idx); 1119 + if (!map) 1120 + return false; 1121 + 1122 + ret = dm_table_supports_dax(map, blocksize); 1123 + 1124 + dm_put_live_table(md, srcu_idx); 1125 + 1126 + return ret; 1127 + } 1128 + 1110 1129 static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, 1111 1130 void *addr, size_t bytes, struct iov_iter *i) 1112 1131 { ··· 3213 3194 3214 3195 static const struct dax_operations dm_dax_ops = { 3215 3196 .direct_access = dm_dax_direct_access, 3197 + .dax_supported = dm_dax_supported, 3216 3198 .copy_from_iter = dm_dax_copy_from_iter, 3217 3199 .copy_to_iter = dm_dax_copy_to_iter, 3218 3200 };
+1
drivers/md/dm.h
··· 72 72 bool dm_table_request_based(struct dm_table *t); 73 73 void dm_table_free_md_mempools(struct dm_table *t); 74 74 struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); 75 + bool dm_table_supports_dax(struct dm_table *t, int blocksize); 75 76 76 77 void dm_lock_md_type(struct mapped_device *md); 77 78 void dm_unlock_md_type(struct mapped_device *md);
+2 -2
drivers/nvdimm/bus.c
··· 642 642 NULL, 643 643 }; 644 644 645 - /** 645 + /* 646 646 * nd_device_attribute_group - generic attributes for all devices on an nd bus 647 647 */ 648 648 struct attribute_group nd_device_attribute_group = { ··· 671 671 return a->mode; 672 672 } 673 673 674 - /** 674 + /* 675 675 * nd_numa_attribute_group - NUMA attributes for all devices on an nd bus 676 676 */ 677 677 struct attribute_group nd_numa_attribute_group = {
+2
drivers/nvdimm/label.c
··· 25 25 static guid_t nvdimm_pfn_guid; 26 26 static guid_t nvdimm_dax_guid; 27 27 28 + static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0"; 29 + 28 30 static u32 best_seq(u32 a, u32 b) 29 31 { 30 32 a &= NSINDEX_SEQ_MASK;
-2
drivers/nvdimm/label.h
··· 38 38 ND_NSINDEX_INIT = 0x1, 39 39 }; 40 40 41 - static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0"; 42 - 43 41 /** 44 42 * struct nd_namespace_index - label set superblock 45 43 * @sig: NAMESPACE_INDEX\0
+9 -2
drivers/nvdimm/pmem.c
··· 281 281 return __pmem_direct_access(pmem, pgoff, nr_pages, kaddr, pfn); 282 282 } 283 283 284 + /* 285 + * Use the 'no check' versions of copy_from_iter_flushcache() and 286 + * copy_to_iter_mcsafe() to bypass HARDENED_USERCOPY overhead. Bounds 287 + * checking, both file offset and device offset, is handled by 288 + * dax_iomap_actor() 289 + */ 284 290 static size_t pmem_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, 285 291 void *addr, size_t bytes, struct iov_iter *i) 286 292 { 287 - return copy_from_iter_flushcache(addr, bytes, i); 293 + return _copy_from_iter_flushcache(addr, bytes, i); 288 294 } 289 295 290 296 static size_t pmem_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, 291 297 void *addr, size_t bytes, struct iov_iter *i) 292 298 { 293 - return copy_to_iter_mcsafe(addr, bytes, i); 299 + return _copy_to_iter_mcsafe(addr, bytes, i); 294 300 } 295 301 296 302 static const struct dax_operations pmem_dax_ops = { 297 303 .direct_access = pmem_dax_direct_access, 304 + .dax_supported = generic_fsdax_supported, 298 305 .copy_from_iter = pmem_copy_from_iter, 299 306 .copy_to_iter = pmem_copy_to_iter, 300 307 };
+1
drivers/s390/block/dcssblk.c
··· 59 59 60 60 static const struct dax_operations dcssblk_dax_ops = { 61 61 .direct_access = dcssblk_dax_direct_access, 62 + .dax_supported = generic_fsdax_supported, 62 63 .copy_from_iter = dcssblk_dax_copy_from_iter, 63 64 .copy_to_iter = dcssblk_dax_copy_to_iter, 64 65 };
+26
include/linux/dax.h
··· 19 19 */ 20 20 long (*direct_access)(struct dax_device *, pgoff_t, long, 21 21 void **, pfn_t *); 22 + /* 23 + * Validate whether this device is usable as an fsdax backing 24 + * device. 25 + */ 26 + bool (*dax_supported)(struct dax_device *, struct block_device *, int, 27 + sector_t, sector_t); 22 28 /* copy_from_iter: required operation for fs-dax direct-i/o */ 23 29 size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t, 24 30 struct iov_iter *); ··· 81 75 return __bdev_dax_supported(bdev, blocksize); 82 76 } 83 77 78 + bool __generic_fsdax_supported(struct dax_device *dax_dev, 79 + struct block_device *bdev, int blocksize, sector_t start, 80 + sector_t sectors); 81 + static inline bool generic_fsdax_supported(struct dax_device *dax_dev, 82 + struct block_device *bdev, int blocksize, sector_t start, 83 + sector_t sectors) 84 + { 85 + return __generic_fsdax_supported(dax_dev, bdev, blocksize, start, 86 + sectors); 87 + } 88 + 84 89 static inline struct dax_device *fs_dax_get_by_host(const char *host) 85 90 { 86 91 return dax_get_by_host(host); ··· 112 95 #else 113 96 static inline bool bdev_dax_supported(struct block_device *bdev, 114 97 int blocksize) 98 + { 99 + return false; 100 + } 101 + 102 + static inline bool generic_fsdax_supported(struct dax_device *dax_dev, 103 + struct block_device *bdev, int blocksize, sector_t start, 104 + sector_t sectors) 115 105 { 116 106 return false; 117 107 } ··· 166 142 void *dax_get_private(struct dax_device *dax_dev); 167 143 long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages, 168 144 void **kaddr, pfn_t *pfn); 145 + bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev, 146 + int blocksize, sector_t start, sector_t len); 169 147 size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, 170 148 size_t bytes, struct iov_iter *i); 171 149 size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,