Skip to content

Commit ae1c908

Browse files
committed
Merge tag 'libnvdimm-fixes-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams: "A handful of small fixes for 4.13-rc2. Three of these fixes are tagged for -stable. They have all appeared in at least one -next release with no reported issues - Fix handling of media errors that span a sector - Fix support of multiple namespaces in a libnvdimm region being in device-dax mode - Clean up the machine check notifier properly when the nfit driver fails to register - Address a static analysis (smatch) report in device-dax" * tag 'libnvdimm-fixes-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: device-dax: fix sysfs duplicate warnings MAINTAINERS: list drivers/acpi/nfit/ files for libnvdimm sub-system acpi/nfit: Fix memory corruption/Unregister mce decoder on failure device-dax: fix 'passing zero to ERR_PTR()' warning libnvdimm: fix badblock range handling of ARS range
2 parents c6efb45 + bbb3be1 commit ae1c908

File tree

6 files changed

+45
-21
lines changed

6 files changed

+45
-21
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7730,6 +7730,7 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
77307730
T: git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
77317731
S: Supported
77327732
F: drivers/nvdimm/*
7733+
F: drivers/acpi/nfit/*
77337734
F: include/linux/nd.h
77347735
F: include/linux/libnvdimm.h
77357736
F: include/uapi/linux/ndctl.h
@@ -7741,7 +7742,6 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
77417742
S: Supported
77427743
F: drivers/nvdimm/blk.c
77437744
F: drivers/nvdimm/region_devs.c
7744-
F: drivers/acpi/nfit*
77457745

77467746
LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
77477747
M: Vishal Verma <[email protected]>

drivers/acpi/nfit/core.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3160,6 +3160,8 @@ static struct acpi_driver acpi_nfit_driver = {
31603160

31613161
static __init int nfit_init(void)
31623162
{
3163+
int ret;
3164+
31633165
BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
31643166
BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
31653167
BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
@@ -3187,8 +3189,14 @@ static __init int nfit_init(void)
31873189
return -ENOMEM;
31883190

31893191
nfit_mce_register();
3192+
ret = acpi_bus_register_driver(&acpi_nfit_driver);
3193+
if (ret) {
3194+
nfit_mce_unregister();
3195+
destroy_workqueue(nfit_wq);
3196+
}
3197+
3198+
return ret;
31903199

3191-
return acpi_bus_register_driver(&acpi_nfit_driver);
31923200
}
31933201

31943202
static __exit void nfit_exit(void)

drivers/dax/device-dax.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(struct device *parent,
2121
int region_id, struct resource *res, unsigned int align,
2222
void *addr, unsigned long flags);
2323
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
24-
struct resource *res, int count);
24+
int id, struct resource *res, int count);
2525
#endif /* __DEVICE_DAX_H__ */

drivers/dax/device.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ static void dev_dax_release(struct device *dev)
529529
struct dax_region *dax_region = dev_dax->region;
530530
struct dax_device *dax_dev = dev_dax->dax_dev;
531531

532-
ida_simple_remove(&dax_region->ida, dev_dax->id);
532+
if (dev_dax->id >= 0)
533+
ida_simple_remove(&dax_region->ida, dev_dax->id);
533534
dax_region_put(dax_region);
534535
put_dax(dax_dev);
535536
kfree(dev_dax);
@@ -559,15 +560,18 @@ static void unregister_dev_dax(void *dev)
559560
}
560561

561562
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
562-
struct resource *res, int count)
563+
int id, struct resource *res, int count)
563564
{
564565
struct device *parent = dax_region->dev;
565566
struct dax_device *dax_dev;
566567
struct dev_dax *dev_dax;
567568
struct inode *inode;
568569
struct device *dev;
569570
struct cdev *cdev;
570-
int rc = 0, i;
571+
int rc, i;
572+
573+
if (!count)
574+
return ERR_PTR(-EINVAL);
571575

572576
dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);
573577
if (!dev_dax)
@@ -587,19 +591,27 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
587591
if (i < count)
588592
goto err_id;
589593

590-
dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
591-
if (dev_dax->id < 0) {
592-
rc = dev_dax->id;
593-
goto err_id;
594+
if (id < 0) {
595+
id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
596+
dev_dax->id = id;
597+
if (id < 0) {
598+
rc = id;
599+
goto err_id;
600+
}
601+
} else {
602+
/* region provider owns @id lifetime */
603+
dev_dax->id = -1;
594604
}
595605

596606
/*
597607
* No 'host' or dax_operations since there is no access to this
598608
* device outside of mmap of the resulting character device.
599609
*/
600610
dax_dev = alloc_dax(dev_dax, NULL, NULL);
601-
if (!dax_dev)
611+
if (!dax_dev) {
612+
rc = -ENOMEM;
602613
goto err_dax;
614+
}
603615

604616
/* from here on we're committed to teardown via dax_dev_release() */
605617
dev = &dev_dax->dev;
@@ -620,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
620632
dev->parent = parent;
621633
dev->groups = dax_attribute_groups;
622634
dev->release = dev_dax_release;
623-
dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
635+
dev_set_name(dev, "dax%d.%d", dax_region->id, id);
624636

625637
rc = cdev_device_add(cdev, dev);
626638
if (rc) {
@@ -636,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
636648
return dev_dax;
637649

638650
err_dax:
639-
ida_simple_remove(&dax_region->ida, dev_dax->id);
651+
if (dev_dax->id >= 0)
652+
ida_simple_remove(&dax_region->ida, dev_dax->id);
640653
err_id:
641654
kfree(dev_dax);
642655

drivers/dax/pmem.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *data)
5858

5959
static int dax_pmem_probe(struct device *dev)
6060
{
61-
int rc;
6261
void *addr;
6362
struct resource res;
63+
int rc, id, region_id;
6464
struct nd_pfn_sb *pfn_sb;
6565
struct dev_dax *dev_dax;
6666
struct dax_pmem *dax_pmem;
67-
struct nd_region *nd_region;
6867
struct nd_namespace_io *nsio;
6968
struct dax_region *dax_region;
7069
struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device *dev)
123122
/* adjust the dax_region resource to the start of data */
124123
res.start += le64_to_cpu(pfn_sb->dataoff);
125124

126-
nd_region = to_nd_region(dev->parent);
127-
dax_region = alloc_dax_region(dev, nd_region->id, &res,
125+
rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
126+
if (rc != 2)
127+
return -EINVAL;
128+
129+
dax_region = alloc_dax_region(dev, region_id, &res,
128130
le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
129131
if (!dax_region)
130132
return -ENOMEM;
131133

132134
/* TODO: support for subdividing a dax region... */
133-
dev_dax = devm_create_dev_dax(dax_region, &res, 1);
135+
dev_dax = devm_create_dev_dax(dax_region, id, &res, 1);
134136

135137
/* child dev_dax instances now own the lifetime of the dax_region */
136138
dax_region_put(dax_region);

drivers/nvdimm/core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,15 @@ static void set_badblock(struct badblocks *bb, sector_t s, int num)
421421
static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len)
422422
{
423423
const unsigned int sector_size = 512;
424-
sector_t start_sector;
424+
sector_t start_sector, end_sector;
425425
u64 num_sectors;
426426
u32 rem;
427427

428428
start_sector = div_u64(ns_offset, sector_size);
429-
num_sectors = div_u64_rem(len, sector_size, &rem);
429+
end_sector = div_u64_rem(ns_offset + len, sector_size, &rem);
430430
if (rem)
431-
num_sectors++;
431+
end_sector++;
432+
num_sectors = end_sector - start_sector;
432433

433434
if (unlikely(num_sectors > (u64)INT_MAX)) {
434435
u64 remaining = num_sectors;

0 commit comments

Comments
 (0)