Skip to content

Commit b2ad813

Browse files
committed
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
2 parents a2c48d9 + 52f476a commit b2ad813

File tree

10 files changed

+129
-43
lines changed

10 files changed

+129
-43
lines changed

drivers/dax/super.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,12 @@ struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
7373
EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
7474
#endif
7575

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)
8779
{
88-
struct dax_device *dax_dev;
8980
bool dax_enabled = false;
9081
pgoff_t pgoff, pgoff_end;
91-
struct request_queue *q;
9282
char buf[BDEVNAME_SIZE];
9383
void *kaddr, *end_kaddr;
9484
pfn_t pfn, end_pfn;
@@ -102,42 +92,26 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
10292
return false;
10393
}
10494

105-
q = bdev_get_queue(bdev);
106-
if (!q || !blk_queue_dax(q)) {
107-
pr_debug("%s: error: request queue doesn't support dax\n",
108-
bdevname(bdev, buf));
109-
return false;
110-
}
111-
112-
err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
95+
err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff);
11396
if (err) {
11497
pr_debug("%s: error: unaligned partition for dax\n",
11598
bdevname(bdev, buf));
11699
return false;
117100
}
118101

119-
last_page = PFN_DOWN(i_size_read(bdev->bd_inode) - 1) * 8;
102+
last_page = PFN_DOWN((start + sectors - 1) * 512) * PAGE_SIZE / 512;
120103
err = bdev_dax_pgoff(bdev, last_page, PAGE_SIZE, &pgoff_end);
121104
if (err) {
122105
pr_debug("%s: error: unaligned partition for dax\n",
123106
bdevname(bdev, buf));
124107
return false;
125108
}
126109

127-
dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
128-
if (!dax_dev) {
129-
pr_debug("%s: error: device does not support dax\n",
130-
bdevname(bdev, buf));
131-
return false;
132-
}
133-
134110
id = dax_read_lock();
135111
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
136112
len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn);
137113
dax_read_unlock(id);
138114

139-
put_dax(dax_dev);
140-
141115
if (len < 1 || len2 < 1) {
142116
pr_debug("%s: error: dax access failed (%ld)\n",
143117
bdevname(bdev, buf), len < 1 ? len : len2);
@@ -178,6 +152,49 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
178152
}
179153
return true;
180154
}
155+
EXPORT_SYMBOL_GPL(__generic_fsdax_supported);
156+
157+
/**
158+
* __bdev_dax_supported() - Check if the device supports dax for filesystem
159+
* @bdev: block device to check
160+
* @blocksize: The block size of the device
161+
*
162+
* This is a library function for filesystems to check if the block device
163+
* can be mounted with dax option.
164+
*
165+
* Return: true if supported, false if unsupported
166+
*/
167+
bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
168+
{
169+
struct dax_device *dax_dev;
170+
struct request_queue *q;
171+
char buf[BDEVNAME_SIZE];
172+
bool ret;
173+
int id;
174+
175+
q = bdev_get_queue(bdev);
176+
if (!q || !blk_queue_dax(q)) {
177+
pr_debug("%s: error: request queue doesn't support dax\n",
178+
bdevname(bdev, buf));
179+
return false;
180+
}
181+
182+
dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
183+
if (!dax_dev) {
184+
pr_debug("%s: error: device does not support dax\n",
185+
bdevname(bdev, buf));
186+
return false;
187+
}
188+
189+
id = dax_read_lock();
190+
ret = dax_supported(dax_dev, bdev, blocksize, 0,
191+
i_size_read(bdev->bd_inode) / 512);
192+
dax_read_unlock(id);
193+
194+
put_dax(dax_dev);
195+
196+
return ret;
197+
}
181198
EXPORT_SYMBOL_GPL(__bdev_dax_supported);
182199
#endif
183200

@@ -303,6 +320,15 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
303320
}
304321
EXPORT_SYMBOL_GPL(dax_direct_access);
305322

