Skip to content

Commit 828bf6e

Browse files
committed
Merge tag 'libnvdimm-for-4.19_misc' of gitolite.kernel.org:pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dave Jiang: "Collection of misc libnvdimm patches for 4.19 submission: - Adding support to read locked nvdimm capacity. - Change test code to make DSM failure code injection an override. - Add support for calculate maximum contiguous area for namespace. - Add support for queueing a short ARS when there is on going ARS for nvdimm. - Allow NULL to be passed in to ->direct_access() for kaddr and pfn params. - Improve smart injection support for nvdimm emulation testing. - Fix test code that supports for emulating controller temperature. - Fix hang on error before devm_memremap_pages() - Fix a bug that causes user memory corruption when data returned to user for ars_status. - Maintainer updates for Ross Zwisler emails and adding Jan Kara to fsdax" * tag 'libnvdimm-for-4.19_misc' of gitolite.kernel.org:pub/scm/linux/kernel/git/nvdimm/nvdimm: libnvdimm: fix ars_status output length calculation device-dax: avoid hang on error before devm_memremap_pages() tools/testing/nvdimm: improve emulation of smart injection filesystem-dax: Do not request kaddr and pfn when not required md/dm-writecache: Don't request pointer dummy_addr when not required dax/super: Do not request a pointer kaddr when not required tools/testing/nvdimm: kaddr and pfn can be NULL to ->direct_access() s390, dcssblk: kaddr and pfn can be NULL to ->direct_access() libnvdimm, pmem: kaddr and pfn can be NULL to ->direct_access() acpi/nfit: queue issuing of ars when an uc error notification comes in libnvdimm: Export max available extent libnvdimm: Use max contiguous area for namespace size MAINTAINERS: Add Jan Kara for filesystem DAX MAINTAINERS: update Ross Zwisler's email address tools/testing/nvdimm: Fix support for emulating controller temperature tools/testing/nvdimm: Make DSM failure code injection an override acpi, nfit: Prefer _DSM over _LSR for namespace label reads libnvdimm: Introduce locked DIMM capacity support
2 parents b326272 + 286e877 commit 828bf6e

File tree

19 files changed

+270
-90
lines changed

19 files changed

+270
-90
lines changed

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
159159
Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net>
160160
Rémi Denis-Courmont <rdenis@simphalempin.com>
161161
Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
162+
Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
162163
Rudolf Marek <R.Marek@sh.cvut.cz>
163164
Rui Saraiva <rmps@joel.ist.utl.pt>
164165
Sachin P Sant <ssant@in.ibm.com>

MAINTAINERS

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4364,7 +4364,8 @@ F: drivers/i2c/busses/i2c-diolan-u2c.c
43644364

43654365
FILESYSTEM DIRECT ACCESS (DAX)
43664366
M: Matthew Wilcox <mawilcox@microsoft.com>
4367-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
4367+
M: Ross Zwisler <zwisler@kernel.org>
4368+
M: Jan Kara <jack@suse.cz>
43684369
L: linux-fsdevel@vger.kernel.org
43694370
S: Supported
43704371
F: fs/dax.c
@@ -4374,7 +4375,7 @@ F: include/trace/events/fs_dax.h
43744375
DEVICE DIRECT ACCESS (DAX)
43754376
M: Dan Williams <dan.j.williams@intel.com>
43764377
M: Dave Jiang <dave.jiang@intel.com>
4377-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
4378+
M: Ross Zwisler <zwisler@kernel.org>
43784379
M: Vishal Verma <vishal.l.verma@intel.com>
43794380
L: linux-nvdimm@lists.01.org
43804381
S: Supported
@@ -8303,7 +8304,7 @@ S: Maintained
83038304
F: tools/lib/lockdep/
83048305

83058306
LIBNVDIMM BLK: MMIO-APERTURE DRIVER
8306-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
8307+
M: Ross Zwisler <zwisler@kernel.org>
83078308
M: Dan Williams <dan.j.williams@intel.com>
83088309
M: Vishal Verma <vishal.l.verma@intel.com>
83098310
M: Dave Jiang <dave.jiang@intel.com>
@@ -8316,15 +8317,15 @@ F: drivers/nvdimm/region_devs.c
83168317
LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
83178318
M: Vishal Verma <vishal.l.verma@intel.com>
83188319
M: Dan Williams <dan.j.williams@intel.com>
8319-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
8320+
M: Ross Zwisler <zwisler@kernel.org>
83208321
M: Dave Jiang <dave.jiang@intel.com>
83218322
L: linux-nvdimm@lists.01.org
83228323
Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
83238324
S: Supported
83248325
F: drivers/nvdimm/btt*
83258326

