forked from Minki/linux
libnvdimm for 5.11-rc7
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEf41QbsdZzFdA8EfZHtKRamZ9iAIFAmAgHpoACgkQHtKRamZ9 iAKjgBAArCfer5Toj+Vsk3Q8N5oLaIUlXNhaDCkDLW20GmJPPO38PdPR2klFi+2q dtxElb3JQet5ZfWv+umkgnCgcPeqX63M2XJsEpVMW8leY7nTgjbSsQhlTdLiN4ww AbEDY72BNfyRBxDzDqdk68fWyY25ZJb3lRVxNC5pj4pMkUoQTT6etAjO6twz5t1X KMDcrmPYe+iA/swpcU9Rj5gBRC54g5fxUJzl9rgX3iiYs1yPwSUHnLw2SGzhOaKx p5n8q2pvkkNvqbCLl6OFkFsihbH7/9jgAyYNiwUXYBC/YJWgIaFwxWXNfrvnz7uG 9jg5CNtI1ldWoaQZUGG6OLaAm6vapfUvvWS+YK3RH83V8TPl56Ujqb6QG5sZ910o Qd4bkCcHojpfss7qcUPX85LMpg81wQG9suFePdTOH4BZH1deSDOxkDcPga4Vo5Fm dZXXBVtVwFXjs+MVTMgzNVMQWDCmJh5JsedO0e31/PGQCsHB5QCea7J5DjbbgfVg OQqM6AmqdYWPv8h50+o19Dxe078sY5VwflqHb3pAgOq4N3YnSfONTkPfsPVvlODn HLhWWnggFxMWTSU9Z7N0+PZU56Lsp3BOj2jDaApjh+bS+O4qC/O3XVMDKWLOMWgP UvV72HwTjSWlc8g6OvIEStcSDZ/hYigXMinnYcCSotwzOQVTumg= =QQRF -----END PGP SIGNATURE----- Merge tag 'libnvdimm-fixes-5.11-rc7' of git://git.kernel.org/pub/scm/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
This commit is contained in:
commit
b75dba7f47
@ -2269,40 +2269,24 @@ 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));
|
||||
@ -2310,8 +2294,8 @@ static int cmp_map_compat(const void *m0, const void *m1)
|
||||
|
||||
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;
|
||||
@ -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;
|
||||
@ -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) {
|
||||
@ -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++) {
|
||||
|
@ -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) {
|
||||
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
1129
tools/testing/nvdimm/test/ndtest.c
Normal file
1129
tools/testing/nvdimm/test/ndtest.c
Normal file
File diff suppressed because it is too large
Load Diff
109
tools/testing/nvdimm/test/ndtest.h
Normal file
109
tools/testing/nvdimm/test/ndtest.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef NDTEST_H
|
||||
#define NDTEST_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/libnvdimm.h>
|
||||
|
||||
/* SCM device is unable to persist memory contents */
|
||||
#define PAPR_PMEM_UNARMED (1ULL << (63 - 0))
|
||||
/* SCM device failed to persist memory contents */
|
||||
#define PAPR_PMEM_SHUTDOWN_DIRTY (1ULL << (63 - 1))
|
||||
/* SCM device contents are not persisted from previous IPL */
|
||||
#define PAPR_PMEM_EMPTY (1ULL << (63 - 3))
|
||||
#define PAPR_PMEM_HEALTH_CRITICAL (1ULL << (63 - 4))
|
||||
/* SCM device will be garded off next IPL due to failure */
|
||||
#define PAPR_PMEM_HEALTH_FATAL (1ULL << (63 - 5))
|
||||
/* SCM contents cannot persist due to current platform health status */
|
||||
#define PAPR_PMEM_HEALTH_UNHEALTHY (1ULL << (63 - 6))
|
||||
|
||||
/* Bits status indicators for health bitmap indicating unarmed dimm */
|
||||
#define PAPR_PMEM_UNARMED_MASK (PAPR_PMEM_UNARMED | \
|
||||
PAPR_PMEM_HEALTH_UNHEALTHY)
|
||||
|
||||
#define PAPR_PMEM_SAVE_FAILED (1ULL << (63 - 10))
|
||||
|
||||
/* Bits status indicators for health bitmap indicating unflushed dimm */
|
||||
#define PAPR_PMEM_BAD_SHUTDOWN_MASK (PAPR_PMEM_SHUTDOWN_DIRTY)
|
||||
|
||||
/* Bits status indicators for health bitmap indicating unrestored dimm */
|
||||
#define PAPR_PMEM_BAD_RESTORE_MASK (PAPR_PMEM_EMPTY)
|
||||
|
||||
/* Bit status indicators for smart event notification */
|
||||
#define PAPR_PMEM_SMART_EVENT_MASK (PAPR_PMEM_HEALTH_CRITICAL | \
|
||||
PAPR_PMEM_HEALTH_FATAL | \
|
||||
PAPR_PMEM_HEALTH_UNHEALTHY)
|
||||
|
||||
#define PAPR_PMEM_SAVE_MASK (PAPR_PMEM_SAVE_FAILED)
|
||||
|
||||
struct ndtest_config;
|
||||
|
||||
struct ndtest_priv {
|
||||
struct platform_device pdev;
|
||||
struct device_node *dn;
|
||||
struct list_head resources;
|
||||
struct nvdimm_bus_descriptor bus_desc;
|
||||
struct nvdimm_bus *bus;
|
||||
struct ndtest_config *config;
|
||||
|
||||
dma_addr_t *dcr_dma;
|
||||
dma_addr_t *label_dma;
|
||||
dma_addr_t *dimm_dma;
|
||||
};
|
||||
|
||||
struct ndtest_blk_mmio {
|
||||
void __iomem *base;
|
||||
u64 size;
|
||||
u64 base_offset;
|
||||
u32 line_size;
|
||||
u32 num_lines;
|
||||
u32 table_size;
|
||||
};
|
||||
|
||||
struct ndtest_dimm {
|
||||
struct device *dev;
|
||||
struct nvdimm *nvdimm;
|
||||
struct ndtest_blk_mmio *mmio;
|
||||
struct nd_region *blk_region;
|
||||
|
||||
dma_addr_t address;
|
||||
unsigned long long flags;
|
||||
unsigned long config_size;
|
||||
void *label_area;
|
||||
char *uuid_str;
|
||||
|
||||
unsigned int size;
|
||||
unsigned int handle;
|
||||
unsigned int fail_cmd;
|
||||
unsigned int physical_id;
|
||||
unsigned int num_formats;
|
||||
int id;
|
||||
int fail_cmd_code;
|
||||
u8 no_alias;
|
||||
};
|
||||
|
||||
struct ndtest_mapping {
|
||||
u64 start;
|
||||
u64 size;
|
||||
u8 position;
|
||||
u8 dimm;
|
||||
};
|
||||
|
||||
struct ndtest_region {
|
||||
struct nd_region *region;
|
||||
struct ndtest_mapping *mapping;
|
||||
u64 size;
|
||||
u8 type;
|
||||
u8 num_mappings;
|
||||
u8 range_index;
|
||||
};
|
||||
|
||||
struct ndtest_config {
|
||||
struct ndtest_dimm *dimms;
|
||||
struct ndtest_region *regions;
|
||||
unsigned int dimm_count;
|
||||
unsigned int dimm_start;
|
||||
u8 num_regions;
|
||||
};
|
||||
|
||||
#endif /* NDTEST_H */
|
Loading…
Reference in New Issue
Block a user