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

memblock, nobootmem: add memblock_virt_alloc_low()

The new memblock_virt APIs are used to replaced old bootmem API.

We need to allocate page below 4G for swiotlb.

That should fix regression on Andrew's system that is using swiotlb.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Yinghai Lu and committed by
Linus Torvalds
ad6492b8 ba635f8c

+40 -3
+1 -1
arch/arm/kernel/setup.c
··· 731 731 kernel_data.end = virt_to_phys(_end - 1); 732 732 733 733 for_each_memblock(memory, region) { 734 - res = memblock_virt_alloc(sizeof(*res), 0); 734 + res = memblock_virt_alloc_low(sizeof(*res), 0); 735 735 res->name = "System RAM"; 736 736 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); 737 737 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+37
include/linux/bootmem.h
··· 175 175 NUMA_NO_NODE); 176 176 } 177 177 178 + #ifndef ARCH_LOW_ADDRESS_LIMIT 179 + #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL 180 + #endif 181 + 182 + static inline void * __init memblock_virt_alloc_low( 183 + phys_addr_t size, phys_addr_t align) 184 + { 185 + return memblock_virt_alloc_try_nid(size, align, 186 + BOOTMEM_LOW_LIMIT, 187 + ARCH_LOW_ADDRESS_LIMIT, 188 + NUMA_NO_NODE); 189 + } 190 + static inline void * __init memblock_virt_alloc_low_nopanic( 191 + phys_addr_t size, phys_addr_t align) 192 + { 193 + return memblock_virt_alloc_try_nid_nopanic(size, align, 194 + BOOTMEM_LOW_LIMIT, 195 + ARCH_LOW_ADDRESS_LIMIT, 196 + NUMA_NO_NODE); 197 + } 198 + 178 199 static inline void * __init memblock_virt_alloc_from_nopanic( 179 200 phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) 180 201 { ··· 257 236 if (!align) 258 237 align = SMP_CACHE_BYTES; 259 238 return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT); 239 + } 240 + 241 + static inline void * __init memblock_virt_alloc_low( 242 + phys_addr_t size, phys_addr_t align) 243 + { 244 + if (!align) 245 + align = SMP_CACHE_BYTES; 246 + return __alloc_bootmem_low(size, align, BOOTMEM_LOW_LIMIT); 247 + } 248 + 249 + static inline void * __init memblock_virt_alloc_low_nopanic( 250 + phys_addr_t size, phys_addr_t align) 251 + { 252 + if (!align) 253 + align = SMP_CACHE_BYTES; 254 + return __alloc_bootmem_low_nopanic(size, align, BOOTMEM_LOW_LIMIT); 260 255 } 261 256 262 257 static inline void * __init memblock_virt_alloc_from_nopanic(
+2 -2
lib/swiotlb.c
··· 172 172 /* 173 173 * Get the overflow emergency buffer 174 174 */ 175 - v_overflow_buffer = memblock_virt_alloc_nopanic( 175 + v_overflow_buffer = memblock_virt_alloc_low_nopanic( 176 176 PAGE_ALIGN(io_tlb_overflow), 177 177 PAGE_SIZE); 178 178 if (!v_overflow_buffer) ··· 220 220 bytes = io_tlb_nslabs << IO_TLB_SHIFT; 221 221 222 222 /* Get IO TLB memory from the low pages */ 223 - vstart = memblock_virt_alloc_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE); 223 + vstart = memblock_virt_alloc_low_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE); 224 224 if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) 225 225 return; 226 226