Skip to content

Commit

Permalink
Merge tag 'libnvdimm-fixes-5.11-rc7' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
 "A fix for a crash scenario that has been present since the initial
  merge, a minor regression in sysfs attribute visibility, and a fix for
  some flexible array warnings.

  The bulk of this pull is an update to the libnvdimm unit test
  infrastructure to test non-ACPI platforms. Given there is zero
  regression risk for test updates, and the tests enable validation of
  bits headed towards the next merge window, I saw no reason to hold the
  new tests back. Santosh originally submitted this before the v5.11
  window opened.

  Summary:

   - Fix a crash when sysfs accesses race 'dimm' driver probe/remove.

   - Fix a regression in 'resource' attribute visibility necessary for
     mapping badblocks and other physical address interrogations.

   - Fix some flexible array warnings

   - Expand the unit test infrastructure for non-ACPI platforms"

* tag 'libnvdimm-fixes-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  libnvdimm/dimm: Avoid race between probe and available_slots_show()
  ndtest: Add papr health related flags
  ndtest: Add nvdimm control functions
  ndtest: Add regions and mappings to the test buses
  ndtest: Add dimm attributes
  ndtest: Add dimms to the two buses
  ndtest: Add compatability string to treat it as PAPR family
  testing/nvdimm: Add test module for non-nfit platforms
  libnvdimm/namespace: Fix visibility of namespace resource attribute
  libnvdimm/pmem: Remove unused header
  ACPI: NFIT: Fix flexible_array.cocci warnings
  • Loading branch information
Linus Torvalds committed Feb 7, 2021
2 parents ff92acb + 7018c89 commit b75dba7
Show file tree
Hide file tree
Showing 8 changed files with 1,293 additions and 58 deletions.
75 changes: 28 additions & 47 deletions drivers/acpi/nfit/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2269,49 +2269,33 @@ static const struct attribute_group *acpi_nfit_region_attribute_groups[] = {

/* enough info to uniquely specify an interleave set */
struct nfit_set_info {
struct nfit_set_info_map {
u64 region_offset;
u32 serial_number;
u32 pad;
} mapping[0];
u64 region_offset;
u32 serial_number;
u32 pad;
};

struct nfit_set_info2 {
struct nfit_set_info_map2 {
u64 region_offset;
u32 serial_number;
u16 vendor_id;
u16 manufacturing_date;
u8 manufacturing_location;
u8 reserved[31];
} mapping[0];
u64 region_offset;
u32 serial_number;
u16 vendor_id;
u16 manufacturing_date;
u8 manufacturing_location;
u8 reserved[31];
};

static size_t sizeof_nfit_set_info(int num_mappings)
{
return sizeof(struct nfit_set_info)
+ num_mappings * sizeof(struct nfit_set_info_map);
}

static size_t sizeof_nfit_set_info2(int num_mappings)
{
return sizeof(struct nfit_set_info2)
+ num_mappings * sizeof(struct nfit_set_info_map2);
}

static int cmp_map_compat(const void *m0, const void *m1)
{
const struct nfit_set_info_map *map0 = m0;
const struct nfit_set_info_map *map1 = m1;
const struct nfit_set_info *map0 = m0;
const struct nfit_set_info *map1 = m1;

return memcmp(&map0->region_offset, &map1->region_offset,
sizeof(u64));
}

static int cmp_map(const void *m0, const void *m1)
{
const struct nfit_set_info_map *map0 = m0;
const struct nfit_set_info_map *map1 = m1;
const struct nfit_set_info *map0 = m0;
const struct nfit_set_info *map1 = m1;

if (map0->region_offset < map1->region_offset)
return -1;
Expand All @@ -2322,8 +2306,8 @@ static int cmp_map(const void *m0, const void *m1)

static int cmp_map2(const void *m0, const void *m1)
{
const struct nfit_set_info_map2 *map0 = m0;
const struct nfit_set_info_map2 *map1 = m1;
const struct nfit_set_info2 *map0 = m0;
const struct nfit_set_info2 *map1 = m1;

if (map0->region_offset < map1->region_offset)
return -1;
Expand Down Expand Up @@ -2361,22 +2345,22 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
return -ENOMEM;
import_guid(&nd_set->type_guid, spa->range_guid);

info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;

info2 = devm_kzalloc(dev, sizeof_nfit_set_info2(nr), GFP_KERNEL);
info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL);
if (!info2)
return -ENOMEM;

for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
struct nfit_set_info_map *map = &info->mapping[i];
struct nfit_set_info_map2 *map2 = &info2->mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
spa->range_index, i);
struct nfit_set_info *map = &info[i];
struct nfit_set_info2 *map2 = &info2[i];
struct acpi_nfit_memory_map *memdev =
memdev_from_spa(acpi_desc, spa->range_index, i);
struct acpi_nfit_control_region *dcr = nfit_mem->dcr;

if (!memdev || !nfit_mem->dcr) {
Expand All @@ -2395,23 +2379,20 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
}

/* v1.1 namespaces */
sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map, NULL);
nd_set->cookie1 = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
sort(info, nr, sizeof(*info), cmp_map, NULL);
nd_set->cookie1 = nd_fletcher64(info, sizeof(*info) * nr, 0);