83268327
LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER
8327-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
8328+
M: Ross Zwisler <zwisler@kernel.org>
83288329
M: Dan Williams <dan.j.williams@intel.com>
83298330
M: Vishal Verma <vishal.l.verma@intel.com>
83308331
M: Dave Jiang <dave.jiang@intel.com>
@@ -8343,7 +8344,7 @@ F: Documentation/devicetree/bindings/pmem/pmem-region.txt
83438344

83448345
LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
83458346
M: Dan Williams <dan.j.williams@intel.com>
8346-
M: Ross Zwisler <ross.zwisler@linux.intel.com>
8347+
M: Ross Zwisler <zwisler@kernel.org>
83478348
M: Vishal Verma <vishal.l.verma@intel.com>
83488349
M: Dave Jiang <dave.jiang@intel.com>
83498350
L: linux-nvdimm@lists.01.org

drivers/acpi/nfit/core.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
16991699
{
17001700
struct acpi_device *adev, *adev_dimm;
17011701
struct device *dev = acpi_desc->dev;
1702-
unsigned long dsm_mask;
1702+
unsigned long dsm_mask, label_mask;
17031703
const guid_t *guid;
17041704
int i;
17051705
int family = -1;
@@ -1771,6 +1771,16 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
17711771
1ULL << i))
17721772
set_bit(i, &nfit_mem->dsm_mask);
17731773

1774+
/*
1775+
* Prefer the NVDIMM_FAMILY_INTEL label read commands if present
1776+
* due to their better semantics handling locked capacity.
1777+
*/
1778+
label_mask = 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA
1779+
| 1 << ND_CMD_SET_CONFIG_DATA;
1780+
if (family == NVDIMM_FAMILY_INTEL
1781+
&& (dsm_mask & label_mask) == label_mask)
1782+
return 0;
1783+
17741784
if (acpi_nvdimm_has_method(adev_dimm, "_LSI")
17751785
&& acpi_nvdimm_has_method(adev_dimm, "_LSR")) {
17761786
dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev));
@@ -2559,7 +2569,12 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc,
25592569
test_bit(ARS_SHORT, &nfit_spa->ars_state)
25602570
? "short" : "long");
25612571
clear_bit(ARS_SHORT, &nfit_spa->ars_state);
2562-
set_bit(ARS_DONE, &nfit_spa->ars_state);
2572+
if (test_and_clear_bit(ARS_REQ_REDO, &nfit_spa->ars_state)) {
2573+
set_bit(ARS_SHORT, &nfit_spa->ars_state);
2574+
set_bit(ARS_REQ, &nfit_spa->ars_state);
2575+
dev_dbg(dev, "ARS: processing scrub request received while in progress\n");
2576+
} else
2577+
set_bit(ARS_DONE, &nfit_spa->ars_state);
25632578
}
25642579

25652580
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
@@ -3256,9 +3271,10 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
32563271
if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
32573272
continue;
32583273

3259-
if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state))
3274+
if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) {
32603275
busy++;
3261-
else {
3276+
set_bit(ARS_REQ_REDO, &nfit_spa->ars_state);
3277+
} else {
32623278
if (test_bit(ARS_SHORT, &flags))
32633279
set_bit(ARS_SHORT, &nfit_spa->ars_state);
32643280
scheduled++;

drivers/acpi/nfit/nfit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ enum nfit_dimm_notifiers {
119119

120120
enum nfit_ars_state {
121121
ARS_REQ,
122+
ARS_REQ_REDO,
122123
ARS_DONE,
123124
ARS_SHORT,
124125
ARS_FAILED,

drivers/dax/pmem.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,19 @@ static int dax_pmem_probe(struct device *dev)
105105
if (rc)
106106
return rc;
107107

108-
rc = devm_add_action_or_reset(dev, dax_pmem_percpu_exit,
109-
&dax_pmem->ref);
110-
if (rc)
108+
rc = devm_add_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref);
109+
if (rc) {
110+
percpu_ref_exit(&dax_pmem->ref);
111111
return rc;
112+
}
112113

113114
dax_pmem->pgmap.ref = &dax_pmem->ref;
114115
addr = devm_memremap_pages(dev, &dax_pmem->pgmap);
115-
if (IS_ERR(addr))
116+
if (IS_ERR(addr)) {
117+
devm_remove_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref);
118+
percpu_ref_exit(&dax_pmem->ref);
116119
return PTR_ERR(addr);
120+
}
117121

118122
rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill,
119123
&dax_pmem->ref);

drivers/dax/super.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
8989
struct request_queue *q;
9090
pgoff_t pgoff;
9191
int err, id;
92-
void *kaddr;
9392
pfn_t pfn;
9493
long len;
9594
char buf[BDEVNAME_SIZE];
@@ -122,7 +121,7 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
122121
}
123122

