diff options
-rw-r--r-- | mm/memblock.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/mm/memblock.c b/mm/memblock.c index 0ac412a0a7ee..accff1087137 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
@@ -83,33 +83,25 @@ static long __init_memblock memblock_overlaps_region(struct memblock_type *type, | |||
83 | } | 83 | } |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * memblock_find_in_range_node - find free area in given range and node | 86 | * __memblock_find_range_top_down - find free area utility, in top-down |
87 | * @start: start of candidate range | 87 | * @start: start of candidate range |
88 | * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE} | 88 | * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE} |
89 | * @size: size of free area to find | 89 | * @size: size of free area to find |
90 | * @align: alignment of free area to find | 90 | * @align: alignment of free area to find |
91 | * @nid: nid of the free area to find, %MAX_NUMNODES for any node | 91 | * @nid: nid of the free area to find, %MAX_NUMNODES for any node |
92 | * | 92 | * |
93 | * Find @size free area aligned to @align in the specified range and node. | 93 | * Utility called from memblock_find_in_range_node(), find free area top-down. |
94 | * | 94 | * |
95 | * RETURNS: | 95 | * RETURNS: |
96 | * Found address on success, %0 on failure. | 96 | * Found address on success, %0 on failure. |
97 | */ | 97 | */ |
98 | phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start, | 98 | static phys_addr_t __init_memblock |
99 | phys_addr_t end, phys_addr_t size, | 99 | __memblock_find_range_top_down(phys_addr_t start, phys_addr_t end, |
100 | phys_addr_t align, int nid) | 100 | phys_addr_t size, phys_addr_t align, int nid) |
101 | { | 101 | { |
102 | phys_addr_t this_start, this_end, cand; | 102 | phys_addr_t this_start, this_end, cand; |
103 | u64 i; | 103 | u64 i; |
104 | 104 | ||
105 | /* pump up @end */ | ||
106 | if (end == MEMBLOCK_ALLOC_ACCESSIBLE) | ||
107 | end = memblock.current_limit; | ||
108 | |||
109 | /* avoid allocating the first page */ | ||
110 | start = max_t(phys_addr_t, start, PAGE_SIZE); | ||
111 | end = max(start, end); | ||
112 | |||
113 | for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) { | 105 | for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) { |
114 | this_start = clamp(this_start, start, end); | 106 | this_start = clamp(this_start, start, end); |
115 | this_end = clamp(this_end, start, end); | 107 | this_end = clamp(this_end, start, end); |
@@ -121,10 +113,39 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start, | |||
121 | if (cand >= this_start) | 113 | if (cand >= this_start) |
122 | return cand; | 114 | return cand; |
123 | } | 115 | } |
116 | |||
124 | return 0; | 117 | return 0; |
125 | } | 118 | } |
126 | 119 | ||
127 | /** | 120 | /** |
121 | * memblock_find_in_range_node - find free area in given range and node | ||
122 | * @start: start of candidate range | ||
123 | * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE} | ||
124 | * @size: size of free area to find | ||
125 | * @align: alignment of free area to find | ||
126 | * @nid: nid of the free area to find, %MAX_NUMNODES for any node | ||
127 | * | ||
128 | * Find @size free area aligned to @align in the specified range and node. | ||
129 | * | ||
130 | * RETURNS: | ||
131 | * Found address on success, %0 on failure. | ||
132 | */ | ||
133 | phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start, | ||
134 | phys_addr_t end, phys_addr_t size, | ||
135 | phys_addr_t align, int nid) | ||
136 | { | ||
137 | /* pump up @end */ | ||
138 | if (end == MEMBLOCK_ALLOC_ACCESSIBLE) | ||
139 | end = memblock.current_limit; | ||
140 | |||
141 | /* avoid allocating the first page */ | ||
142 | start = max_t(phys_addr_t, start, PAGE_SIZE); | ||
143 | end = max(start, end); | ||
144 | |||
145 | return __memblock_find_range_top_down(start, end, size, align, nid); | ||
146 | } | ||
147 | |||
148 | /** | ||
128 | * memblock_find_in_range - find free area in given range | 149 | * memblock_find_in_range - find free area in given range |
129 | * @start: start of candidate range | 150 | * @start: start of candidate range |
130 | * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE} | 151 | * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE} |