Skip to content

Commit 7ac5360

Browse files
Christoph Hellwigdjbw
authored andcommitted
dax: remove the copy_from_iter and copy_to_iter methods
These methods indirect the actual DAX read/write path. In the end pmem uses magic flush and mc safe variants and fuse and dcssblk use plain ones while device mapper picks redirects to the underlying device. Add set_dax_nocache() and set_dax_nomc() APIs to control which copy routines are used to remove indirect call from the read/write fast path as well as a lot of boilerplate code. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Vivek Goyal <[email protected]> [virtiofs] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent 30c6828 commit 7ac5360

File tree

12 files changed

+41
-237
lines changed

12 files changed

+41
-237
lines changed

drivers/dax/bus.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,8 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
13301330
goto err_alloc_dax;
13311331
}
13321332
set_dax_synchronous(dax_dev);
1333+
set_dax_nocache(dax_dev);
1334+
set_dax_nomc(dax_dev);
13331335

13341336
/* a device_dax instance is dead while the driver is not attached */
13351337
kill_dax(dax_dev);

drivers/dax/super.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ enum dax_device_flags {
105105
DAXDEV_WRITE_CACHE,
106106
/* flag to check if device supports synchronous flush */
107107
DAXDEV_SYNC,
108+
/* do not leave the caches dirty after writes */
109+
DAXDEV_NOCACHE,
110+
/* handle CPU fetch exceptions during reads */
111+
DAXDEV_NOMC,
108112
};
109113

110114
/**
@@ -146,19 +150,31 @@ size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
146150
if (!dax_alive(dax_dev))
147151
return 0;
148152

149-
return dax_dev->ops->copy_from_iter(dax_dev, pgoff, addr, bytes, i);
153+
/*
154+
* The userspace address for the memory copy has already been validated
155+
* via access_ok() in vfs_write, so use the 'no check' version to bypass
156+
* the HARDENED_USERCOPY overhead.
157+
*/
158+
if (test_bit(DAXDEV_NOCACHE, &dax_dev->flags))
159+
return _copy_from_iter_flushcache(addr, bytes, i);
160+
return _copy_from_iter(addr, bytes, i);
150161
}
151-
EXPORT_SYMBOL_GPL(dax_copy_from_iter);
152162

153163
size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
154164
size_t bytes, struct iov_iter *i)
155165
{
156166
if (!dax_alive(dax_dev))
157167
return 0;
158168

159-
return dax_dev->ops->copy_to_iter(dax_dev, pgoff, addr, bytes, i);
169+
/*
170+
* The userspace address for the memory copy has already been validated
171+
* via access_ok() in vfs_red, so use the 'no check' version to bypass
172+
* the HARDENED_USERCOPY overhead.
173+
*/
174+
if (test_bit(DAXDEV_NOMC, &dax_dev->flags))
175+
return _copy_mc_to_iter(addr, bytes, i);
176+
return _copy_to_iter(addr, bytes, i);
160177
}
161-
EXPORT_SYMBOL_GPL(dax_copy_to_iter);
162178

163179
int dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
164180
size_t nr_pages)
@@ -220,6 +236,18 @@ void set_dax_synchronous(struct dax_device *dax_dev)
220236
}
221237
EXPORT_SYMBOL_GPL(set_dax_synchronous);
222238

239+
void set_dax_nocache(struct dax_device *dax_dev)
240+
{
241+
set_bit(DAXDEV_NOCACHE, &dax_dev->flags);
242+
}
243+
EXPORT_SYMBOL_GPL(set_dax_nocache);
244+
245+
void set_dax_nomc(struct dax_device *dax_dev)
246+
{
247+
set_bit(DAXDEV_NOMC, &dax_dev->flags);
248+
}
249+
EXPORT_SYMBOL_GPL(set_dax_nomc);
250+
223251
bool dax_alive(struct dax_device *dax_dev)
224252
{
225253
lockdep_assert_held(&dax_srcu);

drivers/md/dm-linear.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -180,22 +180,6 @@ static long linear_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
180180
return dax_direct_access(dax_dev, pgoff, nr_pages, kaddr, pfn);
181181
}
182182

