]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
initramfs: allocate heap buffers together
authorDavid Disseldorp <ddiss@suse.de>
Tue, 4 Mar 2025 05:57:48 +0000 (16:57 +1100)
committerChristian Brauner <brauner@kernel.org>
Sat, 8 Mar 2025 11:13:26 +0000 (12:13 +0100)
header_buf, symlink_buf and name_buf all share the same lifecycle so
needn't be allocated / freed separately. This change leads to a minor
reduction in .text size:

before:
   text    data     bss     dec     hex filename
   7914    1110       8    9032    2348 init/initramfs.o

after:
   text    data     bss     dec     hex filename
   7854    1110       8    8972    230c init/initramfs.o

A previous iteration of this patch reused a single buffer instead of
three, given that buffer use is state-sequential (GotHeader, GotName,
GotSymlink). However, the slight decrease in heap use during early boot
isn't really worth the extra review complexity.

Link: https://lore.kernel.org/all/20241107002044.16477-7-ddiss@suse.de/
Signed-off-by: David Disseldorp <ddiss@suse.de>
Link: https://lore.kernel.org/r/20250304061020.9815-6-ddiss@suse.de
Signed-off-by: Christian Brauner <brauner@kernel.org>
init/initramfs.c

index 6dd3b02c15d7ecb4ededf0ac29c7616ccd4a9d21..df75624cdefbfebbb0bd8063d294f60d32fbdaf9 100644 (file)
@@ -510,14 +510,19 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
        decompress_fn decompress;
        const char *compress_name;
        static __initdata char msg_buf[64];
+       struct {
+               char header[CPIO_HDRLEN];
+               char symlink[PATH_MAX + N_ALIGN(PATH_MAX) + 1];
+               char name[N_ALIGN(PATH_MAX)];
+       } *bufs = kmalloc(sizeof(*bufs), GFP_KERNEL);
 
-       header_buf = kmalloc(CPIO_HDRLEN, GFP_KERNEL);
-       symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
-       name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
-
-       if (!header_buf || !symlink_buf || !name_buf)
+       if (!bufs)
                panic_show_mem("can't allocate buffers");
 
+       header_buf = bufs->header;
+       symlink_buf = bufs->symlink;
+       name_buf = bufs->name;
+
        state = Start;
        this_header = 0;
        message = NULL;
@@ -560,9 +565,7 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
                len -= my_inptr;
        }
        dir_utime();
-       kfree(name_buf);
-       kfree(symlink_buf);
-       kfree(header_buf);
+       kfree(bufs);
        return message;
 }