124123
id = dax_read_lock();
125-
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
124+
len = dax_direct_access(dax_dev, pgoff, 1, NULL, &pfn);
126125
dax_read_unlock(id);
127126

128127
put_dax(dax_dev);

drivers/md/dm-writecache.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,8 @@ static int persistent_memory_claim(struct dm_writecache *wc)
268268
i = 0;
269269
do {
270270
long daa;
271-
void *dummy_addr;
272271
daa = dax_direct_access(wc->ssd_dev->dax_dev, i, p - i,
273-
&dummy_addr, &pfn);
272+
NULL, &pfn);
274273
if (daa <= 0) {
275274
r = daa ? daa : -EINVAL;
276275
goto err3;

drivers/nvdimm/bus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,9 +812,9 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
812812
* overshoots the remainder by 4 bytes, assume it was
813813
* including 'status'.
814814
*/
815-
if (out_field[1] - 8 == remainder)
815+
if (out_field[1] - 4 == remainder)
816816
return remainder;
817-
return out_field[1] - 4;
817+
return out_field[1] - 8;
818818
} else if (cmd == ND_CMD_CALL) {
819819
struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
820820

drivers/nvdimm/dimm.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ static int nvdimm_probe(struct device *dev)
3434
return rc;
3535
}
3636

37+
/* reset locked, to be validated below... */
38+
nvdimm_clear_locked(dev);
39+
3740
ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
3841
if (!ndd)
3942
return -ENOMEM;
@@ -48,12 +51,30 @@ static int nvdimm_probe(struct device *dev)
4851
get_device(dev);
4952
kref_init(&ndd->kref);
5053

54+
/*
55+
* EACCES failures reading the namespace label-area-properties
56+
* are interpreted as the DIMM capacity being locked but the
57+
* namespace labels themselves being accessible.
58+
*/
5159
rc = nvdimm_init_nsarea(ndd);
52-
if (rc == -EACCES)
60+
if (rc == -EACCES) {
61+
/*
62+
* See nvdimm_namespace_common_probe() where we fail to
63+
* allow namespaces to probe while the DIMM is locked,
64+
* but we do allow for namespace enumeration.
65+
*/
5366
nvdimm_set_locked(dev);
67+
rc = 0;
68+
}
5469
if (rc)
5570
goto err;
5671

72+
/*
73+
* EACCES failures reading the namespace label-data are
74+
* interpreted as the label area being locked in addition to the
75+
* DIMM capacity. We fail the dimm probe to prevent regions from
76+
* attempting to parse the label area.
77+
*/
5778
rc = nvdimm_init_config_data(ndd);
5879
if (rc == -EACCES)
5980
nvdimm_set_locked(dev);
@@ -72,7 +93,6 @@ static int nvdimm_probe(struct device *dev)
7293
if (rc == 0)
7394
nvdimm_set_aliasing(dev);
7495
}
75-
nvdimm_clear_locked(dev);
7696
nvdimm_bus_unlock(dev);
7797

7898
if (rc)

drivers/nvdimm/dimm_devs.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,37 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
536536
return info.available;
537537
}
538538

