aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2008-07-25 04:45:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:28 -0400
commit2d6ffcca623a9a16df6cdfbe8250b7a5904a5f5e (patch)
tree70d30cb6516608e9a8a1dce60c59f3a5ff21b305 /arch/alpha
parentba92a43dbaee339cf5915ef766d3d3ffbaaf103c (diff)
inflate: refactor inflate malloc code
Inflate requires some dynamic memory allocation very early in the boot process and this is provided with a set of four functions: malloc/free/gzip_mark/gzip_release. The old inflate code used a mark/release strategy rather than implement free. This new version instead keeps a count on the number of outstanding allocations and when it hits zero, it resets the malloc arena. This allows removing all the mark and release implementations and unifying all the malloc/free implementations. The architecture-dependent code must define two addresses: - free_mem_ptr, the address of the beginning of the area in which allocations should be made - free_mem_end_ptr, the address of the end of the area in which allocations should be made. If set to 0, then no check is made on the number of allocations, it just grows as much as needed The architecture-dependent code can also provide an arch_decomp_wdog() function call. This function will be called several times during the decompression process, and allow to notify the watchdog that the system is still running. If an architecture provides such a call, then it must define ARCH_HAS_DECOMP_WDOG so that the generic inflate code calls arch_decomp_wdog(). Work initially done by Matt Mackall, updated to a recent version of the kernel and improved by me. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Cc: Matt Mackall <mpm@selenic.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Mikael Starvik <mikael.starvik@axis.com> Cc: Jesper Nilsson <jesper.nilsson@axis.com> Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> Cc: David Howells <dhowells@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Andi Kleen <andi@firstfloor.org> Cc: "H. Peter Anvin" <hpa@zytor.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Yoshinori Sato <ysato@users.sourceforge.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/boot/misc.c39
1 files changed, 2 insertions, 37 deletions
diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c
index c00646b25f6e..3047a1b3a517 100644
--- a/arch/alpha/boot/misc.c
+++ b/arch/alpha/boot/misc.c
@@ -78,8 +78,6 @@ static unsigned outcnt; /* bytes in output buffer */
78static int fill_inbuf(void); 78static int fill_inbuf(void);
79static void flush_window(void); 79static void flush_window(void);
80static void error(char *m); 80static void error(char *m);
81static void gzip_mark(void **);
82static void gzip_release(void **);
83 81
84static char *input_data; 82static char *input_data;
85static int input_data_size; 83static int input_data_size;
@@ -88,51 +86,18 @@ static uch *output_data;
88static ulg output_ptr; 86static ulg output_ptr;
89static ulg bytes_out; 87static ulg bytes_out;
90 88
91static void *malloc(int size);
92static void free(void *where);
93static void error(char *m); 89static void error(char *m);
94static void gzip_mark(void **); 90static void gzip_mark(void **);
95static void gzip_release(void **); 91static void gzip_release(void **);
96 92
97extern int end; 93extern int end;
98static ulg free_mem_ptr; 94static ulg free_mem_ptr;
99static ulg free_mem_ptr_end; 95static ulg free_mem_end_ptr;
100 96
101#define HEAP_SIZE 0x3000 97#define HEAP_SIZE 0x3000
102 98
103#include "../../../lib/inflate.c" 99#include "../../../lib/inflate.c"
104 100
105static void *malloc(int size)
106{
107 void *p;
108
109 if (size <0) error("Malloc error");
110 if (free_mem_ptr <= 0) error("Memory error");
111
112 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
113
114 p = (void *)free_mem_ptr;
115 free_mem_ptr += size;
116
117 if (free_mem_ptr >= free_mem_ptr_end)
118 error("Out of memory");
119 return p;
120}
121
122static void free(void *where)
123{ /* gzip_mark & gzip_release do the free */
124}
125
126static void gzip_mark(void **ptr)
127{
128 *ptr = (void *) free_mem_ptr;
129}
130
131static void gzip_release(void **ptr)
132{
133 free_mem_ptr = (long) *ptr;
134}
135
136/* =========================================================================== 101/* ===========================================================================
137 * Fill the input buffer. This is called only when the buffer is empty 102 * Fill the input buffer. This is called only when the buffer is empty
138 * and at least one byte is really needed. 103 * and at least one byte is really needed.
@@ -193,7 +158,7 @@ decompress_kernel(void *output_start,
193 158
194 /* FIXME FIXME FIXME */ 159 /* FIXME FIXME FIXME */
195 free_mem_ptr = (ulg)output_start + ksize; 160 free_mem_ptr = (ulg)output_start + ksize;
196 free_mem_ptr_end = (ulg)output_start + ksize + 0x200000; 161 free_mem_end_ptr = (ulg)output_start + ksize + 0x200000;
197 /* FIXME FIXME FIXME */ 162 /* FIXME FIXME FIXME */
198 163
199 /* put in temp area to reduce initial footprint */ 164 /* put in temp area to reduce initial footprint */