mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
libnvdimm for 5.11
- Fix a long standing block-window-namespace issue surfaced by the ndctl change to attempt to preserve the kernel device name over a 'reconfigure' - Fix a few error path memory leaks in nfit and device-dax - Silence a smatch warning in the ioctl path - Miscellaneous cleanups -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEf41QbsdZzFdA8EfZHtKRamZ9iAIFAl/k4lUACgkQHtKRamZ9 iALR+RAAnc/9/tGP0PQZ+24l0CyzlJhWlN9xniuWxqFL14yVE9432IJHSJ9GFm6Z 0uDQrAEZMAqScTBdQGNxMrWDyHEkGu466X6S+WbzeBdEsVC1X1nCYJUhhG16S4Q3 imn596EJyf3SSIZKrl/+YA7gSY+6DenRXzGkNVpqODDa/LSGz1cf35nITEkAn9Rb JJ2lMkf8VhaiNklvtVaqCwj8vhSSs8dY8GUFz+zV0zyAt+jjCGxeFD9p2D6OmHs0 4gZ2LymXxMaI8Abu8fVUbfFNi3HxD5EybNpbOvhiH5OWRhfg4YhgxOGVawkDPjv2 wFrQDdEImhjoh/9E53SR0nLh1rp1Hd8+IGC4rZXfZkYlagNMmuuJmTJcRaMILXYW kcZX+C62Cv/7NOQXr7C0AwMq+S2U+ZVmOhV3t3OoKfSogaNPtp7ttvA5KcSvjMq5 NtNy9LV7Wir/7bsJOhnRRDzqrpbE34w/Zcb1LdODzvfuCyOO8qik56RxXtoiG/W8 cA80uH2Sn0mJoAWmZ0zrEJhNdqST1gg/xGBB1wD6pGcpkAUszntRF0cb+2CvhCj3 V5XZ1rzr/n6NIxEOdFmZ+R+y8a0UYS7I6AAZ8ufltIVJY0ltq0M3g8SCljsJrAwe YK1TNEf+dS/Ua2qJiWvIZjOHPs0fGMXF7/LeiVxmDsmIs7/rkqM= =/fha -----END PGP SIGNATURE----- Merge tag 'libnvdimm-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm Pull libnvdimm updates from Dan Williams: "Twas the day before Christmas and the only thing stirring in libnvdimm / device-dax land is a pile of miscellaneous fixups and cleanups. The bulk of it has appeared in -next save the last two patches to device-dax that have passed my build and unit tests. - Fix a long standing block-window-namespace issue surfaced by the ndctl change to attempt to preserve the kernel device name over a 'reconfigure' - Fix a few error path memory leaks in nfit and device-dax - Silence a smatch warning in the ioctl path - Miscellaneous cleanups" * tag 'libnvdimm-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: device-dax: Avoid an unnecessary check in alloc_dev_dax_range() device-dax: Fix range release device-dax: delete a redundancy check in dev_dax_validate_align() libnvdimm/label: Return -ENXIO for no slot in __blk_label_update device-dax/core: Fix memory leak when rmmod dax.ko device-dax/pmem: Convert comma to semicolon libnvdimm: Cleanup include of badblocks.h ACPI: NFIT: Fix input validation of bus-family libnvdimm/namespace: Fix reaping of invalidated block-window-namespace labels ACPI/nfit: avoid accessing uninitialized memory in acpi_nfit_ctl()
This commit is contained in:
commit
1f13d2f7d8
|
@ -5,6 +5,7 @@
|
||||||
#include <linux/list_sort.h>
|
#include <linux/list_sort.h>
|
||||||
#include <linux/libnvdimm.h>
|
#include <linux/libnvdimm.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/ndctl.h>
|
#include <linux/ndctl.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
|
@ -282,18 +283,19 @@ static union acpi_object *pkg_to_buf(union acpi_object *pkg)
|
||||||
|
|
||||||
static union acpi_object *int_to_buf(union acpi_object *integer)
|
static union acpi_object *int_to_buf(union acpi_object *integer)
|
||||||
{
|
{
|
||||||
union acpi_object *buf = ACPI_ALLOCATE(sizeof(*buf) + 4);
|
union acpi_object *buf = NULL;
|
||||||
void *dst = NULL;
|
void *dst = NULL;
|
||||||
|
|
||||||
if (!buf)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (integer->type != ACPI_TYPE_INTEGER) {
|
if (integer->type != ACPI_TYPE_INTEGER) {
|
||||||
WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n",
|
WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n",
|
||||||
integer->type);
|
integer->type);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = ACPI_ALLOCATE(sizeof(*buf) + 4);
|
||||||
|
if (!buf)
|
||||||
|
goto err;
|
||||||
|
|
||||||
dst = buf + 1;
|
dst = buf + 1;
|
||||||
buf->type = ACPI_TYPE_BUFFER;
|
buf->type = ACPI_TYPE_BUFFER;
|
||||||
buf->buffer.length = 4;
|
buf->buffer.length = 4;
|
||||||
|
@ -478,8 +480,11 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
|
||||||
cmd_mask = nd_desc->cmd_mask;
|
cmd_mask = nd_desc->cmd_mask;
|
||||||
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
|
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
|
||||||
family = call_pkg->nd_family;
|
family = call_pkg->nd_family;
|
||||||
if (!test_bit(family, &nd_desc->bus_family_mask))
|
if (family > NVDIMM_BUS_FAMILY_MAX ||
|
||||||
|
!test_bit(family, &nd_desc->bus_family_mask))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
family = array_index_nospec(family,
|
||||||
|
NVDIMM_BUS_FAMILY_MAX + 1);
|
||||||
dsm_mask = acpi_desc->family_dsm_mask[family];
|
dsm_mask = acpi_desc->family_dsm_mask[family];
|
||||||
guid = to_nfit_bus_uuid(family);
|
guid = to_nfit_bus_uuid(family);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -367,19 +367,28 @@ void kill_dev_dax(struct dev_dax *dev_dax)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(kill_dev_dax);
|
EXPORT_SYMBOL_GPL(kill_dev_dax);
|
||||||
|
|
||||||
static void free_dev_dax_ranges(struct dev_dax *dev_dax)
|
static void trim_dev_dax_range(struct dev_dax *dev_dax)
|
||||||
{
|
{
|
||||||
|
int i = dev_dax->nr_range - 1;
|
||||||
|
struct range *range = &dev_dax->ranges[i].range;
|
||||||
struct dax_region *dax_region = dev_dax->region;
|
struct dax_region *dax_region = dev_dax->region;
|
||||||
int i;
|
|
||||||
|
|
||||||
device_lock_assert(dax_region->dev);
|
device_lock_assert(dax_region->dev);
|
||||||
for (i = 0; i < dev_dax->nr_range; i++) {
|
dev_dbg(&dev_dax->dev, "delete range[%d]: %#llx:%#llx\n", i,
|
||||||
struct range *range = &dev_dax->ranges[i].range;
|
(unsigned long long)range->start,
|
||||||
|
(unsigned long long)range->end);
|
||||||
|
|
||||||
__release_region(&dax_region->res, range->start,
|
__release_region(&dax_region->res, range->start, range_len(range));
|
||||||
range_len(range));
|
if (--dev_dax->nr_range == 0) {
|
||||||
|
kfree(dev_dax->ranges);
|
||||||
|
dev_dax->ranges = NULL;
|
||||||
}
|
}
|
||||||
dev_dax->nr_range = 0;
|
}
|
||||||
|
|
||||||
|
static void free_dev_dax_ranges(struct dev_dax *dev_dax)
|
||||||
|
{
|
||||||
|
while (dev_dax->nr_range)
|
||||||
|
trim_dev_dax_range(dev_dax);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_dev_dax(void *dev)
|
static void unregister_dev_dax(void *dev)
|
||||||
|
@ -763,22 +772,14 @@ static int alloc_dev_dax_range(struct dev_dax *dev_dax, u64 start,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ranges = krealloc(dev_dax->ranges, sizeof(*ranges)
|
alloc = __request_region(res, start, size, dev_name(dev), 0);
|
||||||
* (dev_dax->nr_range + 1), GFP_KERNEL);
|
if (!alloc)
|
||||||
if (!ranges)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
alloc = __request_region(res, start, size, dev_name(dev), 0);
|
ranges = krealloc(dev_dax->ranges, sizeof(*ranges)
|
||||||
if (!alloc) {
|
* (dev_dax->nr_range + 1), GFP_KERNEL);
|
||||||
/*
|
if (!ranges) {
|
||||||
* If this was an empty set of ranges nothing else
|
__release_region(res, alloc->start, resource_size(alloc));
|
||||||
* will release @ranges, so do it now.
|
|
||||||
*/
|
|
||||||
if (!dev_dax->nr_range) {
|
|
||||||
kfree(ranges);
|
|
||||||
ranges = NULL;
|
|
||||||
}
|
|
||||||
dev_dax->ranges = ranges;
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,15 +805,10 @@ static int alloc_dev_dax_range(struct dev_dax *dev_dax, u64 start,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = devm_register_dax_mapping(dev_dax, dev_dax->nr_range - 1);
|
rc = devm_register_dax_mapping(dev_dax, dev_dax->nr_range - 1);
|
||||||
if (rc) {
|
if (rc)
|
||||||
dev_dbg(dev, "delete range[%d]: %pa:%pa\n", dev_dax->nr_range - 1,
|
trim_dev_dax_range(dev_dax);
|
||||||
&alloc->start, &alloc->end);
|
|
||||||
dev_dax->nr_range--;
|
|
||||||
__release_region(res, alloc->start, resource_size(alloc));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adjust_dev_dax_range(struct dev_dax *dev_dax, struct resource *res, resource_size_t size)
|
static int adjust_dev_dax_range(struct dev_dax *dev_dax, struct resource *res, resource_size_t size)
|
||||||
|
@ -885,12 +881,7 @@ static int dev_dax_shrink(struct dev_dax *dev_dax, resource_size_t size)
|
||||||
if (shrink >= range_len(range)) {
|
if (shrink >= range_len(range)) {
|
||||||
devm_release_action(dax_region->dev,
|
devm_release_action(dax_region->dev,
|
||||||
unregister_dax_mapping, &mapping->dev);
|
unregister_dax_mapping, &mapping->dev);
|
||||||
__release_region(&dax_region->res, range->start,
|
trim_dev_dax_range(dev_dax);
|
||||||
range_len(range));
|
|
||||||
dev_dax->nr_range--;
|
|
||||||
dev_dbg(dev, "delete range[%d]: %#llx:%#llx\n", i,
|
|
||||||
(unsigned long long) range->start,
|
|
||||||
(unsigned long long) range->end);
|
|
||||||
to_shrink -= shrink;
|
to_shrink -= shrink;
|
||||||
if (!to_shrink)
|
if (!to_shrink)
|
||||||
break;
|
break;
|
||||||
|
@ -1114,16 +1105,9 @@ static ssize_t align_show(struct device *dev,
|
||||||
|
|
||||||
static ssize_t dev_dax_validate_align(struct dev_dax *dev_dax)
|
static ssize_t dev_dax_validate_align(struct dev_dax *dev_dax)
|
||||||
{
|
{
|
||||||
resource_size_t dev_size = dev_dax_size(dev_dax);
|
|
||||||
struct device *dev = &dev_dax->dev;
|
struct device *dev = &dev_dax->dev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (dev_size > 0 && !alloc_is_aligned(dev_dax, dev_size)) {
|
|
||||||
dev_dbg(dev, "%s: align %u invalid for size %pa\n",
|
|
||||||
__func__, dev_dax->align, &dev_size);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < dev_dax->nr_range; i++) {
|
for (i = 0; i < dev_dax->nr_range; i++) {
|
||||||
size_t len = range_len(&dev_dax->ranges[i].range);
|
size_t len = range_len(&dev_dax->ranges[i].range);
|
||||||
|
|
||||||
|
@ -1274,7 +1258,6 @@ static void dev_dax_release(struct device *dev)
|
||||||
put_dax(dax_dev);
|
put_dax(dax_dev);
|
||||||
free_dev_dax_id(dev_dax);
|
free_dev_dax_id(dev_dax);
|
||||||
dax_region_put(dax_region);
|
dax_region_put(dax_region);
|
||||||
kfree(dev_dax->ranges);
|
|
||||||
kfree(dev_dax->pgmap);
|
kfree(dev_dax->pgmap);
|
||||||
kfree(dev_dax);
|
kfree(dev_dax);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys)
|
||||||
|
|
||||||
/* adjust the dax_region range to the start of data */
|
/* adjust the dax_region range to the start of data */
|
||||||
range = pgmap.range;
|
range = pgmap.range;
|
||||||
range.start += offset,
|
range.start += offset;
|
||||||
dax_region = alloc_dax_region(dev, region_id, &range,
|
dax_region = alloc_dax_region(dev, region_id, &range,
|
||||||
nd_region->target_node, le32_to_cpu(pfn_sb->align),
|
nd_region->target_node, le32_to_cpu(pfn_sb->align),
|
||||||
IORESOURCE_DAX_STATIC);
|
IORESOURCE_DAX_STATIC);
|
||||||
|
|
|
@ -752,6 +752,7 @@ static int __init dax_core_init(void)
|
||||||
|
|
||||||
static void __exit dax_core_exit(void)
|
static void __exit dax_core_exit(void)
|
||||||
{
|
{
|
||||||
|
dax_bus_exit();
|
||||||
unregister_chrdev_region(dax_devt, MINORMASK+1);
|
unregister_chrdev_region(dax_devt, MINORMASK+1);
|
||||||
ida_destroy(&dax_minor_ida);
|
ida_destroy(&dax_minor_ida);
|
||||||
dax_fs_exit();
|
dax_fs_exit();
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#ifndef _LINUX_BTT_H
|
#ifndef _LINUX_BTT_H
|
||||||
#define _LINUX_BTT_H
|
#define _LINUX_BTT_H
|
||||||
|
|
||||||
#include <linux/badblocks.h>
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define BTT_SIG_LEN 16
|
#define BTT_SIG_LEN 16
|
||||||
|
@ -197,6 +196,8 @@ struct arena_info {
|
||||||
int log_index[2];
|
int log_index[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct badblocks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct btt - handle for a BTT instance
|
* struct btt - handle for a BTT instance
|
||||||
* @btt_disk: Pointer to the gendisk for BTT device
|
* @btt_disk: Pointer to the gendisk for BTT device
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
#include <linux/badblocks.h>
|
||||||
#include "nd-core.h"
|
#include "nd-core.h"
|
||||||
#include "pmem.h"
|
#include "pmem.h"
|
||||||
#include "pfn.h"
|
#include "pfn.h"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#include <linux/libnvdimm.h>
|
#include <linux/libnvdimm.h>
|
||||||
#include <linux/badblocks.h>
|
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
|
@ -980,6 +980,15 @@ static int __blk_label_update(struct nd_region *nd_region,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* release slots associated with any invalidated UUIDs */
|
||||||
|
mutex_lock(&nd_mapping->lock);
|
||||||
|
list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list)
|
||||||
|
if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)) {
|
||||||
|
reap_victim(nd_mapping, label_ent);
|
||||||
|
list_move(&label_ent->list, &list);
|
||||||
|
}
|
||||||
|
mutex_unlock(&nd_mapping->lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the resource associated with the first label in the set
|
* Find the resource associated with the first label in the set
|
||||||
* per the v1.2 namespace specification.
|
* per the v1.2 namespace specification.
|
||||||
|
@ -999,8 +1008,10 @@ static int __blk_label_update(struct nd_region *nd_region,
|
||||||
if (is_old_resource(res, old_res_list, old_num_resources))
|
if (is_old_resource(res, old_res_list, old_num_resources))
|
||||||
continue; /* carry-over */
|
continue; /* carry-over */
|
||||||
slot = nd_label_alloc_slot(ndd);
|
slot = nd_label_alloc_slot(ndd);
|
||||||
if (slot == UINT_MAX)
|
if (slot == UINT_MAX) {
|
||||||
|
rc = -ENXIO;
|
||||||
goto abort;
|
goto abort;
|
||||||
|
}
|
||||||
dev_dbg(ndd->dev, "allocated: %d\n", slot);
|
dev_dbg(ndd->dev, "allocated: %d\n", slot);
|
||||||
|
|
||||||
nd_label = to_label(ndd, slot);
|
nd_label = to_label(ndd, slot);
|
||||||
|
|
Loading…
Reference in a new issue