mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
libnvdimm fixes for 6.2
- Resolve the conflict between KMSAN and NVDIMM with respect to reserving pmem namespace / volume capacity for larger sizeof(struct page) - Fix a lockdep warning in the the NFIT code - Fix a kernel-doc build warning -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSbo+XnGs+rwLz9XGXfioYZHlFsZwUCY+b8BQAKCRDfioYZHlFs Z+W4AQDNd/WepR9MiDZsDx+Kbte2WEpf3lHvP8Nzi9hspnlpQwD8Ds/rV4y4XGW5 /CXl6fqrs4A6O9jtz4FxCu+ZCy5YvAI= =SiUf -----END PGP SIGNATURE----- Merge tag 'libnvdimm-fixes-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm Pull libnvdimm fixes from Dan Williams: "A fix for an issue that could causes users to inadvertantly reserve too much capacity when debugging the KMSAN and persistent memory namespace, a lockdep fix, and a kernel-doc build warning: - Resolve the conflict between KMSAN and NVDIMM with respect to reserving pmem namespace / volume capacity for larger sizeof(struct page) - Fix a lockdep warning in the the NFIT code - Fix a kernel-doc build warning" * tag 'libnvdimm-fixes-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: nvdimm: Support sizeof(struct page) > MAX_STRUCT_PAGE_SIZE ACPI: NFIT: fix a potential deadlock during NFIT teardown dax: super.c: fix kernel-doc bad line warning
This commit is contained in:
commit
95232dd9ae
@ -3297,8 +3297,8 @@ void acpi_nfit_shutdown(void *data)
|
||||
|
||||
mutex_lock(&acpi_desc->init_mutex);
|
||||
set_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
|
||||
cancel_delayed_work_sync(&acpi_desc->dwork);
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
cancel_delayed_work_sync(&acpi_desc->dwork);
|
||||
|
||||
/*
|
||||
* Bounce the nvdimm bus lock to make sure any in-flight
|
||||
|
@ -475,7 +475,7 @@ EXPORT_SYMBOL_GPL(put_dax);
|
||||
/**
|
||||
* dax_holder() - obtain the holder of a dax device
|
||||
* @dax_dev: a dax_device instance
|
||||
|
||||
*
|
||||
* Return: the holder's data which represents the holder if registered,
|
||||
* otherwize NULL.
|
||||
*/
|
||||
|
@ -102,6 +102,25 @@ config NVDIMM_KEYS
|
||||
depends on ENCRYPTED_KEYS
|
||||
depends on (LIBNVDIMM=ENCRYPTED_KEYS) || LIBNVDIMM=m
|
||||
|
||||
config NVDIMM_KMSAN
|
||||
bool
|
||||
depends on KMSAN
|
||||
help
|
||||
KMSAN, and other memory debug facilities, increase the size of
|
||||
'struct page' to contain extra metadata. This collides with
|
||||
the NVDIMM capability to store a potentially
|
||||
larger-than-"System RAM" size 'struct page' array in a
|
||||
reservation of persistent memory rather than limited /
|
||||
precious DRAM. However, that reservation needs to persist for
|
||||
the life of the given NVDIMM namespace. If you are using KMSAN
|
||||
to debug an issue unrelated to NVDIMMs or DAX then say N to this
|
||||
option. Otherwise, say Y but understand that any namespaces
|
||||
(with the page array stored pmem) created with this build of
|
||||
the kernel will permanently reserve and strand excess
|
||||
capacity compared to the CONFIG_KMSAN=n case.
|
||||
|
||||
Select N if unsure.
|
||||
|
||||
config NVDIMM_TEST_BUILD
|
||||
tristate "Build the unit test core"
|
||||
depends on m
|
||||
|
@ -652,7 +652,7 @@ void devm_namespace_disable(struct device *dev,
|
||||
struct nd_namespace_common *ndns);
|
||||
#if IS_ENABLED(CONFIG_ND_CLAIM)
|
||||
/* max struct page size independent of kernel config */
|
||||
#define MAX_STRUCT_PAGE_SIZE 128
|
||||
#define MAX_STRUCT_PAGE_SIZE 64
|
||||
int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
|
||||
#else
|
||||
static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "pfn.h"
|
||||
#include "nd.h"
|
||||
|
||||
static const bool page_struct_override = IS_ENABLED(CONFIG_NVDIMM_KMSAN);
|
||||
|
||||
static void nd_pfn_release(struct device *dev)
|
||||
{
|
||||
struct nd_region *nd_region = to_nd_region(dev->parent);
|
||||
@ -758,12 +760,6 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note, we use 64 here for the standard size of struct page,
|
||||
* debugging options may cause it to be larger in which case the
|
||||
* implementation will limit the pfns advertised through
|
||||
* ->direct_access() to those that are included in the memmap.
|
||||
*/
|
||||
start = nsio->res.start;
|
||||
size = resource_size(&nsio->res);
|
||||
npfns = PHYS_PFN(size - SZ_8K);
|
||||
@ -782,20 +778,33 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
|
||||
}
|
||||
end_trunc = start + size - ALIGN_DOWN(start + size, align);
|
||||
if (nd_pfn->mode == PFN_MODE_PMEM) {
|
||||
unsigned long page_map_size = MAX_STRUCT_PAGE_SIZE * npfns;
|
||||
|
||||
/*
|
||||
* The altmap should be padded out to the block size used
|
||||
* when populating the vmemmap. This *should* be equal to
|
||||
* PMD_SIZE for most architectures.
|
||||
*
|
||||
* Also make sure size of struct page is less than 128. We
|
||||
* want to make sure we use large enough size here so that
|
||||
* we don't have a dynamic reserve space depending on
|
||||
* struct page size. But we also want to make sure we notice
|
||||
* when we end up adding new elements to struct page.
|
||||
* Also make sure size of struct page is less than
|
||||
* MAX_STRUCT_PAGE_SIZE. The goal here is compatibility in the
|
||||
* face of production kernel configurations that reduce the
|
||||
* 'struct page' size below MAX_STRUCT_PAGE_SIZE. For debug
|
||||
* kernel configurations that increase the 'struct page' size
|
||||
* above MAX_STRUCT_PAGE_SIZE, the page_struct_override allows
|
||||
* for continuing with the capacity that will be wasted when
|
||||
* reverting to a production kernel configuration. Otherwise,
|
||||
* those configurations are blocked by default.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(struct page) > MAX_STRUCT_PAGE_SIZE);
|
||||
offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align)
|
||||
- start;
|
||||
if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE) {
|
||||
if (page_struct_override)
|
||||
page_map_size = sizeof(struct page) * npfns;
|
||||
else {
|
||||
dev_err(&nd_pfn->dev,
|
||||
"Memory debug options prevent using pmem for the page map\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
offset = ALIGN(start + SZ_8K + page_map_size, align) - start;
|
||||
} else if (nd_pfn->mode == PFN_MODE_RAM)
|
||||
offset = ALIGN(start + SZ_8K, align) - start;
|
||||
else
|
||||
@ -818,7 +827,10 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
|
||||
pfn_sb->version_minor = cpu_to_le16(4);
|
||||
pfn_sb->end_trunc = cpu_to_le32(end_trunc);
|
||||
pfn_sb->align = cpu_to_le32(nd_pfn->align);
|
||||
pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE);
|
||||
if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE && page_struct_override)
|
||||
pfn_sb->page_struct_size = cpu_to_le16(sizeof(struct page));
|
||||
else
|
||||
pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE);
|
||||
pfn_sb->page_size = cpu_to_le32(PAGE_SIZE);
|
||||
checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
|
||||
pfn_sb->checksum = cpu_to_le64(checksum);
|
||||
|
Loading…
Reference in New Issue
Block a user