Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'libnvdimm-fixes-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

More libnvdimm updates from Dan Williams:

- Complete the reworks to interoperate with powerpc dynamic huge page
sizes

- Fix a crash due to missed accounting for the powerpc 'struct
page'-memmap mapping granularity

- Fix badblock initialization for volatile (DRAM emulated) pmem ranges

- Stop triggering request_key() notifications to userspace when
NVDIMM-security is disabled / not present

- Miscellaneous small fixups

* tag 'libnvdimm-fixes-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
libnvdimm/region: Enable MAP_SYNC for volatile regions
libnvdimm: prevent nvdimm from requesting key when security is disabled
libnvdimm/region: Initialize bad block for volatile namespaces
libnvdimm/nfit_test: Fix acpi_handle redefinition
libnvdimm/altmap: Track namespace boundaries in altmap
libnvdimm: Fix endian conversion issues 
libnvdimm/dax: Pick the right alignment default when creating dax devices
powerpc/book3s64: Export has_transparent_hugepage() related functions.

+110 -51
+7 -1
arch/powerpc/include/asm/book3s/64/radix.h
··· 254 254 extern pgtable_t radix__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); 255 255 extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm, 256 256 unsigned long addr, pmd_t *pmdp); 257 - extern int radix__has_transparent_hugepage(void); 257 + static inline int radix__has_transparent_hugepage(void) 258 + { 259 + /* For radix 2M at PMD level means thp */ 260 + if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT) 261 + return 1; 262 + return 0; 263 + } 258 264 #endif 259 265 260 266 extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
+2
arch/powerpc/mm/book3s64/hash_pgtable.c
··· 406 406 407 407 return 1; 408 408 } 409 + EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage); 410 + 409 411 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 410 412 411 413 #ifdef CONFIG_STRICT_KERNEL_RWX
-7
arch/powerpc/mm/book3s64/radix_pgtable.c
··· 1027 1027 return old_pmd; 1028 1028 } 1029 1029 1030 - int radix__has_transparent_hugepage(void) 1031 - { 1032 - /* For radix 2M at PMD level means thp */ 1033 - if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT) 1034 - return 1; 1035 - return 0; 1036 - } 1037 1030 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 1038 1031 1039 1032 void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
+16 -1
arch/powerpc/mm/init_64.c
··· 172 172 vmemmap_list = vmem_back; 173 173 } 174 174 175 + static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long start, 176 + unsigned long page_size) 177 + { 178 + unsigned long nr_pfn = page_size / sizeof(struct page); 179 + unsigned long start_pfn = page_to_pfn((struct page *)start); 180 + 181 + if ((start_pfn + nr_pfn) > altmap->end_pfn) 182 + return true; 183 + 184 + if (start_pfn < altmap->base_pfn) 185 + return true; 186 + 187 + return false; 188 + } 189 + 175 190 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, 176 191 struct vmem_altmap *altmap) 177 192 { ··· 209 194 * fail due to alignment issues when using 16MB hugepages, so 210 195 * fall back to system memory if the altmap allocation fail. 211 196 */ 212 - if (altmap) { 197 + if (altmap && !altmap_cross_boundary(altmap, start, page_size)) { 213 198 p = altmap_alloc_block_buf(page_size, altmap); 214 199 if (!p) 215 200 pr_debug("altmap block allocation failed, falling back to system memory");
+4 -4
drivers/nvdimm/btt.c
··· 392 392 arena->freelist[lane].sub = 1 - arena->freelist[lane].sub; 393 393 if (++(arena->freelist[lane].seq) == 4) 394 394 arena->freelist[lane].seq = 1; 395 - if (ent_e_flag(ent->old_map)) 395 + if (ent_e_flag(le32_to_cpu(ent->old_map))) 396 396 arena->freelist[lane].has_err = 1; 397 - arena->freelist[lane].block = le32_to_cpu(ent_lba(ent->old_map)); 397 + arena->freelist[lane].block = ent_lba(le32_to_cpu(ent->old_map)); 398 398 399 399 return ret; 400 400 } ··· 560 560 * FIXME: if error clearing fails during init, we want to make 561 561 * the BTT read-only 562 562 */ 563 - if (ent_e_flag(log_new.old_map) && 564 - !ent_normal(log_new.old_map)) { 563 + if (ent_e_flag(le32_to_cpu(log_new.old_map)) && 564 + !ent_normal(le32_to_cpu(log_new.old_map))) { 565 565 arena->freelist[i].has_err = 1; 566 566 ret = arena_clear_freelist_error(arena, i); 567 567 if (ret)
+1 -1
drivers/nvdimm/bus.c
··· 180 180 sector_t sector; 181 181 182 182 /* make sure device is a region */ 183 - if (!is_nd_pmem(dev)) 183 + if (!is_memory(dev)) 184 184 return 0; 185 185 186 186 nd_region = to_nd_region(dev);
+4 -3
drivers/nvdimm/namespace_devs.c
··· 1987 1987 nd_mapping = &nd_region->mapping[i]; 1988 1988 label_ent = list_first_entry_or_null(&nd_mapping->labels, 1989 1989 typeof(*label_ent), list); 1990 - label0 = label_ent ? label_ent->label : 0; 1990 + label0 = label_ent ? label_ent->label : NULL; 1991 1991 1992 1992 if (!label0) { 1993 1993 WARN_ON(1); ··· 2322 2322 continue; 2323 2323 2324 2324 /* skip labels that describe extents outside of the region */ 2325 - if (nd_label->dpa < nd_mapping->start || nd_label->dpa > map_end) 2326 - continue; 2325 + if (__le64_to_cpu(nd_label->dpa) < nd_mapping->start || 2326 + __le64_to_cpu(nd_label->dpa) > map_end) 2327 + continue; 2327 2328 2328 2329 i = add_namespace_resource(nd_region, nd_label, devs, count); 2329 2330 if (i < 0)
+1 -5
drivers/nvdimm/nd.h
··· 289 289 struct nd_pfn *to_nd_pfn(struct device *dev); 290 290 #if IS_ENABLED(CONFIG_NVDIMM_PFN) 291 291 292 - #ifdef CONFIG_TRANSPARENT_HUGEPAGE 293 - #define PFN_DEFAULT_ALIGNMENT HPAGE_PMD_SIZE 294 - #else 295 - #define PFN_DEFAULT_ALIGNMENT PAGE_SIZE 296 - #endif 292 + #define MAX_NVDIMM_ALIGN 4 297 293 298 294 int nd_pfn_probe(struct device *dev, struct nd_namespace_common *ndns); 299 295 bool is_nd_pfn(struct device *dev);
+56 -21
drivers/nvdimm/pfn_devs.c
··· 103 103 return sprintf(buf, "%ld\n", nd_pfn->align); 104 104 } 105 105 106 - static const unsigned long *nd_pfn_supported_alignments(void) 106 + static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments) 107 107 { 108 - /* 109 - * This needs to be a non-static variable because the *_SIZE 110 - * macros aren't always constants. 111 - */ 112 - const unsigned long supported_alignments[] = { 113 - PAGE_SIZE, 114 - #ifdef CONFIG_TRANSPARENT_HUGEPAGE 115 - HPAGE_PMD_SIZE, 116 - #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD 117 - HPAGE_PUD_SIZE, 118 - #endif 119 - #endif 120 - 0, 121 - }; 122 - static unsigned long data[ARRAY_SIZE(supported_alignments)]; 123 108 124 - memcpy(data, supported_alignments, sizeof(data)); 109 + alignments[0] = PAGE_SIZE; 125 110 126 - return data; 111 + if (has_transparent_hugepage()) { 112 + alignments[1] = HPAGE_PMD_SIZE; 113 + if (IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)) 114 + alignments[2] = HPAGE_PUD_SIZE; 115 + } 116 + 117 + return alignments; 118 + } 119 + 120 + /* 121 + * Use pmd mapping if supported as default alignment 122 + */ 123 + static unsigned long nd_pfn_default_alignment(void) 124 + { 125 + 126 + if (has_transparent_hugepage()) 127 + return HPAGE_PMD_SIZE; 128 + return PAGE_SIZE; 127 129 } 128 130 129 131 static ssize_t align_store(struct device *dev, 130 132 struct device_attribute *attr, const char *buf, size_t len) 131 133 { 132 134 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 135 + unsigned long aligns[MAX_NVDIMM_ALIGN] = { [0] = 0, }; 133 136 ssize_t rc; 134 137 135 138 nd_device_lock(dev); 136 139 nvdimm_bus_lock(dev); 137 140 rc = nd_size_select_store(dev, buf, &nd_pfn->align, 138 - nd_pfn_supported_alignments()); 141 + nd_pfn_supported_alignments(aligns)); 139 142 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 140 143 buf[len - 1] == '\n' ? "" : "\n"); 141 144 nvdimm_bus_unlock(dev); ··· 262 259 static ssize_t supported_alignments_show(struct device *dev, 263 260 struct device_attribute *attr, char *buf) 264 261 { 265 - return nd_size_select_show(0, nd_pfn_supported_alignments(), buf); 262 + unsigned long aligns[MAX_NVDIMM_ALIGN] = { [0] = 0, }; 263 + 264 + return nd_size_select_show(0, 265 + nd_pfn_supported_alignments(aligns), buf); 266 266 } 267 267 static DEVICE_ATTR_RO(supported_alignments); 268 268 ··· 308 302 return NULL; 309 303 310 304 nd_pfn->mode = PFN_MODE_NONE; 311 - nd_pfn->align = PFN_DEFAULT_ALIGNMENT; 305 + nd_pfn->align = nd_pfn_default_alignment(); 312 306 dev = &nd_pfn->dev; 313 307 device_initialize(&nd_pfn->dev); 314 308 if (ndns && !__nd_attach_ndns(&nd_pfn->dev, ndns, &nd_pfn->ndns)) { ··· 418 412 return 0; 419 413 } 420 414 415 + static bool nd_supported_alignment(unsigned long align) 416 + { 417 + int i; 418 + unsigned long supported[MAX_NVDIMM_ALIGN] = { [0] = 0, }; 419 + 420 + if (align == 0) 421 + return false; 422 + 423 + nd_pfn_supported_alignments(supported); 424 + for (i = 0; supported[i]; i++) 425 + if (align == supported[i]) 426 + return true; 427 + return false; 428 + } 429 + 421 430 /** 422 431 * nd_pfn_validate - read and validate info-block 423 432 * @nd_pfn: fsdax namespace runtime state / properties ··· 514 493 dev_err(&nd_pfn->dev, 515 494 "init failed, struct page size mismatch %d\n", 516 495 le16_to_cpu(pfn_sb->page_struct_size)); 496 + return -EOPNOTSUPP; 497 + } 498 + 499 + /* 500 + * Check whether the we support the alignment. For Dax if the 501 + * superblock alignment is not matching, we won't initialize 502 + * the device. 503 + */ 504 + if (!nd_supported_alignment(align) && 505 + !memcmp(pfn_sb->signature, DAX_SIG, PFN_SIG_LEN)) { 506 + dev_err(&nd_pfn->dev, "init failed, alignment mismatch: " 507 + "%ld:%ld\n", nd_pfn->align, align); 517 508 return -EOPNOTSUPP; 518 509 } 519 510 ··· 672 639 struct nd_namespace_common *ndns = nd_pfn->ndns; 673 640 struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); 674 641 resource_size_t base = nsio->res.start + start_pad; 642 + resource_size_t end = nsio->res.end - end_trunc; 675 643 struct vmem_altmap __altmap = { 676 644 .base_pfn = init_altmap_base(base), 677 645 .reserve = init_altmap_reserve(base), 646 + .end_pfn = PHYS_PFN(end), 678 647 }; 679 648 680 649 memcpy(res, &nsio->res, sizeof(*res));
+2 -2
drivers/nvdimm/region.c
··· 34 34 if (rc) 35 35 return rc; 36 36 37 - if (is_nd_pmem(&nd_region->dev)) { 37 + if (is_memory(&nd_region->dev)) { 38 38 struct resource ndr_res; 39 39 40 40 if (devm_init_badblocks(dev, &nd_region->bb)) ··· 123 123 struct nd_region *nd_region = to_nd_region(dev); 124 124 struct resource res; 125 125 126 - if (is_nd_pmem(&nd_region->dev)) { 126 + if (is_memory(&nd_region->dev)) { 127 127 res.start = nd_region->ndr_start; 128 128 res.end = nd_region->ndr_start + 129 129 nd_region->ndr_size - 1;
+5 -2
drivers/nvdimm/region_devs.c
··· 632 632 if (!is_memory(dev) && a == &dev_attr_dax_seed.attr) 633 633 return 0; 634 634 635 - if (!is_nd_pmem(dev) && a == &dev_attr_badblocks.attr) 635 + if (!is_memory(dev) && a == &dev_attr_badblocks.attr) 636 636 return 0; 637 637 638 638 if (a == &dev_attr_resource.attr) { 639 - if (is_nd_pmem(dev)) 639 + if (is_memory(dev)) 640 640 return 0400; 641 641 else 642 642 return 0; ··· 1168 1168 1169 1169 bool is_nvdimm_sync(struct nd_region *nd_region) 1170 1170 { 1171 + if (is_nd_volatile(&nd_region->dev)) 1172 + return true; 1173 + 1171 1174 return is_nd_pmem(&nd_region->dev) && 1172 1175 !test_bit(ND_REGION_ASYNC, &nd_region->flags); 1173 1176 }
+4
drivers/nvdimm/security.c
··· 177 177 || !nvdimm->sec.flags) 178 178 return -EIO; 179 179 180 + /* No need to go further if security is disabled */ 181 + if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags)) 182 + return 0; 183 + 180 184 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { 181 185 dev_dbg(dev, "Security operation in progress.\n"); 182 186 return -EBUSY;
+6 -1
include/linux/huge_mm.h
··· 108 108 109 109 if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_FLAG)) 110 110 return true; 111 - 111 + /* 112 + * For dax vmas, try to always use hugepage mappings. If the kernel does 113 + * not support hugepages, fsdax mappings will fallback to PAGE_SIZE 114 + * mappings, and device-dax namespaces, that try to guarantee a given 115 + * mapping size, will fail to enable 116 + */ 112 117 if (vma_is_dax(vma)) 113 118 return true; 114 119
+1
include/linux/memremap.h
··· 17 17 */ 18 18 struct vmem_altmap { 19 19 const unsigned long base_pfn; 20 + const unsigned long end_pfn; 20 21 const unsigned long reserve; 21 22 unsigned long free; 22 23 unsigned long align;
+1 -3
tools/testing/nvdimm/test/nfit_test.h
··· 4 4 */ 5 5 #ifndef __NFIT_TEST_H__ 6 6 #define __NFIT_TEST_H__ 7 + #include <linux/acpi.h> 7 8 #include <linux/list.h> 8 9 #include <linux/uuid.h> 9 10 #include <linux/ioport.h> ··· 202 201 __u8 enable; 203 202 __u32 status; 204 203 } __packed; 205 - 206 - union acpi_object; 207 - typedef void *acpi_handle; 208 204 209 205 typedef struct nfit_test_resource *(*nfit_test_lookup_fn)(resource_size_t); 210 206 typedef union acpi_object *(*nfit_test_evaluate_dsm_fn)(acpi_handle handle,