mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
7e1c4e2792
When a memblock allocation APIs are called with align = 0, the alignment is implicitly set to SMP_CACHE_BYTES. Implicit alignment is done deep in the memblock allocator and it can come as a surprise. Not that such an alignment would be wrong even when used incorrectly but it is better to be explicit for the sake of clarity and the prinicple of the least surprise. Replace all such uses of memblock APIs with the 'align' parameter explicitly set to SMP_CACHE_BYTES and stop implicit alignment assignment in the memblock internal allocation functions. For the case when memblock APIs are used via helper functions, e.g. like iommu_arena_new_node() in Alpha, the helper functions were detected with Coccinelle's help and then manually examined and updated where appropriate. The direct memblock APIs users were updated using the semantic patch below: @@ expression size, min_addr, max_addr, nid; @@ ( | - memblock_alloc_try_nid_raw(size, 0, min_addr, max_addr, nid) + memblock_alloc_try_nid_raw(size, SMP_CACHE_BYTES, min_addr, max_addr, nid) | - memblock_alloc_try_nid_nopanic(size, 0, min_addr, max_addr, nid) + memblock_alloc_try_nid_nopanic(size, SMP_CACHE_BYTES, min_addr, max_addr, nid) | - memblock_alloc_try_nid(size, 0, min_addr, max_addr, nid) + memblock_alloc_try_nid(size, SMP_CACHE_BYTES, min_addr, max_addr, nid) | - memblock_alloc(size, 0) + memblock_alloc(size, SMP_CACHE_BYTES) | - memblock_alloc_raw(size, 0) + memblock_alloc_raw(size, SMP_CACHE_BYTES) | - memblock_alloc_from(size, 0, min_addr) + memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr) | - memblock_alloc_nopanic(size, 0) + memblock_alloc_nopanic(size, SMP_CACHE_BYTES) | - memblock_alloc_low(size, 0) + memblock_alloc_low(size, SMP_CACHE_BYTES) | - memblock_alloc_low_nopanic(size, 0) + memblock_alloc_low_nopanic(size, SMP_CACHE_BYTES) | - memblock_alloc_from_nopanic(size, 0, min_addr) + memblock_alloc_from_nopanic(size, SMP_CACHE_BYTES, min_addr) | - memblock_alloc_node(size, 0, nid) + memblock_alloc_node(size, SMP_CACHE_BYTES, nid) ) [mhocko@suse.com: changelog update] [akpm@linux-foundation.org: coding-style fixes] [rppt@linux.ibm.com: fix missed uses of implicit alignment] Link: http://lkml.kernel.org/r/20181016133656.GA10925@rapoport-lnx Link: http://lkml.kernel.org/r/1538687224-17535-1-git-send-email-rppt@linux.vnet.ibm.com Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Suggested-by: Michal Hocko <mhocko@suse.com> Acked-by: Paul Burton <paul.burton@mips.com> [MIPS] Acked-by: Michael Ellerman <mpe@ellerman.id.au> [powerpc] Acked-by: Michal Hocko <mhocko@suse.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Chris Zankel <chris@zankel.net> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Guan Xuetao <gxt@pku.edu.cn> Cc: Ingo Molnar <mingo@redhat.com> Cc: Matt Turner <mattst88@gmail.com> Cc: Michal Simek <monstr@monstr.eu> Cc: Richard Weinberger <richard@nod.at> Cc: Russell King <linux@armlinux.org.uk> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
82 lines
1.6 KiB
C
82 lines
1.6 KiB
C
/*
|
|
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
|
* Licensed under the GPL
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/memblock.h>
|
|
#include <linux/initrd.h>
|
|
#include <asm/types.h>
|
|
#include <init.h>
|
|
#include <os.h>
|
|
|
|
/* Changed by uml_initrd_setup, which is a setup */
|
|
static char *initrd __initdata = NULL;
|
|
static int load_initrd(char *filename, void *buf, int size);
|
|
|
|
int __init read_initrd(void)
|
|
{
|
|
void *area;
|
|
long long size;
|
|
int err;
|
|
|
|
if (initrd == NULL)
|
|
return 0;
|
|
|
|
err = os_file_size(initrd, &size);
|
|
if (err)
|
|
return 0;
|
|
|
|
/*
|
|
* This is necessary because alloc_bootmem craps out if you
|
|
* ask for no memory.
|
|
*/
|
|
if (size == 0) {
|
|
printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd);
|
|
return 0;
|
|
}
|
|
|
|
area = memblock_alloc(size, SMP_CACHE_BYTES);
|
|
|
|
if (load_initrd(initrd, area, size) == -1)
|
|
return 0;
|
|
|
|
initrd_start = (unsigned long) area;
|
|
initrd_end = initrd_start + size;
|
|
return 0;
|
|
}
|
|
|
|
static int __init uml_initrd_setup(char *line, int *add)
|
|
{
|
|
initrd = line;
|
|
return 0;
|
|
}
|
|
|
|
__uml_setup("initrd=", uml_initrd_setup,
|
|
"initrd=<initrd image>\n"
|
|
" This is used to boot UML from an initrd image. The argument is the\n"
|
|
" name of the file containing the image.\n\n"
|
|
);
|
|
|
|
static int load_initrd(char *filename, void *buf, int size)
|
|
{
|
|
int fd, n;
|
|
|
|
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
|
|
if (fd < 0) {
|
|
printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
|
|
-fd);
|
|
return -1;
|
|
}
|
|
n = os_read_file(fd, buf, size);
|
|
if (n != size) {
|
|
printk(KERN_ERR "Read of %d bytes from '%s' failed, "
|
|
"err = %d\n", size,
|
|
filename, -n);
|
|
return -1;
|
|
}
|
|
|
|
os_close_file(fd);
|
|
return 0;
|
|
}
|