wok rev 3879

linux: free initrd cpio data earlier
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Aug 10 23:39:19 2009 +0200 (2009-08-10)
parents d7465f7f9abb
children 40b5fcaccebd
files linux/receipt linux/stuff/linux-freeinitrd-2.6.30.4.u
line diff
     1.1 --- a/linux/receipt	Mon Aug 10 12:33:20 2009 +0000
     1.2 +++ b/linux/receipt	Mon Aug 10 23:39:19 2009 +0200
     1.3 @@ -34,6 +34,7 @@
     1.4  	done <<EOT
     1.5  $PACKAGE-utf8-$VERSION.u
     1.6  $PACKAGE-diff-$VERSION.u
     1.7 +$PACKAGE-freeinitrd-$VERSION.u
     1.8  EOT
     1.9  	make mrproper
    1.10  	cp ../stuff/$PACKAGE-$VERSION-slitaz.config .config
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linux/stuff/linux-freeinitrd-2.6.30.4.u	Mon Aug 10 23:39:19 2009 +0200
     2.3 @@ -0,0 +1,143 @@
     2.4 +--- linux-2.6.30.4/arch/x86/mm/init.c
     2.5 ++++ linux-2.6.30.4/arch/x86/mm/init.c
     2.6 +@@ -381,7 +381,7 @@
     2.7 + 	 */
     2.8 + 	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
     2.9 + 
    2.10 +-	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
    2.11 ++	if (what) printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
    2.12 + 
    2.13 + 	for (; addr < end; addr += PAGE_SIZE) {
    2.14 + 		ClearPageReserved(virt_to_page(addr));
    2.15 +
    2.16 +--- linux-2.6.30.4/init/initramfs.c
    2.17 ++++ linux-2.6.30.4/init/initramfs.c
    2.18 +@@ -374,6 +374,47 @@
    2.19 + 	[Reset]		= do_reset,
    2.20 + };
    2.21 + 
    2.22 ++#include <linux/initrd.h>
    2.23 ++#define INITRD_PAGE ((PAGE_SIZE > 1024*1024) ? PAGE_SIZE : 1024*1024)
    2.24 ++
    2.25 ++static void free_rootfs_mem(unsigned long start, unsigned long end)
    2.26 ++{
    2.27 ++	free_init_pages(NULL, start, end);
    2.28 ++}
    2.29 ++
    2.30 ++static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end, 
    2.31 ++			 void (*free_initrd_mem)(unsigned long, unsigned long));
    2.32 ++
    2.33 ++static struct {
    2.34 ++	int offset, last, inptr;
    2.35 ++	char *max;
    2.36 ++} fill;
    2.37 ++
    2.38 ++static void release_inbuf(void)
    2.39 ++{
    2.40 ++	if (fill.offset >= INITRD_PAGE) {
    2.41 ++		unsigned rem = fill.offset % INITRD_PAGE;
    2.42 ++		unsigned end = initrd_start + fill.offset - rem;
    2.43 ++		_free_initrd(initrd_start, end, free_rootfs_mem);
    2.44 ++		printk(".");
    2.45 ++		initrd_start = end;
    2.46 ++		fill.offset = rem;
    2.47 ++	}
    2.48 ++}
    2.49 ++
    2.50 ++static int fill_buffer(void *buffer, unsigned size)
    2.51 ++{
    2.52 ++	int max =  fill.max - (char *) initrd_start - fill.offset;
    2.53 ++	if (max > size) max = size;
    2.54 ++	if (max > INITRD_PAGE) max = INITRD_PAGE;
    2.55 ++	memcpy(buffer, (void *)(initrd_start + fill.offset), max);
    2.56 ++	fill.offset += max;
    2.57 ++	release_inbuf();
    2.58 ++	fill.inptr += fill.last;
    2.59 ++	fill.last = max;
    2.60 ++	return max;
    2.61 ++}
    2.62 ++
    2.63 + static int __init write_buffer(char *buf, unsigned len)
    2.64 + {
    2.65 + 	count = len;
    2.66 +@@ -417,6 +458,7 @@
    2.67 + 	decompress_fn decompress;
    2.68 + 	const char *compress_name;
    2.69 + 	static __initdata char msg_buf[64];
    2.70 ++	int early_free_initrd = (buf == (char *) initrd_start);
    2.71 + 
    2.72 + 	header_buf = kmalloc(110, GFP_KERNEL);
    2.73 + 	symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
    2.74 +@@ -430,8 +472,31 @@
    2.75 + 	message = NULL;
    2.76 + 	while (!message && len) {
    2.77 + 		loff_t saved_offset = this_header;
    2.78 ++		fill.offset = buf - (char *) initrd_start;
    2.79 ++		fill.max = buf + len;
    2.80 ++		fill.inptr = fill.last = 0;
    2.81 + 		if (*buf == '0' && !(this_header & 3)) {
    2.82 + 			state = Start;
    2.83 ++			if (early_free_initrd) {
    2.84 ++				while (len) {
    2.85 ++					unsigned n = len, tofree;
    2.86 ++					if (n > INITRD_PAGE)
    2.87 ++						n = INITRD_PAGE;
    2.88 ++					flush_buffer(buf, n);
    2.89 ++					buf += n;
    2.90 ++					len -= n;
    2.91 ++					n = buf - (char *) initrd_start;
    2.92 ++					tofree = n - (n % INITRD_PAGE);
    2.93 ++					if (!tofree)
    2.94 ++						continue;
    2.95 ++					_free_initrd(initrd_start,
    2.96 ++						     initrd_start + tofree,
    2.97 ++						     free_rootfs_mem);
    2.98 ++					initrd_start += tofree;
    2.99 ++					printk(".");
   2.100 ++				}
   2.101 ++				continue;
   2.102 ++			}
   2.103 + 			written = write_buffer(buf, len);
   2.104 + 			buf += written;
   2.105 + 			len -= written;
   2.106 +@@ -445,9 +510,15 @@
   2.107 + 		}
   2.108 + 		this_header = 0;
   2.109 + 		decompress = decompress_method(buf, len, &compress_name);
   2.110 +-		if (decompress)
   2.111 +-			decompress(buf, len, NULL, flush_buffer, NULL,
   2.112 ++		if (decompress) {
   2.113 ++			if (early_free_initrd) {
   2.114 ++				decompress(NULL, 0, fill_buffer, flush_buffer,
   2.115 ++					   NULL, &my_inptr, error);
   2.116 ++				my_inptr += fill.inptr;
   2.117 ++			}
   2.118 ++			else decompress(buf, len, NULL, flush_buffer, NULL,
   2.119 + 				   &my_inptr, error);
   2.120 ++		}
   2.121 + 		else if (compress_name) {
   2.122 + 			if (!message) {
   2.123 + 				snprintf(msg_buf, sizeof msg_buf,
   2.124 +@@ -484,7 +555,8 @@
   2.125 + #include <linux/initrd.h>
   2.126 + #include <linux/kexec.h>
   2.127 + 
   2.128 +-static void __init free_initrd(void)
   2.129 ++static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end, 
   2.130 ++			 void (*free_initrd_mem)(unsigned long, unsigned long))
   2.131 + {
   2.132 + #ifdef CONFIG_KEXEC
   2.133 + 	unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
   2.134 +@@ -512,6 +584,12 @@
   2.135 + #endif
   2.136 + 		free_initrd_mem(initrd_start, initrd_end);
   2.137 + skip:
   2.138 ++	;
   2.139 ++}
   2.140 ++
   2.141 ++static void __init free_initrd(void)
   2.142 ++{
   2.143 ++	_free_initrd(initrd_start, initrd_end, free_initrd_mem);
   2.144 + 	initrd_start = 0;
   2.145 + 	initrd_end = 0;
   2.146 + }