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

mm: memory_hotplug: enumerate all supported section flags

Patch series "make hugetlb_optimize_vmemmap compatible with
memmap_on_memory", v3.

This series makes hugetlb_optimize_vmemmap compatible with
memmap_on_memory.


This patch (of 2):

We are almost running out of section flags, only one bit is available in
the worst case (powerpc with 256k pages). However, there are still some
free bits (in ->section_mem_map) on other architectures (e.g. x86_64 has
10 bits available, arm64 has 8 bits available with worst case of 64K
pages). We have hard coded those numbers in code, it is inconvenient to
use those bits on other architectures except powerpc. So transfer those
section flags to enumeration to make it easy to add new section flags in
the future. Also, move SECTION_TAINT_ZONE_DEVICE into the scope of
CONFIG_ZONE_DEVICE to save a bit on non-zone-device case.

[songmuchun@bytedance.com: replace enum with defines per David]
Link: https://lkml.kernel.org/r/20220620110616.12056-2-songmuchun@bytedance.com
Link: https://lkml.kernel.org/r/20220617135650.74901-1-songmuchun@bytedance.com
Link: https://lkml.kernel.org/r/20220617135650.74901-2-songmuchun@bytedance.com
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Muchun Song and committed by
akpm
ed7802dd ceff9d33

+39 -10
+32 -9
include/linux/mmzone.h
··· 1418 1418 * (equal SECTION_SIZE_BITS - PAGE_SHIFT), and the 1419 1419 * worst combination is powerpc with 256k pages, 1420 1420 * which results in PFN_SECTION_SHIFT equal 6. 1421 - * To sum it up, at least 6 bits are available. 1421 + * To sum it up, at least 6 bits are available on all architectures. 1422 + * However, we can exceed 6 bits on some other architectures except 1423 + * powerpc (e.g. 15 bits are available on x86_64, 13 bits are available 1424 + * with the worst case of 64K pages on arm64) if we make sure the 1425 + * exceeded bit is not applicable to powerpc. 1422 1426 */ 1423 - #define SECTION_MARKED_PRESENT (1UL<<0) 1424 - #define SECTION_HAS_MEM_MAP (1UL<<1) 1425 - #define SECTION_IS_ONLINE (1UL<<2) 1426 - #define SECTION_IS_EARLY (1UL<<3) 1427 - #define SECTION_TAINT_ZONE_DEVICE (1UL<<4) 1428 - #define SECTION_MAP_LAST_BIT (1UL<<5) 1429 - #define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1)) 1430 - #define SECTION_NID_SHIFT 6 1427 + enum { 1428 + SECTION_MARKED_PRESENT_BIT, 1429 + SECTION_HAS_MEM_MAP_BIT, 1430 + SECTION_IS_ONLINE_BIT, 1431 + SECTION_IS_EARLY_BIT, 1432 + #ifdef CONFIG_ZONE_DEVICE 1433 + SECTION_TAINT_ZONE_DEVICE_BIT, 1434 + #endif 1435 + SECTION_MAP_LAST_BIT, 1436 + }; 1437 + 1438 + #define SECTION_MARKED_PRESENT BIT(SECTION_MARKED_PRESENT_BIT) 1439 + #define SECTION_HAS_MEM_MAP BIT(SECTION_HAS_MEM_MAP_BIT) 1440 + #define SECTION_IS_ONLINE BIT(SECTION_IS_ONLINE_BIT) 1441 + #define SECTION_IS_EARLY BIT(SECTION_IS_EARLY_BIT) 1442 + #ifdef CONFIG_ZONE_DEVICE 1443 + #define SECTION_TAINT_ZONE_DEVICE BIT(SECTION_TAINT_ZONE_DEVICE_BIT) 1444 + #endif 1445 + #define SECTION_MAP_MASK (~(BIT(SECTION_MAP_LAST_BIT) - 1)) 1446 + #define SECTION_NID_SHIFT SECTION_MAP_LAST_BIT 1431 1447 1432 1448 static inline struct page *__section_mem_map_addr(struct mem_section *section) 1433 1449 { ··· 1482 1466 return (section && (section->section_mem_map & SECTION_IS_ONLINE)); 1483 1467 } 1484 1468 1469 + #ifdef CONFIG_ZONE_DEVICE 1485 1470 static inline int online_device_section(struct mem_section *section) 1486 1471 { 1487 1472 unsigned long flags = SECTION_IS_ONLINE | SECTION_TAINT_ZONE_DEVICE; 1488 1473 1489 1474 return section && ((section->section_mem_map & flags) == flags); 1490 1475 } 1476 + #else 1477 + static inline int online_device_section(struct mem_section *section) 1478 + { 1479 + return 0; 1480 + } 1481 + #endif 1491 1482 1492 1483 static inline int online_section_nr(unsigned long nr) 1493 1484 {
+6
mm/memory_hotplug.c
··· 670 670 671 671 } 672 672 673 + #ifdef CONFIG_ZONE_DEVICE 673 674 static void section_taint_zone_device(unsigned long pfn) 674 675 { 675 676 struct mem_section *ms = __pfn_to_section(pfn); 676 677 677 678 ms->section_mem_map |= SECTION_TAINT_ZONE_DEVICE; 678 679 } 680 + #else 681 + static inline void section_taint_zone_device(unsigned long pfn) 682 + { 683 + } 684 + #endif 679 685 680 686 /* 681 687 * Associate the pfn range with the given zone, initializing the memmaps
+1 -1
mm/sparse.c
··· 281 281 { 282 282 unsigned long coded_mem_map = 283 283 (unsigned long)(mem_map - (section_nr_to_pfn(pnum))); 284 - BUILD_BUG_ON(SECTION_MAP_LAST_BIT > (1UL<<PFN_SECTION_SHIFT)); 284 + BUILD_BUG_ON(SECTION_MAP_LAST_BIT > PFN_SECTION_SHIFT); 285 285 BUG_ON(coded_mem_map & ~SECTION_MAP_MASK); 286 286 return coded_mem_map; 287 287 }