183-
static size_t linear_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff,
184-
void *addr, size_t bytes, struct iov_iter *i)
185-
{
186-
struct dax_device *dax_dev = linear_dax_pgoff(ti, &pgoff);
187-
188-
return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
189-
}
190-
191-
static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
192-
void *addr, size_t bytes, struct iov_iter *i)
193-
{
194-
struct dax_device *dax_dev = linear_dax_pgoff(ti, &pgoff);
195-
196-
return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
197-
}
198-
199183
static int linear_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
200184
size_t nr_pages)
201185
{
@@ -206,8 +190,6 @@ static int linear_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
206190

207191
#else
208192
#define linear_dax_direct_access NULL
209-
#define linear_dax_copy_from_iter NULL
210-
#define linear_dax_copy_to_iter NULL
211193
#define linear_dax_zero_page_range NULL
212194
#endif
213195

@@ -225,8 +207,6 @@ static struct target_type linear_target = {
225207
.prepare_ioctl = linear_prepare_ioctl,
226208
.iterate_devices = linear_iterate_devices,
227209
.direct_access = linear_dax_direct_access,
228-
.dax_copy_from_iter = linear_dax_copy_from_iter,
229-
.dax_copy_to_iter = linear_dax_copy_to_iter,
230210
.dax_zero_page_range = linear_dax_zero_page_range,
231211
};
232212

drivers/md/dm-log-writes.c

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -902,51 +902,6 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit
902902
}
903903

904904
#if IS_ENABLED(CONFIG_FS_DAX)
905-
static int log_dax(struct log_writes_c *lc, sector_t sector, size_t bytes,
906-
struct iov_iter *i)
907-
{
908-
struct pending_block *block;
909-
910-
if (!bytes)
911-
return 0;
912-
913-
block = kzalloc(sizeof(struct pending_block), GFP_KERNEL);
914-
if (!block) {
915-
DMERR("Error allocating dax pending block");
916-
return -ENOMEM;
917-
}
918-
919-
block->data = kzalloc(bytes, GFP_KERNEL);
920-
if (!block->data) {
921-
DMERR("Error allocating dax data space");
922-
kfree(block);
923-
return -ENOMEM;
924-
}
925-
926-
/* write data provided via the iterator */
927-
if (!copy_from_iter(block->data, bytes, i)) {
928-
DMERR("Error copying dax data");
929-
kfree(block->data);
930-
kfree(block);
931-
return -EIO;
932-
}
933-
934-
/* rewind the iterator so that the block driver can use it */
935-
iov_iter_revert(i, bytes);
936-
937-
block->datalen = bytes;
938-
block->sector = bio_to_dev_sectors(lc, sector);
939-
block->nr_sectors = ALIGN(bytes, lc->sectorsize) >> lc->sectorshift;
940-
941-
atomic_inc(&lc->pending_blocks);
942-
spin_lock_irq(&lc->blocks_lock);
943-
list_add_tail(&block->list, &lc->unflushed_blocks);
944-
spin_unlock_irq(&lc->blocks_lock);
945-
wake_up_process(lc->log_kthread);
946-
947-
return 0;
948-
}
949-
950905
static struct dax_device *log_writes_dax_pgoff(struct dm_target *ti,
951906
pgoff_t *pgoff)
952907
{
@@ -964,37 +919,6 @@ static long log_writes_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
964919
return dax_direct_access(dax_dev, pgoff, nr_pages, kaddr, pfn);
965920
}
966921

