mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +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/libnvdimm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ndctl.h>
|
||||
#include <linux/sysfs.h>
|
||||
@ -282,18 +283,19 @@ err:
|
||||
|
||||
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;
|
||||
|
||||
if (!buf)
|
||||
goto err;
|
||||
|
||||
if (integer->type != ACPI_TYPE_INTEGER) {
|
||||
WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n",
|
||||
integer->type);
|
||||
goto err;
|
||||
}
|
||||
|
||||
buf = ACPI_ALLOCATE(sizeof(*buf) + 4);
|
||||
if (!buf)
|
||||
goto err;
|
||||
|
||||
dst = buf + 1;
|
||||
buf->type = ACPI_TYPE_BUFFER;
|
||||
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;
|
||||
if (cmd == ND_CMD_CALL && 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;
|
||||
family = array_index_nospec(family,
|
||||
NVDIMM_BUS_FAMILY_MAX + 1);
|
||||
dsm_mask = acpi_desc->family_dsm_mask[family];
|
||||
guid = to_nfit_bus_uuid(family);
|
||||
} else {
|
||||
|
@ -367,19 +367,28 @@ void kill_dev_dax(struct dev_dax *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;
|
||||
int i;
|
||||
|
||||
device_lock_assert(dax_region->dev);
|
||||
for (i = 0; i < dev_dax->nr_range; i++) {
|
||||
struct range *range = &dev_dax->ranges[i].range;
|
||||
dev_dbg(&dev_dax->dev, "delete range[%d]: %#llx:%#llx\n", i,
|
||||
(unsigned long long)range->start,
|
||||
(unsigned long long)range->end);
|
||||
|
||||
__release_region(&dax_region->res, range->start,
|
||||
range_len(range));
|
||||
__release_region(&dax_region->res, range->start, 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)
|
||||
@ -763,22 +772,14 @@ static int alloc_dev_dax_range(struct dev_dax *dev_dax, u64 start,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ranges = krealloc(dev_dax->ranges, sizeof(*ranges)
|
||||
* (dev_dax->nr_range + 1), GFP_KERNEL);
|
||||
if (!ranges)
|
||||
alloc = __request_region(res, start, size, dev_name(dev), 0);
|
||||
if (!alloc)
|
||||
return -ENOMEM;
|
||||
|
||||
alloc = __request_region(res, start, size, dev_name(dev), 0);
|
||||
if (!alloc) {
|
||||
/*
|
||||
* If this was an empty set of ranges nothing else
|
||||
* will release @ranges, so do it now.
|
||||
*/
|
||||
if (!dev_dax->nr_range) {
|
||||
kfree(ranges);
|
||||
ranges = NULL;
|
||||
}
|
||||
dev_dax->ranges = ranges;
|
||||
ranges = krealloc(dev_dax->ranges, sizeof(*ranges)
|
||||
* (dev_dax->nr_range + 1), GFP_KERNEL);
|
||||
if (!ranges) {
|
||||
__release_region(res, alloc->start, resource_size(alloc));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -804,15 +805,10 @@ static int alloc_dev_dax_range(struct dev_dax *dev_dax, u64 start,
|
||||
return 0;
|
||||
|
||||
rc = devm_register_dax_mapping(dev_dax, dev_dax->nr_range - 1);
|
||||
if (rc) {
|
||||
dev_dbg(dev, "delete range[%d]: %pa:%pa\n", dev_dax->nr_range - 1,
|
||||
&alloc->start, &alloc->end);
|
||||
dev_dax->nr_range--;
|
||||
__release_region(res, alloc->start, resource_size(alloc));
|
||||
return rc;
|
||||
}
|
||||
if (rc)
|
||||
trim_dev_dax_range(dev_dax);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
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)) {
|
||||
devm_release_action(dax_region->dev,
|
||||
unregister_dax_mapping, &mapping->dev);
|
||||
__release_region(&dax_region->res, range->start,
|
||||
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);
|
||||
trim_dev_dax_range(dev_dax);
|
||||
to_shrink -= shrink;
|
||||
if (!to_shrink)
|
||||
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)
|
||||
{
|
||||
resource_size_t dev_size = dev_dax_size(dev_dax);
|
||||
struct device *dev = &dev_dax->dev;
|
||||
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++) {
|
||||
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);
|
||||
free_dev_dax_id(dev_dax);
|
||||
dax_region_put(dax_region);
|
||||
kfree(dev_dax->ranges);
|
||||
kfree(dev_dax->pgmap);
|
||||
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 */
|
||||
range = pgmap.range;
|
||||
range.start += offset,
|
||||
range.start += offset;
|
||||
dax_region = alloc_dax_region(dev, region_id, &range,
|
||||
nd_region->target_node, le32_to_cpu(pfn_sb->align),
|
||||
IORESOURCE_DAX_STATIC);
|
||||
|
@ -752,6 +752,7 @@ err_chrdev:
|
||||
|
||||
static void __exit dax_core_exit(void)
|
||||
{
|
||||
dax_bus_exit();
|
||||
unregister_chrdev_region(dax_devt, MINORMASK+1);
|
||||
ida_destroy(&dax_minor_ida);
|
||||
dax_fs_exit();
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef _LINUX_BTT_H
|
||||
#define _LINUX_BTT_H
|
||||
|
||||
#include <linux/badblocks.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define BTT_SIG_LEN 16
|
||||
@ -197,6 +196,8 @@ struct arena_info {
|
||||
int log_index[2];
|
||||
};
|
||||
|
||||
struct badblocks;
|
||||
|
||||
/**
|
||||
* struct btt - handle for a BTT instance
|
||||
* @btt_disk: Pointer to the gendisk for BTT device
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/badblocks.h>
|
||||
#include "nd-core.h"
|
||||
#include "pmem.h"
|
||||
#include "pfn.h"
|
||||
|
@ -3,7 +3,6 @@
|
||||
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
#include <linux/libnvdimm.h>
|
||||
#include <linux/badblocks.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/export.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
|
||||
* 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))
|
||||
continue; /* carry-over */
|
||||
slot = nd_label_alloc_slot(ndd);
|
||||
if (slot == UINT_MAX)
|
||||
if (slot == UINT_MAX) {
|
||||
rc = -ENXIO;
|
||||
goto abort;
|
||||
}
|
||||
dev_dbg(ndd->dev, "allocated: %d\n", slot);
|
||||
|
||||
nd_label = to_label(ndd, slot);
|
||||
|
Loading…
Reference in New Issue
Block a user