Commit 1f13d2f7 authored by Linus Torvalds's avatar Linus Torvalds

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()
parents ef2c8b81 127c3d2e
......@@ -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 @@ static union acpi_object *pkg_to_buf(union acpi_object *pkg)
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;
__release_region(&dax_region->res, range->start,
range_len(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));
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 @@ static int __init dax_core_init(void)
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment