free_initmem() bug
Geert Uytterhoeven
geert at linux-m68k.org
Thu Aug 3 06:11:05 EST 2000
free_initmem() must not be __init because that means sawing the branch
underneat itselves, which may cause a crash.
I also optimized the freeing of the various sections, both from a soure and
object view.
The patch is half tested, i.e. it compiles. Since I won't be able to do bk for
a while, can someone please take care of this? Thanks!
--- linux-2.4.0-test6-pre1/arch/ppc/mm/init.c Tue Jul 18 14:08:50 2000
+++ geert-ppc-2.4.0-test6-pre1/arch/ppc/mm/init.c Wed Aug 2 22:06:37 2000
@@ -788,76 +788,40 @@
return p;
}
-void __init free_initmem(void)
+static void free_sec(unsigned long start, unsigned long end, const char *name)
{
- unsigned long a;
- unsigned long num_freed_pages = 0, num_prep_pages = 0,
- num_pmac_pages = 0, num_openfirmware_pages = 0,
- num_apus_pages = 0, num_chrp_pages = 0;
-#define FREESEC(START,END,CNT) do { \
- a = (unsigned long)(&START); \
- for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
- clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags); \
- set_page_count(mem_map+MAP_NR(a), 1); \
- free_page(a); \
- CNT++; \
- } \
-} while (0)
+ unsigned long cnt = 0;
- FREESEC(__init_begin,__init_end,num_freed_pages);
- switch (_machine)
- {
- case _MACH_Pmac:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_chrp:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- break;
- case _MACH_prep:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_mbx:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_apus:
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_gemini:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
+ while (start < end) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ cnt++;
+ start += PAGE_SIZE;
}
+ if (cnt)
+ printk(" %ldk %s", PGTOKB(cnt), name);
+}
- if ( !have_of )
- FREESEC( __openfirmware_begin, __openfirmware_end,
- num_openfirmware_pages );
-
- printk ("Freeing unused kernel memory: %ldk init",
- PGTOKB(num_freed_pages));
+#define FREESEC(TYPE) \
+ free_sec((unsigned long)(&__ ## TYPE ## _begin), \
+ (unsigned long)(&__ ## TYPE ## _end), \
+ #TYPE);
- if ( num_prep_pages )
- printk(" %ldk prep", PGTOKB(num_prep_pages));
- if ( num_chrp_pages )
- printk(" %ldk chrp", PGTOKB(num_chrp_pages));
- if ( num_pmac_pages )
- printk(" %ldk pmac", PGTOKB(num_pmac_pages));
- if ( num_openfirmware_pages )
- printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages));
- if ( num_apus_pages )
- printk(" %ldk apus", PGTOKB(num_apus_pages));
+void free_initmem(void)
+{
+ printk ("Freeing unused kernel memory:");
+ FREESEC(init);
+ if (_machine != _MACH_Pmac)
+ FREESEC(pmac);
+ if (_machine != _MACH_chrp)
+ FREESEC(chrp);
+ if (_machine != _MACH_prep)
+ FREESEC(prep);
+ if (_machine != _MACH_apus)
+ FREESEC(apus);
+ if (!have_of)
+ FREESEC(openfirmware);
printk("\n");
}
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list