wok view linux-libre/stuff/linux-libre-freeinitrd-3.18.129-gnu.u @ rev 21825

Up lz4 (1.9.2) & zstd (1.4.3)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Sep 11 10:54:36 2019 +0200 (2019-09-11)
parents
children
line source
1 --- linux-libre-3.18.129-gnu/init/initramfs.c
2 +++ linux-libre-3.18.129-gnu/init/initramfs.c
3 @@ -409,6 +409,52 @@
4 [Reset] = do_reset,
5 };
7 +#include <linux/initrd.h>
8 +#define INITRD_PAGE ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
9 +#define INITRD_DOT (1024*1024)
10 +
11 +static void free_rootfs_mem(unsigned long start, unsigned long end)
12 +{
13 + free_init_pages(NULL, start, end);
14 +}
15 +
16 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
17 + void (*free_initrd_mem)(unsigned long, unsigned long));
18 +
19 +static struct {
20 + int offset, last, inptr, freed;
21 + char *max;
22 +} fill;
23 +
24 +static void release_inbuf(unsigned n)
25 +{
26 + if (n >= INITRD_PAGE) {
27 + unsigned rem = n % INITRD_PAGE;
28 + unsigned end = initrd_start + n - rem;
29 + _free_initrd(initrd_start, end, free_rootfs_mem);
30 + fill.freed += n - rem;
31 + if (fill.freed >= INITRD_DOT) {
32 + fill.freed -= INITRD_DOT;
33 + printk(".");
34 + }
35 + initrd_start = end;
36 + fill.offset = rem;
37 + }
38 +}
39 +
40 +static int fill_buffer(void *buffer, unsigned size)
41 +{
42 + int max = fill.max - (char *) initrd_start - fill.offset;
43 + if (max > size) max = size;
44 + if (max > INITRD_PAGE) max = INITRD_PAGE;
45 + memcpy(buffer, (void *)(initrd_start + fill.offset), max);
46 + release_inbuf(fill.offset);
47 + fill.offset += max;
48 + fill.inptr += fill.last;
49 + fill.last = max;
50 + return max;
51 +}
52 +
53 static long __init write_buffer(char *buf, unsigned long len)
54 {
55 byte_count = len;
56 @@ -452,6 +498,7 @@
57 decompress_fn decompress;
58 const char *compress_name;
59 static __initdata char msg_buf[64];
60 + int early_free_initrd = (buf == (char *) initrd_start);
62 header_buf = kmalloc(110, GFP_KERNEL);
63 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
64 @@ -465,11 +512,16 @@
65 message = NULL;
66 while (!message && len) {
67 loff_t saved_offset = this_header;
68 + fill.offset = buf - (char *) initrd_start;
69 + fill.max = buf + len;
70 + fill.inptr = fill.last = fill.freed = 0;
71 if (*buf == '0' && !(this_header & 3)) {
72 state = Start;
73 written = write_buffer(buf, len);
74 buf += written;
75 len -= written;
76 + if (early_free_initrd)
77 + release_inbuf(buf - (char *) initrd_start);
78 continue;
79 }
80 if (!*buf) {
81 @@ -482,7 +534,13 @@
82 decompress = decompress_method(buf, len, &compress_name);
83 pr_debug("Detected %s compressed data\n", compress_name);
84 if (decompress) {
85 - int res = decompress(buf, len, NULL, flush_buffer, NULL,
86 + int res;
87 + if (early_free_initrd) {
88 + res = decompress(NULL, 0, fill_buffer,
89 + flush_buffer, NULL, &my_inptr, error);
90 + my_inptr += fill.inptr;
91 + }
92 + else res = decompress(buf, len, NULL, flush_buffer, NULL,
93 &my_inptr, error);
94 if (res)
95 error("decompressor failed");
96 @@ -524,7 +582,8 @@
97 #include <linux/initrd.h>
98 #include <linux/kexec.h>
100 -static void __init free_initrd(void)
101 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
102 + void (*free_initrd_mem)(unsigned long, unsigned long))
103 {
104 #ifdef CONFIG_KEXEC
105 unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
106 @@ -552,6 +611,12 @@
107 #endif
108 free_initrd_mem(initrd_start, initrd_end);
109 skip:
110 + ;
111 +}
112 +
113 +static void __init free_initrd(void)
114 +{
115 + _free_initrd(initrd_start, initrd_end, free_initrd_mem);
116 initrd_start = 0;
117 initrd_end = 0;
118 }