aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-05-02 09:46:33 -0400
committerDan Williams <dan.j.williams@intel.com>2018-05-23 02:18:31 -0400
commitb3a9a0c36e1f7b9e2e6cf965c2bb973624f2b3b9 (patch)
tree54f43a8720a29159310b112cf21e7d3a3b5dce85
parent522239b445a2de988edb81672963708a6aaf9046 (diff)
dax: Introduce a ->copy_to_iter dax operation
Similar to the ->copy_from_iter() operation, a platform may want to deploy an architecture or device specific routine for handling reads from a dax_device like /dev/pmemX. On x86 this routine will point to a machine check safe version of copy_to_iter(). For now, add the plumbing to device-mapper and the dax core. Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Mike Snitzer <snitzer@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/dax/super.c10
-rw-r--r--drivers/md/dm-linear.c16
-rw-r--r--drivers/md/dm-log-writes.c15
-rw-r--r--drivers/md/dm-stripe.c21
-rw-r--r--drivers/md/dm.c25
-rw-r--r--drivers/nvdimm/pmem.c7
-rw-r--r--drivers/s390/block/dcssblk.c7
-rw-r--r--fs/dax.c3
-rw-r--r--include/linux/dax.h5
-rw-r--r--include/linux/device-mapper.h5
10 files changed, 111 insertions, 3 deletions
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 2b2332b605e4..31b839113399 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -282,6 +282,16 @@ size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
282} 282}
283EXPORT_SYMBOL_GPL(dax_copy_from_iter); 283EXPORT_SYMBOL_GPL(dax_copy_from_iter);
284 284
285size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
286 size_t bytes, struct iov_iter *i)
287{
288 if (!dax_alive(dax_dev))
289 return 0;
290
291 return dax_dev->ops->copy_to_iter(dax_dev, pgoff, addr, bytes, i);
292}
293EXPORT_SYMBOL_GPL(dax_copy_to_iter);
294
285#ifdef CONFIG_ARCH_HAS_PMEM_API 295#ifdef CONFIG_ARCH_HAS_PMEM_API
286void arch_wb_cache_pmem(void *addr, size_t size); 296void arch_wb_cache_pmem(void *addr, size_t size);
287void dax_flush(struct dax_device *dax_dev, void *addr, size_t size) 297void dax_flush(struct dax_device *dax_dev, void *addr, size_t size)
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 775c06d953b7..d10964d41fd7 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -185,9 +185,24 @@ static size_t linear_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff,
185 return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i); 185 return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
186} 186}
187 187
188static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
189 void *addr, size_t bytes, struct iov_iter *i)
190{
191 struct linear_c *lc = ti->private;
192 struct block_device *bdev = lc->dev->bdev;
193 struct dax_device *dax_dev = lc->dev->dax_dev;
194 sector_t dev_sector, sector = pgoff * PAGE_SECTORS;
195
196 dev_sector = linear_map_sector(ti, sector);
197 if (bdev_dax_pgoff(bdev, dev_sector, ALIGN(bytes, PAGE_SIZE), &pgoff))
198 return 0;
199 return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
200}
201
188#else 202#else
189#define linear_dax_direct_access NULL 203#define linear_dax_direct_access NULL
190#define linear_dax_copy_from_iter NULL 204#define linear_dax_copy_from_iter NULL
205#define linear_dax_copy_to_iter NULL
191#endif 206#endif
192 207
193static struct target_type linear_target = { 208static struct target_type linear_target = {
@@ -204,6 +219,7 @@ static struct target_type linear_target = {
204 .iterate_devices = linear_iterate_devices, 219 .iterate_devices = linear_iterate_devices,
205 .direct_access = linear_dax_direct_access, 220 .direct_access = linear_dax_direct_access,
206 .dax_copy_from_iter = linear_dax_copy_from_iter, 221 .dax_copy_from_iter = linear_dax_copy_from_iter,
222 .dax_copy_to_iter = linear_dax_copy_to_iter,
207}; 223};
208 224
209int __init dm_linear_init(void) 225int __init dm_linear_init(void)
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
index c90c7c08a77f..9ea2b0291f20 100644
--- a/drivers/md/dm-log-writes.c
+++ b/drivers/md/dm-log-writes.c
@@ -962,9 +962,23 @@ static size_t log_writes_dax_copy_from_iter(struct dm_target *ti,
962dax_copy: 962dax_copy:
963 return dax_copy_from_iter(lc->dev->dax_dev, pgoff, addr, bytes, i); 963 return dax_copy_from_iter(lc->dev->dax_dev, pgoff, addr, bytes, i);
964} 964}
965
966static size_t log_writes_dax_copy_to_iter(struct dm_target *ti,
967 pgoff_t pgoff, void *addr, size_t bytes,
968 struct iov_iter *i)
969{
970 struct log_writes_c *lc = ti->private;
971 sector_t sector = pgoff * PAGE_SECTORS;
972
973 if (bdev_dax_pgoff(lc->dev->bdev, sector, ALIGN(bytes, PAGE_SIZE), &pgoff))
974 return 0;
975 return dax_copy_to_iter(lc->dev->dax_dev, pgoff, addr, bytes, i);
976}
977
965#else 978#else
966#define log_writes_dax_direct_access NULL 979#define log_writes_dax_direct_access NULL
967#define log_writes_dax_copy_from_iter NULL 980#define log_writes_dax_copy_from_iter NULL
981#define log_writes_dax_copy_to_iter NULL
968#endif 982#endif
969 983
970static struct target_type log_writes_target = { 984static struct target_type log_writes_target = {
@@ -982,6 +996,7 @@ static struct target_type log_writes_target = {
982 .io_hints = log_writes_io_hints, 996 .io_hints = log_writes_io_hints,
983 .direct_access = log_writes_dax_direct_access, 997 .direct_access = log_writes_dax_direct_access,
984 .dax_copy_from_iter = log_writes_dax_copy_from_iter, 998 .dax_copy_from_iter = log_writes_dax_copy_from_iter,
999 .dax_copy_to_iter = log_writes_dax_copy_to_iter,
985}; 1000};
986 1001
987static int __init dm_log_writes_init(void) 1002static int __init dm_log_writes_init(void)
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index fe7fb9b1aec3..8547d7594338 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -354,9 +354,29 @@ static size_t stripe_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff,
354 return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i); 354 return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
355} 355}
356 356
357static size_t stripe_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
358 void *addr, size_t bytes, struct iov_iter *i)
359{
360 sector_t dev_sector, sector = pgoff * PAGE_SECTORS;
361 struct stripe_c *sc = ti->private;
362 struct dax_device *dax_dev;
363 struct block_device *bdev;
364 uint32_t stripe;
365
366 stripe_map_sector(sc, sector, &stripe, &dev_sector);
367 dev_sector += sc->stripe[stripe].physical_start;
368 dax_dev = sc->stripe[stripe].dev->dax_dev;
369 bdev = sc->stripe[stripe].dev->bdev;
370
371 if (bdev_dax_pgoff(bdev, dev_sector, ALIGN(bytes, PAGE_SIZE), &pgoff))
372 return 0;
373 return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
374}
375
357#else 376#else
358#define stripe_dax_direct_access NULL 377#define stripe_dax_direct_access NULL
359#define stripe_dax_copy_from_iter NULL 378#define stripe_dax_copy_from_iter NULL
379#define stripe_dax_copy_to_iter NULL
360#endif 380#endif
361 381
362/* 382/*
@@ -478,6 +498,7 @@ static struct target_type stripe_target = {
478 .io_hints = stripe_io_hints, 498 .io_hints = stripe_io_hints,
479 .direct_access = stripe_dax_direct_access, 499 .direct_access = stripe_dax_direct_access,
480 .dax_copy_from_iter = stripe_dax_copy_from_iter, 500 .dax_copy_from_iter = stripe_dax_copy_from_iter,
501 .dax_copy_to_iter = stripe_dax_copy_to_iter,
481}; 502};
482 503
483int __init dm_stripe_init(void) 504int __init dm_stripe_init(void)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 0a7b0107ca78..6752f1c25258 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1089,6 +1089,30 @@ static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
1089 return ret; 1089 return ret;
1090} 1090}
1091 1091
1092static size_t dm_dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
1093 void *addr, size_t bytes, struct iov_iter *i)
1094{
1095 struct mapped_device *md = dax_get_private(dax_dev);
1096 sector_t sector = pgoff * PAGE_SECTORS;
1097 struct dm_target *ti;
1098 long ret = 0;
1099 int srcu_idx;
1100
1101 ti = dm_dax_get_live_target(md, sector, &srcu_idx);
1102
1103 if (!ti)
1104 goto out;
1105 if (!ti->type->dax_copy_to_iter) {
1106 ret = copy_to_iter(addr, bytes, i);
1107 goto out;
1108 }
1109 ret = ti->type->dax_copy_to_iter(ti, pgoff, addr, bytes, i);
1110 out:
1111 dm_put_live_table(md, srcu_idx);
1112
1113 return ret;
1114}
1115
1092/* 1116/*
1093 * A target may call dm_accept_partial_bio only from the map routine. It is 1117 * A target may call dm_accept_partial_bio only from the map routine. It is
1094 * allowed for all bio types except REQ_PREFLUSH and REQ_OP_ZONE_RESET. 1118 * allowed for all bio types except REQ_PREFLUSH and REQ_OP_ZONE_RESET.
@@ -3134,6 +3158,7 @@ static const struct block_device_operations dm_blk_dops = {
3134static const struct dax_operations dm_dax_ops = { 3158static const struct dax_operations dm_dax_ops = {
3135 .direct_access = dm_dax_direct_access, 3159 .direct_access = dm_dax_direct_access,
3136 .copy_from_iter = dm_dax_copy_from_iter, 3160 .copy_from_iter = dm_dax_copy_from_iter,
3161 .copy_to_iter = dm_dax_copy_to_iter,
3137}; 3162};
3138 3163
3139/* 3164/*
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index e023d6aa22b5..1b8ab48365de 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -264,9 +264,16 @@ static size_t pmem_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
264 return copy_from_iter_flushcache(addr, bytes, i); 264 return copy_from_iter_flushcache(addr, bytes, i);
265} 265}
266 266
267static size_t pmem_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
268 void *addr, size_t bytes, struct iov_iter *i)
269{
270 return copy_to_iter(addr, bytes, i);
271}
272
267static const struct dax_operations pmem_dax_ops = { 273static const struct dax_operations pmem_dax_ops = {
268 .direct_access = pmem_dax_direct_access, 274 .direct_access = pmem_dax_direct_access,
269 .copy_from_iter = pmem_copy_from_iter, 275 .copy_from_iter = pmem_copy_from_iter,
276 .copy_to_iter = pmem_copy_to_iter,
270}; 277};
271 278
272static const struct attribute_group *pmem_attribute_groups[] = { 279static const struct attribute_group *pmem_attribute_groups[] = {
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 0a312e450207..29024492b8ed 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -51,9 +51,16 @@ static size_t dcssblk_dax_copy_from_iter(struct dax_device *dax_dev,
51 return copy_from_iter(addr, bytes, i); 51 return copy_from_iter(addr, bytes, i);
52} 52}
53 53
54static size_t dcssblk_dax_copy_to_iter(struct dax_device *dax_dev,
55 pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i)
56{
57 return copy_to_iter(addr, bytes, i);
58}
59
54static const struct dax_operations dcssblk_dax_ops = { 60static const struct dax_operations dcssblk_dax_ops = {
55 .direct_access = dcssblk_dax_direct_access, 61 .direct_access = dcssblk_dax_direct_access,
56 .copy_from_iter = dcssblk_dax_copy_from_iter, 62 .copy_from_iter = dcssblk_dax_copy_from_iter,
63 .copy_to_iter = dcssblk_dax_copy_to_iter,
57}; 64};
58 65
59struct dcssblk_dev_info { 66struct dcssblk_dev_info {
diff --git a/fs/dax.c b/fs/dax.c
index aaec72ded1b6..a64afdf7ec0d 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1057,7 +1057,8 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
1057 map_len = dax_copy_from_iter(dax_dev, pgoff, kaddr, 1057 map_len = dax_copy_from_iter(dax_dev, pgoff, kaddr,
1058 map_len, iter); 1058 map_len, iter);
1059 else 1059 else
1060 map_len = copy_to_iter(kaddr, map_len, iter); 1060 map_len = dax_copy_to_iter(dax_dev, pgoff, kaddr,
1061 map_len, iter);
1061 if (map_len <= 0) { 1062 if (map_len <= 0) {
1062 ret = map_len ? map_len : -EFAULT; 1063 ret = map_len ? map_len : -EFAULT;
1063 break; 1064 break;
diff --git a/include/linux/dax.h b/include/linux/dax.h
index f9eb22ad341e..a43b396fb336 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -20,6 +20,9 @@ struct dax_operations {
20 /* copy_from_iter: required operation for fs-dax direct-i/o */ 20 /* copy_from_iter: required operation for fs-dax direct-i/o */
21 size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t, 21 size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t,
22 struct iov_iter *); 22 struct iov_iter *);
23 /* copy_to_iter: required operation for fs-dax direct-i/o */
24 size_t (*copy_to_iter)(struct dax_device *, pgoff_t, void *, size_t,
25 struct iov_iter *);
23}; 26};
24 27
25extern struct attribute_group dax_attribute_group; 28extern struct attribute_group dax_attribute_group;
@@ -118,6 +121,8 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
118 void **kaddr, pfn_t *pfn); 121 void **kaddr, pfn_t *pfn);
119size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, 122size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
120 size_t bytes, struct iov_iter *i); 123 size_t bytes, struct iov_iter *i);
124size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
125 size_t bytes, struct iov_iter *i);
121void dax_flush(struct dax_device *dax_dev, void *addr, size_t size); 126void dax_flush(struct dax_device *dax_dev, void *addr, size_t size);
122 127
123ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, 128ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 31fef7c34185..6fb0808e87c8 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -133,7 +133,7 @@ typedef int (*dm_busy_fn) (struct dm_target *ti);
133 */ 133 */
134typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff, 134typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff,
135 long nr_pages, void **kaddr, pfn_t *pfn); 135 long nr_pages, void **kaddr, pfn_t *pfn);
136typedef size_t (*dm_dax_copy_from_iter_fn)(struct dm_target *ti, pgoff_t pgoff, 136typedef size_t (*dm_dax_copy_iter_fn)(struct dm_target *ti, pgoff_t pgoff,
137 void *addr, size_t bytes, struct iov_iter *i); 137 void *addr, size_t bytes, struct iov_iter *i);
138#define PAGE_SECTORS (PAGE_SIZE / 512) 138#define PAGE_SECTORS (PAGE_SIZE / 512)
139 139
@@ -184,7 +184,8 @@ struct target_type {
184 dm_iterate_devices_fn iterate_devices; 184 dm_iterate_devices_fn iterate_devices;
185 dm_io_hints_fn io_hints; 185 dm_io_hints_fn io_hints;
186 dm_dax_direct_access_fn direct_access; 186 dm_dax_direct_access_fn direct_access;
187 dm_dax_copy_from_iter_fn dax_copy_from_iter; 187 dm_dax_copy_iter_fn dax_copy_from_iter;
188 dm_dax_copy_iter_fn dax_copy_to_iter;
188 189
189 /* For internal device-mapper use. */ 190 /* For internal device-mapper use. */
190 struct list_head list; 191 struct list_head list;