539+
/**
540+
* nd_pmem_max_contiguous_dpa - For the given dimm+region, return the max
541+
* contiguous unallocated dpa range.
542+
* @nd_region: constrain available space check to this reference region
543+
* @nd_mapping: container of dpa-resource-root + labels
544+
*/
545+
resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
546+
struct nd_mapping *nd_mapping)
547+
{
548+
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
549+
struct nvdimm_bus *nvdimm_bus;
550+
resource_size_t max = 0;
551+
struct resource *res;
552+
553+
/* if a dimm is disabled the available capacity is zero */
554+
if (!ndd)
555+
return 0;
556+
557+
nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
558+
if (__reserve_free_pmem(&nd_region->dev, nd_mapping->nvdimm))
559+
return 0;
560+
for_each_dpa_resource(ndd, res) {
561+
if (strcmp(res->name, "pmem-reserve") != 0)
562+
continue;
563+
if (resource_size(res) > max)
564+
max = resource_size(res);
565+
}
566+
release_free_pmem(nvdimm_bus, nd_mapping);
567+
return max;
568+
}
569+
539570
/**
540571
* nd_pmem_available_dpa - for the given dimm+region account unallocated dpa
541572
* @nd_mapping: container of dpa-resource-root + labels

drivers/nvdimm/namespace_devs.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ static int merge_dpa(struct nd_region *nd_region,
799799
return 0;
800800
}
801801

802-
static int __reserve_free_pmem(struct device *dev, void *data)
802+
int __reserve_free_pmem(struct device *dev, void *data)
803803
{
804804
struct nvdimm *nvdimm = data;
805805
struct nd_region *nd_region;
@@ -836,7 +836,7 @@ static int __reserve_free_pmem(struct device *dev, void *data)
836836
return 0;
837837
}
838838

839-
static void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
839+
void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
840840
struct nd_mapping *nd_mapping)
841841
{
842842
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
@@ -1032,7 +1032,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
10321032

10331033
allocated += nvdimm_allocated_dpa(ndd, &label_id);
10341034
}
1035-
available = nd_region_available_dpa(nd_region);
1035+
available = nd_region_allocatable_dpa(nd_region);
10361036

10371037
if (val > available + allocated)
10381038
return -ENOSPC;
@@ -1144,6 +1144,26 @@ resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns)
11441144
}
11451145
EXPORT_SYMBOL(nvdimm_namespace_capacity);
11461146

1147+
bool nvdimm_namespace_locked(struct nd_namespace_common *ndns)
1148+
{
1149+
int i;
1150+
bool locked = false;
1151+
struct device *dev = &ndns->dev;
1152+
struct nd_region *nd_region = to_nd_region(dev->parent);
1153+
1154+
for (i = 0; i < nd_region->ndr_mappings; i++) {
1155+
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1156+
struct nvdimm *nvdimm = nd_mapping->nvdimm;
1157+
1158+
if (test_bit(NDD_LOCKED, &nvdimm->flags)) {
1159+
dev_dbg(dev, "%s locked\n", nvdimm_name(nvdimm));
1160+
locked = true;
1161+
}
1162+
}
1163+
return locked;
1164+
}
1165+
EXPORT_SYMBOL(nvdimm_namespace_locked);
1166+
11471167
static ssize_t size_show(struct device *dev,
11481168
struct device_attribute *attr, char *buf)
11491169
{
@@ -1695,6 +1715,9 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)
16951715
}
16961716
}
16971717

1718+
if (nvdimm_namespace_locked(ndns))
1719+
return ERR_PTR(-EACCES);
1720+
16981721
size = nvdimm_namespace_capacity(ndns);
16991722
if (size < ND_MIN_NAMESPACE_SIZE) {
17001723
dev_dbg(&ndns->dev, "%pa, too small must be at least %#x\n",

drivers/nvdimm/nd-core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ struct nd_region;
100100
struct nvdimm_drvdata;
101101
struct nd_mapping;
102102
void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
103+
104+
int __reserve_free_pmem(struct device *dev, void *data);
105+
void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
106+
struct nd_mapping *nd_mapping);
107+
108+
resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
109+
struct nd_mapping *nd_mapping);
110+
resource_size_t nd_region_allocatable_dpa(struct nd_region *nd_region);
103111
resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
104112
struct nd_mapping *nd_mapping, resource_size_t *overlap);
105113
resource_size_t nd_blk_available_dpa(struct nd_region *nd_region);

drivers/nvdimm/nd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
357357
struct nd_label_id *label_id, resource_size_t start,
358358
resource_size_t n);
359359
resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
360+
bool nvdimm_namespace_locked(struct nd_namespace_common *ndns);
360361
struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev);
361362
int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);
362363
int nvdimm_namespace_detach_btt(struct nd_btt *nd_btt);

drivers/nvdimm/pmem.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,11 @@ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
226226
if (unlikely(is_bad_pmem(&pmem->bb, PFN_PHYS(pgoff) / 512,
227227
PFN_PHYS(nr_pages))))
228228
return -EIO;
229-
*kaddr = pmem->virt_addr + offset;
230-
*pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
229+
230+
if (kaddr)
231+
*kaddr = pmem->virt_addr + offset;
232+
if (pfn)
233+
*pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
231234

232235
/*
233236
* If badblocks are present, limit known good range to the

0 commit comments

Comments
 (0)