diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/Makefile | 1 | ||||
-rw-r--r-- | mm/memblock.c | 104 | ||||
-rw-r--r-- | mm/nobootmem.c | 128 |
3 files changed, 104 insertions, 129 deletions
diff --git a/mm/Makefile b/mm/Makefile index ca3c844d7a56..d210cc9d6f80 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -42,7 +42,6 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ | |||
42 | debug.o $(mmu-y) | 42 | debug.o $(mmu-y) |
43 | 43 | ||
44 | obj-y += init-mm.o | 44 | obj-y += init-mm.o |
45 | obj-y += nobootmem.o | ||
46 | obj-y += memblock.o | 45 | obj-y += memblock.o |
47 | 46 | ||
48 | ifdef CONFIG_MMU | 47 | ifdef CONFIG_MMU |
diff --git a/mm/memblock.c b/mm/memblock.c index 8b63a04e8cca..3dd9cfef996c 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -82,6 +82,16 @@ | |||
82 | * initialization compltes. | 82 | * initialization compltes. |
83 | */ | 83 | */ |
84 | 84 | ||
85 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
86 | struct pglist_data __refdata contig_page_data; | ||
87 | EXPORT_SYMBOL(contig_page_data); | ||
88 | #endif | ||
89 | |||
90 | unsigned long max_low_pfn; | ||
91 | unsigned long min_low_pfn; | ||
92 | unsigned long max_pfn; | ||
93 | unsigned long long max_possible_pfn; | ||
94 | |||
85 | static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; | 95 | static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; |
86 | static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; | 96 | static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; |
87 | #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP | 97 | #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP |
@@ -1877,6 +1887,100 @@ static int __init early_memblock(char *p) | |||
1877 | } | 1887 | } |
1878 | early_param("memblock", early_memblock); | 1888 | early_param("memblock", early_memblock); |
1879 | 1889 | ||
1890 | static void __init __free_pages_memory(unsigned long start, unsigned long end) | ||
1891 | { | ||
1892 | int order; | ||
1893 | |||
1894 | while (start < end) { | ||
1895 | order = min(MAX_ORDER - 1UL, __ffs(start)); | ||
1896 | |||
1897 | while (start + (1UL << order) > end) | ||
1898 | order--; | ||
1899 | |||
1900 | memblock_free_pages(pfn_to_page(start), start, order); | ||
1901 | |||
1902 | start += (1UL << order); | ||
1903 | } | ||
1904 | } | ||
1905 | |||
1906 | static unsigned long __init __free_memory_core(phys_addr_t start, | ||
1907 | phys_addr_t end) | ||
1908 | { | ||
1909 | unsigned long start_pfn = PFN_UP(start); | ||
1910 | unsigned long end_pfn = min_t(unsigned long, | ||
1911 | PFN_DOWN(end), max_low_pfn); | ||
1912 | |||
1913 | if (start_pfn >= end_pfn) | ||
1914 | return 0; | ||
1915 | |||
1916 | __free_pages_memory(start_pfn, end_pfn); | ||
1917 | |||
1918 | return end_pfn - start_pfn; | ||
1919 | } | ||
1920 | |||
1921 | static unsigned long __init free_low_memory_core_early(void) | ||
1922 | { | ||
1923 | unsigned long count = 0; | ||
1924 | phys_addr_t start, end; | ||
1925 | u64 i; | ||
1926 | |||
1927 | memblock_clear_hotplug(0, -1); | ||
1928 | |||
1929 | for_each_reserved_mem_region(i, &start, &end) | ||
1930 | reserve_bootmem_region(start, end); | ||
1931 | |||
1932 | /* | ||
1933 | * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id | ||
1934 | * because in some case like Node0 doesn't have RAM installed | ||
1935 | * low ram will be on Node1 | ||
1936 | */ | ||
1937 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end, | ||
1938 | NULL) | ||
1939 | count += __free_memory_core(start, end); | ||
1940 | |||
1941 | return count; | ||
1942 | } | ||
1943 | |||
1944 | static int reset_managed_pages_done __initdata; | ||
1945 | |||
1946 | void reset_node_managed_pages(pg_data_t *pgdat) | ||
1947 | { | ||
1948 | struct zone *z; | ||
1949 | |||
1950 | for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) | ||
1951 | z->managed_pages = 0; | ||
1952 | } | ||
1953 | |||
1954 | void __init reset_all_zones_managed_pages(void) | ||
1955 | { | ||
1956 | struct pglist_data *pgdat; | ||
1957 | |||
1958 | if (reset_managed_pages_done) | ||
1959 | return; | ||
1960 | |||
1961 | for_each_online_pgdat(pgdat) | ||
1962 | reset_node_managed_pages(pgdat); | ||
1963 | |||
1964 | reset_managed_pages_done = 1; | ||
1965 | } | ||
1966 | |||
1967 | /** | ||
1968 | * memblock_free_all - release free pages to the buddy allocator | ||
1969 | * | ||
1970 | * Return: the number of pages actually released. | ||
1971 | */ | ||
1972 | unsigned long __init memblock_free_all(void) | ||
1973 | { | ||
1974 | unsigned long pages; | ||
1975 | |||
1976 | reset_all_zones_managed_pages(); | ||
1977 | |||
1978 | pages = free_low_memory_core_early(); | ||
1979 | totalram_pages += pages; | ||
1980 | |||
1981 | return pages; | ||
1982 | } | ||
1983 | |||
1880 | #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_ARCH_DISCARD_MEMBLOCK) | 1984 | #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_ARCH_DISCARD_MEMBLOCK) |
1881 | 1985 | ||
1882 | static int memblock_debug_show(struct seq_file *m, void *private) | 1986 | static int memblock_debug_show(struct seq_file *m, void *private) |
diff --git a/mm/nobootmem.c b/mm/nobootmem.c deleted file mode 100644 index 9608bc581cd6..000000000000 --- a/mm/nobootmem.c +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * bootmem - A boot-time physical memory allocator and configurator | ||
4 | * | ||
5 | * Copyright (C) 1999 Ingo Molnar | ||
6 | * 1999 Kanoj Sarcar, SGI | ||
7 | * 2008 Johannes Weiner | ||
8 | * | ||
9 | * Access to this subsystem has to be serialized externally (which is true | ||
10 | * for the boot process anyway). | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/pfn.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/kmemleak.h> | ||
17 | #include <linux/range.h> | ||
18 | #include <linux/memblock.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | |||
21 | #include <asm/bug.h> | ||
22 | #include <asm/io.h> | ||
23 | |||
24 | #include "internal.h" | ||
25 | |||
26 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
27 | struct pglist_data __refdata contig_page_data; | ||
28 | EXPORT_SYMBOL(contig_page_data); | ||
29 | #endif | ||
30 | |||
31 | unsigned long max_low_pfn; | ||
32 | unsigned long min_low_pfn; | ||
33 | unsigned long max_pfn; | ||
34 | unsigned long long max_possible_pfn; | ||
35 | |||
36 | static void __init __free_pages_memory(unsigned long start, unsigned long end) | ||
37 | { | ||
38 | int order; | ||
39 | |||
40 | while (start < end) { | ||
41 | order = min(MAX_ORDER - 1UL, __ffs(start)); | ||
42 | |||
43 | while (start + (1UL << order) > end) | ||
44 | order--; | ||
45 | |||
46 | memblock_free_pages(pfn_to_page(start), start, order); | ||
47 | |||
48 | start += (1UL << order); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | static unsigned long __init __free_memory_core(phys_addr_t start, | ||
53 | phys_addr_t end) | ||
54 | { | ||
55 | unsigned long start_pfn = PFN_UP(start); | ||
56 | unsigned long end_pfn = min_t(unsigned long, | ||
57 | PFN_DOWN(end), max_low_pfn); | ||
58 | |||
59 | if (start_pfn >= end_pfn) | ||
60 | return 0; | ||
61 | |||
62 | __free_pages_memory(start_pfn, end_pfn); | ||
63 | |||
64 | return end_pfn - start_pfn; | ||
65 | } | ||
66 | |||
67 | static unsigned long __init free_low_memory_core_early(void) | ||
68 | { | ||
69 | unsigned long count = 0; | ||
70 | phys_addr_t start, end; | ||
71 | u64 i; | ||
72 | |||
73 | memblock_clear_hotplug(0, -1); | ||
74 | |||
75 | for_each_reserved_mem_region(i, &start, &end) | ||
76 | reserve_bootmem_region(start, end); | ||
77 | |||
78 | /* | ||
79 | * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id | ||
80 | * because in some case like Node0 doesn't have RAM installed | ||
81 | * low ram will be on Node1 | ||
82 | */ | ||
83 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end, | ||
84 | NULL) | ||
85 | count += __free_memory_core(start, end); | ||
86 | |||
87 | return count; | ||
88 | } | ||
89 | |||
90 | static int reset_managed_pages_done __initdata; | ||
91 | |||
92 | void reset_node_managed_pages(pg_data_t *pgdat) | ||
93 | { | ||
94 | struct zone *z; | ||
95 | |||
96 | for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) | ||
97 | z->managed_pages = 0; | ||
98 | } | ||
99 | |||
100 | void __init reset_all_zones_managed_pages(void) | ||
101 | { | ||
102 | struct pglist_data *pgdat; | ||
103 | |||
104 | if (reset_managed_pages_done) | ||
105 | return; | ||
106 | |||
107 | for_each_online_pgdat(pgdat) | ||
108 | reset_node_managed_pages(pgdat); | ||
109 | |||
110 | reset_managed_pages_done = 1; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * memblock_free_all - release free pages to the buddy allocator | ||
115 | * | ||
116 | * Return: the number of pages actually released. | ||
117 | */ | ||
118 | unsigned long __init memblock_free_all(void) | ||
119 | { | ||
120 | unsigned long pages; | ||
121 | |||
122 | reset_all_zones_managed_pages(); | ||
123 | |||
124 | pages = free_low_memory_core_early(); | ||
125 | totalram_pages += pages; | ||
126 | |||
127 | return pages; | ||
128 | } | ||