History

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

Linus Torvalds committed 3 years ago

Commit 95232dd2 parents 230809c c91d7135 files · +49 −18Browse files

Unified · Split

5 files
  1. drivers/acpi/nfit/core.c +1 −1
  2. drivers/dax/super.c +1 −1
  3. drivers/nvdimm/Kconfig +19 −0
  4. drivers/nvdimm/nd.h +1 −1
  5. drivers/nvdimm/pfn_devs.c +27 −15
drivers/acpi/nfit/core.c+1−1
@@ -3297,8 +3297,8 @@ void acpi_nfit_shutdown(void *data) · 3296 unmodified lines
32973297
32983298 mutex_lock(&acpi_desc->init_mutex);
32993299 set_bit(ARS_CANCEL, &acpi_desc->scrub_flags);
3300− cancel_delayed_work_sync(&acpi_desc->dwork);
33013300 mutex_unlock(&acpi_desc->init_mutex);
3301+ cancel_delayed_work_sync(&acpi_desc->dwork);
33023302
33033303 /*
33043304 * Bounce the nvdimm bus lock to make sure any in-flight
drivers/dax/super.c+1−1
@@ -475,7 +475,7 @@ EXPORT_SYMBOL_GPL(put_dax); · 474 unmodified lines
475475 /**
476476 * dax_holder() - obtain the holder of a dax device
477477 * @dax_dev: a dax_device instance
478−
478+ *
479479 * Return: the holder's data which represents the holder if registered,
480480 * otherwize NULL.
481481 */
drivers/nvdimm/Kconfig+19−0
@@ -102,6 +102,25 @@ config NVDIMM_KEYS · 101 unmodified lines
102102 depends on ENCRYPTED_KEYS
103103 depends on (LIBNVDIMM=ENCRYPTED_KEYS) || LIBNVDIMM=m
104104
105+config NVDIMM_KMSAN
106+ bool
107+ depends on KMSAN
108+ help
109+ KMSAN, and other memory debug facilities, increase the size of
110+ 'struct page' to contain extra metadata. This collides with
111+ the NVDIMM capability to store a potentially
112+ larger-than-"System RAM" size 'struct page' array in a
113+ reservation of persistent memory rather than limited /
114+ precious DRAM. However, that reservation needs to persist for
115+ the life of the given NVDIMM namespace. If you are using KMSAN
116+ to debug an issue unrelated to NVDIMMs or DAX then say N to this
117+ option. Otherwise, say Y but understand that any namespaces
118+ (with the page array stored pmem) created with this build of
119+ the kernel will permanently reserve and strand excess
120+ capacity compared to the CONFIG_KMSAN=n case.
121+
122+ Select N if unsure.
123+
105124 config NVDIMM_TEST_BUILD
106125 tristate "Build the unit test core"
107126 depends on m
drivers/nvdimm/nd.h+1−1
@@ -652,7 +652,7 @@ void devm_namespace_disable(struct device *dev, · 651 unmodified lines
652652 struct nd_namespace_common *ndns);
653653 #if IS_ENABLED(CONFIG_ND_CLAIM)
654654 /* max struct page size independent of kernel config */
655−#define MAX_STRUCT_PAGE_SIZE 128
655+#define MAX_STRUCT_PAGE_SIZE 64
656656 int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
657657 #else
658658 static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
drivers/nvdimm/pfn_devs.c+27−15
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 #include "pfn.h"
1414 #include "nd.h"
1515
16+static const bool page_struct_override = IS_ENABLED(CONFIG_NVDIMM_KMSAN);
17+
1618 static void nd_pfn_release(struct device *dev)
1719 {
1820 struct nd_region *nd_region = to_nd_region(dev->parent);
@@ -758,12 +760,6 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 739 unmodified lines
758760 return -ENXIO;
759761 }
760762
761− /*
762− * Note, we use 64 here for the standard size of struct page,
763− * debugging options may cause it to be larger in which case the
764− * implementation will limit the pfns advertised through
765− * ->direct_access() to those that are included in the memmap.
766− */
767763 start = nsio->res.start;
768764 size = resource_size(&nsio->res);
769765 npfns = PHYS_PFN(size - SZ_8K);
@@ -782,20 +778,33 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 12 unmodified lines
782778 }
783779 end_trunc = start + size - ALIGN_DOWN(start + size, align);
784780 if (nd_pfn->mode == PFN_MODE_PMEM) {
781+ unsigned long page_map_size = MAX_STRUCT_PAGE_SIZE * npfns;
782+
785783 /*
786784 * The altmap should be padded out to the block size used
787785 * when populating the vmemmap. This *should* be equal to
788786 * PMD_SIZE for most architectures.
789787 *
790− * Also make sure size of struct page is less than 128. We
791− * want to make sure we use large enough size here so that
792− * we don't have a dynamic reserve space depending on
793− * struct page size. But we also want to make sure we notice
794− * when we end up adding new elements to struct page.
788+ * Also make sure size of struct page is less than
789+ * MAX_STRUCT_PAGE_SIZE. The goal here is compatibility in the
790+ * face of production kernel configurations that reduce the
791+ * 'struct page' size below MAX_STRUCT_PAGE_SIZE. For debug
792+ * kernel configurations that increase the 'struct page' size
793+ * above MAX_STRUCT_PAGE_SIZE, the page_struct_override allows
794+ * for continuing with the capacity that will be wasted when
795+ * reverting to a production kernel configuration. Otherwise,
796+ * those configurations are blocked by default.
795797 */
796− BUILD_BUG_ON(sizeof(struct page) > MAX_STRUCT_PAGE_SIZE);
797− offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align)
798− - start;
798+ if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE) {
799+ if (page_struct_override)
800+ page_map_size = sizeof(struct page) * npfns;
801+ else {
802+ dev_err(&nd_pfn->dev,
803+ "Memory debug options prevent using pmem for the page map\n");
804+ return -EINVAL;
805+ }
806+ }
807+ offset = ALIGN(start + SZ_8K + page_map_size, align) - start;
799808 } else if (nd_pfn->mode == PFN_MODE_RAM)
800809 offset = ALIGN(start + SZ_8K, align) - start;
801810 else
@@ -818,7 +827,10 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 16 unmodified lines
818827 pfn_sb->version_minor = cpu_to_le16(4);
819828 pfn_sb->end_trunc = cpu_to_le32(end_trunc);
820829 pfn_sb->align = cpu_to_le32(nd_pfn->align);
821− pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE);
830+ if (sizeof(struct page) > MAX_STRUCT_PAGE_SIZE && page_struct_override)
831+ pfn_sb->page_struct_size = cpu_to_le16(sizeof(struct page));
832+ else
833+ pfn_sb->page_struct_size = cpu_to_le16(MAX_STRUCT_PAGE_SIZE);
822834 pfn_sb->page_size = cpu_to_le32(PAGE_SIZE);
823835 checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
824836 pfn_sb->checksum = cpu_to_le64(checksum);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t