967-
static size_t log_writes_dax_copy_from_iter(struct dm_target *ti,
968-
pgoff_t pgoff, void *addr, size_t bytes,
969-
struct iov_iter *i)
970-
{
971-
struct log_writes_c *lc = ti->private;
972-
sector_t sector = pgoff * PAGE_SECTORS;
973-
struct dax_device *dax_dev = log_writes_dax_pgoff(ti, &pgoff);
974-
int err;
975-
976-
/* Don't bother doing anything if logging has been disabled */
977-
if (!lc->logging_enabled)
978-
goto dax_copy;
979-
980-
err = log_dax(lc, sector, bytes, i);
981-
if (err) {
982-
DMWARN("Error %d logging DAX write", err);
983-
return 0;
984-
}
985-
dax_copy:
986-
return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
987-
}
988-
989-
static size_t log_writes_dax_copy_to_iter(struct dm_target *ti,
990-
pgoff_t pgoff, void *addr, size_t bytes,
991-
struct iov_iter *i)
992-
{
993-
struct dax_device *dax_dev = log_writes_dax_pgoff(ti, &pgoff);
994-
995-
return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
996-
}
997-
998922
static int log_writes_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
999923
size_t nr_pages)
1000924
{
@@ -1005,8 +929,6 @@ static int log_writes_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
1005929

1006930
#else
1007931
#define log_writes_dax_direct_access NULL
1008-
#define log_writes_dax_copy_from_iter NULL
1009-
#define log_writes_dax_copy_to_iter NULL
1010932
#define log_writes_dax_zero_page_range NULL
1011933
#endif
1012934

@@ -1024,8 +946,6 @@ static struct target_type log_writes_target = {
1024946
.iterate_devices = log_writes_iterate_devices,
1025947
.io_hints = log_writes_io_hints,
1026948
.direct_access = log_writes_dax_direct_access,
1027-
.dax_copy_from_iter = log_writes_dax_copy_from_iter,
1028-
.dax_copy_to_iter = log_writes_dax_copy_to_iter,
1029949
.dax_zero_page_range = log_writes_dax_zero_page_range,
1030950
};
1031951

drivers/md/dm-stripe.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -324,22 +324,6 @@ static long stripe_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
324324
return dax_direct_access(dax_dev, pgoff, nr_pages, kaddr, pfn);
325325
}
326326

327-
static size_t stripe_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff,
328-
void *addr, size_t bytes, struct iov_iter *i)
329-
{
330-
struct dax_device *dax_dev = stripe_dax_pgoff(ti, &pgoff);
331-
332-
return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
333-
}
334-
335-
static size_t stripe_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
336-
void *addr, size_t bytes, struct iov_iter *i)
337-
{
338-
struct dax_device *dax_dev = stripe_dax_pgoff(ti, &pgoff);
339-
340-
return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
341-
}
342-
343327
static int stripe_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
344328
size_t nr_pages)
345329
{
@@ -350,8 +334,6 @@ static int stripe_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
350334

351335
#else
352336
#define stripe_dax_direct_access NULL
353-
#define stripe_dax_copy_from_iter NULL
354-
#define stripe_dax_copy_to_iter NULL
355337
#define stripe_dax_zero_page_range NULL
356338
#endif
357339

@@ -488,8 +470,6 @@ static struct target_type stripe_target = {
488470
.iterate_devices = stripe_iterate_devices,
489471
.io_hints = stripe_io_hints,
490472
.direct_access = stripe_dax_direct_access,
491-
.dax_copy_from_iter = stripe_dax_copy_from_iter,
492-
.dax_copy_to_iter = stripe_dax_copy_to_iter,
493473
.dax_zero_page_range = stripe_dax_zero_page_range,
494474
};
495475

drivers/md/dm.c

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,54 +1027,6 @@ static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
10271027
return ret;
10281028
}
10291029