323+
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
324+
int blocksize, sector_t start, sector_t len)
325+
{
326+
if (!dax_alive(dax_dev))
327+
return false;
328+
329+
return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len);
330+
}
331+
306332
size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
307333
size_t bytes, struct iov_iter *i)
308334
{

drivers/md/dm-table.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -880,13 +880,17 @@ void dm_table_set_type(struct dm_table *t, enum dm_queue_mode type)
880880
}
881881
EXPORT_SYMBOL_GPL(dm_table_set_type);
882882

883+
/* validate the dax capability of the target device span */
883884
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)
885886
{
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);
887891
}
888892

889-
static bool dm_table_supports_dax(struct dm_table *t)
893+
bool dm_table_supports_dax(struct dm_table *t, int blocksize)
890894
{
891895
struct dm_target *ti;
892896
unsigned i;
@@ -899,7 +903,8 @@ static bool dm_table_supports_dax(struct dm_table *t)
899903
return false;
900904

901905
if (!ti->type->iterate_devices ||
902-
!ti->type->iterate_devices(ti, device_supports_dax, NULL))
906+
!ti->type->iterate_devices(ti, device_supports_dax,
907+
&blocksize))
903908
return false;
904909
}
905910

@@ -979,7 +984,7 @@ static int dm_table_determine_type(struct dm_table *t)
979984
verify_bio_based:
980985
/* We must use this table as bio-based */
981986
t->type = DM_TYPE_BIO_BASED;
982-
if (dm_table_supports_dax(t) ||
987+
if (dm_table_supports_dax(t, PAGE_SIZE) ||
983988
(list_empty(devices) && live_md_type == DM_TYPE_DAX_BIO_BASED)) {
984989
t->type = DM_TYPE_DAX_BIO_BASED;
985990
} else {
@@ -1905,7 +1910,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
19051910
}
19061911
blk_queue_write_cache(q, wc, fua);
19071912

1908-
if (dm_table_supports_dax(t))
1913+
if (dm_table_supports_dax(t, PAGE_SIZE))
19091914
blk_queue_flag_set(QUEUE_FLAG_DAX, q);
19101915
else
19111916
blk_queue_flag_clear(QUEUE_FLAG_DAX, q);

drivers/md/dm.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,25 @@ static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
11071107
return ret;
11081108
}
11091109

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+
11101129
static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
11111130
void *addr, size_t bytes, struct iov_iter *i)
11121131
{
@@ -3194,6 +3213,7 @@ static const struct block_device_operations dm_blk_dops = {
31943213

31953214
static const struct dax_operations dm_dax_ops = {
31963215
.direct_access = dm_dax_direct_access,
3216+
.dax_supported = dm_dax_supported,
31973217
.copy_from_iter = dm_dax_copy_from_iter,
31983218
.copy_to_iter = dm_dax_copy_to_iter,
31993219
};

drivers/md/dm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ bool dm_table_bio_based(struct dm_table *t);
7272
bool dm_table_request_based(struct dm_table *t);
7373
void dm_table_free_md_mempools(struct dm_table *t);
7474
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);
7576

7677
void dm_lock_md_type(struct mapped_device *md);
7778
void dm_unlock_md_type(struct mapped_device *md);

drivers/nvdimm/bus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ static struct attribute *nd_device_attributes[] = {
642642
NULL,
643643
};
644644

645-
/**
645+
/*
646646
* nd_device_attribute_group - generic attributes for all devices on an nd bus
647647
*/
648648
struct attribute_group nd_device_attribute_group = {
@@ -671,7 +671,7 @@ static umode_t nd_numa_attr_visible(struct kobject *kobj, struct attribute *a,
671671
return a->mode;
672672
}
673673

674-
/**
674+
/*
675675
* nd_numa_attribute_group - NUMA attributes for all devices on an nd bus
676676
*/
677677
struct attribute_group nd_numa_attribute_group = {

drivers/nvdimm/label.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ static guid_t nvdimm_btt2_guid;
2525
static guid_t nvdimm_pfn_guid;
2626
static guid_t nvdimm_dax_guid;
2727

28+
static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
29+
2830
static u32 best_seq(u32 a, u32 b)
2931
{
3032
a &= NSINDEX_SEQ_MASK;

drivers/nvdimm/label.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ enum {
3838
ND_NSINDEX_INIT = 0x1,
3939
};
4040

41-
static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
42-
4341
/**
4442
* struct nd_namespace_index - label set superblock
4543
* @sig: NAMESPACE_INDEX\0

drivers/nvdimm/pmem.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,27 @@ static long pmem_dax_direct_access(struct dax_device *dax_dev,
281281
return __pmem_direct_access(pmem, pgoff, nr_pages, kaddr, pfn);
282282
}
283283

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+
*/
284290
static size_t pmem_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
285291
void *addr, size_t bytes, struct iov_iter *i)
286292
{
287-
return copy_from_iter_flushcache(addr, bytes, i);
293+
return _copy_from_iter_flushcache(addr, bytes, i);
288294
}
289295

290296
static size_t pmem_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
291297
void *addr, size_t bytes, struct iov_iter *i)
292298
{
293-
return copy_to_iter_mcsafe(addr, bytes, i);
299+
return _copy_to_iter_mcsafe(addr, bytes, i);
294300
}
295301

296302
static const struct dax_operations pmem_dax_ops = {
297303
.direct_access = pmem_dax_direct_access,
304+
.dax_supported = generic_fsdax_supported,
298305
.copy_from_iter = pmem_copy_from_iter,
299306
.copy_to_iter = pmem_copy_to_iter,
300307
};

drivers/s390/block/dcssblk.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static size_t dcssblk_dax_copy_to_iter(struct dax_device *dax_dev,
5959

6060
static const struct dax_operations dcssblk_dax_ops = {
6161
.direct_access = dcssblk_dax_direct_access,
62+
.dax_supported = generic_fsdax_supported,
6263
.copy_from_iter = dcssblk_dax_copy_from_iter,
6364
.copy_to_iter = dcssblk_dax_copy_to_iter,
6465
};

include/linux/dax.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ struct dax_operations {
1919
*/
2020
long (*direct_access)(struct dax_device *, pgoff_t, long,
2121
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);
2228
/* copy_from_iter: required operation for fs-dax direct-i/o */
2329
size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t,
2430
struct iov_iter *);
@@ -75,6 +81,17 @@ static inline bool bdev_dax_supported(struct block_device *bdev, int blocksize)
7581
return __bdev_dax_supported(bdev, blocksize);
7682
}
7783

84+
bool __generic_fsdax_supported(struct dax_device *dax_dev,
85+
struct block_device *bdev, int blocksize, sector_t start,
86+
sector_t sectors);
87+
static inline bool generic_fsdax_supported(struct dax_device *dax_dev,
88+
struct block_device *bdev, int blocksize, sector_t start,
89+
sector_t sectors)
90+
{
91+
return __generic_fsdax_supported(dax_dev, bdev, blocksize, start,
92+
sectors);
93+
}
94+
7895
static inline struct dax_device *fs_dax_get_by_host(const char *host)
7996
{
8097
return dax_get_by_host(host);
@@ -99,6 +116,13 @@ static inline bool bdev_dax_supported(struct block_device *bdev,
99116
return false;
100117
}
101118

119+
static inline bool generic_fsdax_supported(struct dax_device *dax_dev,
120+
struct block_device *bdev, int blocksize, sector_t start,
121+
sector_t sectors)
122+
{
123+
return false;
124+
}
125+
102126
static inline struct dax_device *fs_dax_get_by_host(const char *host)
103127
{
104128
return NULL;
@@ -142,6 +166,8 @@ bool dax_alive(struct dax_device *dax_dev);
142166
void *dax_get_private(struct dax_device *dax_dev);
143167
long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
144168
void **kaddr, pfn_t *pfn);
169+
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
170+
int blocksize, sector_t start, sector_t len);
145171
size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
146172
size_t bytes, struct iov_iter *i);
147173
size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,

0 commit comments

Comments
 (0)