Commit 1f13d2f7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -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 {
+27 −44
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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();
+2 −1
Original line number Diff line number Diff line
@@ -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
Loading