1030-
static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
1031-
void *addr, size_t bytes, struct iov_iter *i)
1032-
{
1033-
struct mapped_device *md = dax_get_private(dax_dev);
1034-
sector_t sector = pgoff * PAGE_SECTORS;
1035-
struct dm_target *ti;
1036-
long ret = 0;
1037-
int srcu_idx;
1038-
1039-
ti = dm_dax_get_live_target(md, sector, &srcu_idx);
1040-
1041-
if (!ti)
1042-
goto out;
1043-
if (!ti->type->dax_copy_from_iter) {
1044-
ret = copy_from_iter(addr, bytes, i);
1045-
goto out;
1046-
}
1047-
ret = ti->type->dax_copy_from_iter(ti, pgoff, addr, bytes, i);
1048-
out:
1049-
dm_put_live_table(md, srcu_idx);
1050-
1051-
return ret;
1052-
}
1053-
1054-
static size_t dm_dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
1055-
void *addr, size_t bytes, struct iov_iter *i)
1056-
{
1057-
struct mapped_device *md = dax_get_private(dax_dev);
1058-
sector_t sector = pgoff * PAGE_SECTORS;
1059-
struct dm_target *ti;
1060-
long ret = 0;
1061-
int srcu_idx;
1062-
1063-
ti = dm_dax_get_live_target(md, sector, &srcu_idx);
1064-
1065-
if (!ti)
1066-
goto out;
1067-
if (!ti->type->dax_copy_to_iter) {
1068-
ret = copy_to_iter(addr, bytes, i);
1069-
goto out;
1070-
}
1071-
ret = ti->type->dax_copy_to_iter(ti, pgoff, addr, bytes, i);
1072-
out:
1073-
dm_put_live_table(md, srcu_idx);
1074-
1075-
return ret;
1076-
}
1077-
10781030
static int dm_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
10791031
size_t nr_pages)
10801032
{
@@ -1770,6 +1722,8 @@ static struct mapped_device *alloc_dev(int minor)
17701722
md->dax_dev = NULL;
17711723
goto bad;
17721724
}
1725+
set_dax_nocache(md->dax_dev);
1726+
set_dax_nomc(md->dax_dev);
17731727
if (dax_add_host(md->dax_dev, md->disk))
17741728
goto bad;
17751729
}
@@ -3024,8 +2978,6 @@ static const struct block_device_operations dm_rq_blk_dops = {
30242978

30252979
static const struct dax_operations dm_dax_ops = {
30262980
.direct_access = dm_dax_direct_access,
3027-
.copy_from_iter = dm_dax_copy_from_iter,
3028-
.copy_to_iter = dm_dax_copy_to_iter,
30292981
.zero_page_range = dm_dax_zero_page_range,
30302982
};
30312983

drivers/nvdimm/pmem.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -301,26 +301,8 @@ static long pmem_dax_direct_access(struct dax_device *dax_dev,
301301
return __pmem_direct_access(pmem, pgoff, nr_pages, kaddr, pfn);
302302
}
303303

304-
/*
305-
* Bounds checking, both file offset and device offset, is handled by
306-
* dax_iomap_actor()
307-
*/
308-
static size_t pmem_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
309-
void *addr, size_t bytes, struct iov_iter *i)
310-
{
311-
return _copy_from_iter_flushcache(addr, bytes, i);
312-
}
313-
314-
static size_t pmem_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
315-
void *addr, size_t bytes, struct iov_iter *i)
316-
{
317-
return _copy_mc_to_iter(addr, bytes, i);
318-
}
319-
320304
static const struct dax_operations pmem_dax_ops = {
321305
.direct_access = pmem_dax_direct_access,
322-
.copy_from_iter = pmem_copy_from_iter,
323-
.copy_to_iter = pmem_copy_to_iter,
324306
.zero_page_range = pmem_dax_zero_page_range,
325307
};
326308

@@ -497,6 +479,8 @@ static int pmem_attach_disk(struct device *dev,
497479
rc = PTR_ERR(dax_dev);
498480
goto out;
499481
}
482+
set_dax_nocache(dax_dev);
483+
set_dax_nomc(dax_dev);
500484
if (is_nvdimm_sync(nd_region))
501485
set_dax_synchronous(dax_dev);
502486
rc = dax_add_host(dax_dev, disk);

0 commit comments

Comments
 (0)