/* v1.2 namespaces */
sort(&info2->mapping[0], nr, sizeof(struct nfit_set_info_map2),
cmp_map2, NULL);
nd_set->cookie2 = nd_fletcher64(info2, sizeof_nfit_set_info2(nr), 0);
sort(info2, nr, sizeof(*info2), cmp_map2, NULL);
nd_set->cookie2 = nd_fletcher64(info2, sizeof(*info2) * nr, 0);

/* support v1.1 namespaces created with the wrong sort order */
sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map_compat, NULL);
nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
sort(info, nr, sizeof(*info), cmp_map_compat, NULL);
nd_set->altcookie = nd_fletcher64(info, sizeof(*info) * nr, 0);

/* record the result of the sort for the mapping position */
for (i = 0; i < nr; i++) {
struct nfit_set_info_map2 *map2 = &info2->mapping[i];
struct nfit_set_info2 *map2 = &info2[i];
int j;

for (j = 0; j < nr; j++) {
Expand Down
18 changes: 15 additions & 3 deletions drivers/nvdimm/dimm_devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,16 +335,16 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(state);

static ssize_t available_slots_show(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t __available_slots_show(struct nvdimm_drvdata *ndd, char *buf)
{
struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
struct device *dev;
ssize_t rc;
u32 nfree;

if (!ndd)
return -ENXIO;

dev = ndd->dev;
nvdimm_bus_lock(dev);
nfree = nd_label_nfree(ndd);
if (nfree - 1 > nfree) {
Expand All @@ -356,6 +356,18 @@ static ssize_t available_slots_show(struct device *dev,
nvdimm_bus_unlock(dev);
return rc;
}

static ssize_t available_slots_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t rc;

nd_device_lock(dev);
rc = __available_slots_show(dev_get_drvdata(dev), buf);
nd_device_unlock(dev);

return rc;
}
static DEVICE_ATTR_RO(available_slots);

__weak ssize_t security_show(struct device *dev,
Expand Down
10 changes: 5 additions & 5 deletions drivers/nvdimm/namespace_devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,11 +1635,11 @@ static umode_t namespace_visible(struct kobject *kobj,
return a->mode;
}

if (a == &dev_attr_nstype.attr || a == &dev_attr_size.attr
|| a == &dev_attr_holder.attr
|| a == &dev_attr_holder_class.attr
|| a == &dev_attr_force_raw.attr
|| a == &dev_attr_mode.attr)
/* base is_namespace_io() attributes */
if (a == &dev_attr_nstype.attr || a == &dev_attr_size.attr ||
a == &dev_attr_holder.attr || a == &dev_attr_holder_class.attr ||
a == &dev_attr_force_raw.attr || a == &dev_attr_mode.attr ||
a == &dev_attr_resource.attr)
return a->mode;

return 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/nvdimm/pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <linux/uio.h>
#include <linux/dax.h>
#include <linux/nd.h>
#include <linux/backing-dev.h>
#include <linux/mm.h>
#include <asm/cacheflush.h>
#include "pmem.h"
Expand Down
3 changes: 2 additions & 1 deletion tools/testing/nvdimm/config_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ void check(void)
BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT));
BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_PFN));
BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK));
BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT));
if (IS_ENABLED(CONFIG_ACPI_NFIT))
BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT));
BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX));
BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX_PMEM));
}
6 changes: 5 additions & 1 deletion tools/testing/nvdimm/test/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ ccflags-y += -I$(srctree)/drivers/acpi/nfit/
obj-m += nfit_test.o
obj-m += nfit_test_iomap.o

nfit_test-y := nfit.o
ifeq ($(CONFIG_ACPI_NFIT),m)
nfit_test-y := nfit.o
else
nfit_test-y := ndtest.o
endif
nfit_test_iomap-y := iomap.o
Loading

0 comments on commit b75dba7

Please sign in to comment.