On Friday 04 December 2009 10:35:59 am John Baldwin wrote:
> On Thursday 03 December 2009 4:20:08 pm Hiroki Sato wrote:
> > John Baldwin <[email protected]> wrote
> > in <[email protected]>:
> >
> > jh> On Thursday 03 December 2009 5:29:13 am Hiroki Sato wrote:
> > jh> > John Baldwin <[email protected]> wrote
> > jh> > in <[email protected]>:
> > jh> >
> > jh> > jh> On Tuesday 01 December 2009 12:13:39 pm Hiroki Sato wrote:
> > jh> > jh> > While the "load" command seemed to finish, the box got stuck
> > just
> > jh> > jh> > after entering "boot" command.
> > jh> > jh> >
> > jh> > jh> > Curious to say, I have got this symptom only on a specific box
> > in
> > jh> > jh> > more than ten different boxes I upgraded so far; it is based
> > on an
> > jh> > jh> > old motherboard Supermicro P4DPE[*].
> > jh> > jh> >
> > jh> > jh> > [*]
> > jh> http://www.supermicro.com/products/motherboard/Xeon/E7500/P4DPE.cfm
> > jh> > jh> >
> > jh> > jh> > Any workaround? Booting from release CDROMs (7.2R and 8.0R)
> > also
> > jh> > jh> > fail. On the box "7.1R" or "7.1R's loader + 7.2R kernel"
> > worked
> > jh> > jh> > fine. It is possible something in changes of loader(8)
> > between 7.1R
> > jh> > jh> > and 7.2R is the cause, but I am still not sure what it is...
> > jh> > jh>
> > jh> > jh> It may be related to the loader switching to using memory > 1MB
> > for its
> > jh> > jh> malloc(). Maybe try building the loader with
> > jh> 'LOADER_NO_GPT_SUPPORT=yes' in
> > jh> > jh> /etc/src.conf?
> > jh> >
> > jh> > Thanks, a recompiled loader with LOADER_NO_GPT_SUPPORT=yes' displayed
> > jh> > "elf32_loadimage: could not read symbols - skipped!" for 8.0R kernel.
> > jh> > This is the same as 7.1R's loader + 8.0R kernel case.
> > jh>
> > jh> Can you get the output of 'smap' from the loader? Is the 8.0 kernel
> > bigger
> > jh> than the 7.x kernel? If so, can you try trimming the 8.0 kernel a bit
> > to see
> > jh> if that changes things?
> >
> > Sure. Output of smap on an 8.0R loader with LOADER_NO_GPT_SUPPORT=yes
> > was:
> >
> > | OK smap
> > | SMAP type=01 base=0000000000000000 len=000000000009f400
> > | SMAP type=02 base=000000000009f400 len=0000000000000c00
> > | SMAP type=02 base=00000000000dc000 len=0000000000024000
> > | SMAP type=01 base=0000000000100000 len=0000000000e00000
>
> So this is the region that ends up getting used for malloc:
>
> /* look for the first segment in 'extended' memory */
> if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) {
> bios_extmem = smap.length;
>
> ...
>
> /* Set memtop to actual top of memory */
> memtop = memtop_copyin = 0x100000 + bios_extmem;
>
>
> and then later:
>
> #if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) ||
> defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
> heap_top = PTOV(memtop_copyin);
> memtop_copyin -= 0x300000;
> heap_bottom = PTOV(memtop_copyin);
> #else
>
> So memtop_copyin would start off as 0xf00000 but would end up as 0xc00000,
> and since the kernel starts at 4MB, I think that only leaves about 8MB for
> the kernel. Probably the loader needs to be more intelligent about using
> high memory for malloc by using the largest region > 1MB but < 4GB for
> malloc() instead of stealing memory from bios_extmem in the SMAP case.
> Try the attached patch which tries to make the loader use better smarts
> when picking a memory region for the heap (warning, I haven't tested it
> myself yet).
Use the updated patch (actually tested in qemu) instead.
--
John Baldwin
--- //depot/vendor/freebsd/src/sys/boot/i386/libi386/biosmem.c 2007/10/28 21:26:35
+++ //depot/user/jhb/boot/sys/boot/i386/libi386/biosmem.c 2009/12/04 22:20:17
@@ -35,14 +35,20 @@
#include "libi386.h"
#include "btxv86.h"
-vm_offset_t memtop, memtop_copyin;
-u_int32_t bios_basemem, bios_extmem;
+vm_offset_t memtop, memtop_copyin, high_heap_base;
+uint32_t bios_basemem, bios_extmem, high_heap_size;
static struct bios_smap smap;
+/*
+ * The minimum amount of memory to reserve in bios_extmem for the heap.
+ */
+#define HEAP_MIN (3 * 1024 * 1024)
+
void
bios_getmem(void)
{
+ uint64_t size;
/* Parse system memory map */
v86.ebx = 0;
@@ -65,6 +71,26 @@
if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) {
bios_extmem = smap.length;
}
+
+ /*
+ * Look for the largest segment in 'extended' memory beyond
+ * 1MB but below 4GB.
+ */
+ if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) &&
+ (smap.base < 0x100000000ull)) {
+ size = smap.length;
+
+ /*
+ * If this segment crosses the 4GB boundary, truncate it.
+ */
+ if (smap.base + size > 0x100000000ull)
+ size = 0x100000000ull - smap.base;
+
+ if (size > high_heap_size) {
+ high_heap_size = size;
+ high_heap_base = smap.base;
+ }
+ }
} while (v86.ebx != 0);
/* Fall back to the old compatibility function for base memory */
@@ -97,5 +123,13 @@
/* Set memtop to actual top of memory */
memtop = memtop_copyin = 0x100000 + bios_extmem;
+ /*
+ * If we have extended memory and did not find a suitable heap
+ * region in the SMAP, use the last 3MB of 'extended' memory as a
+ * high heap candidate.
+ */
+ if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) {
+ high_heap_size = HEAP_MIN;
+ high_heap_base = memtop - HEAP_MIN;
+ }
}
-
--- //depot/vendor/freebsd/src/sys/boot/i386/libi386/libi386.h 2009/03/12 20:45:15
+++ //depot/user/jhb/boot/sys/boot/i386/libi386/libi386.h 2009/12/04 15:33:59
@@ -78,9 +78,9 @@
int bc_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
int bc_bios2unit(int biosdev); /* xlate BIOS device -> bioscd unit */
int bc_unit2bios(int unit); /* xlate bioscd unit -> BIOS device */
-u_int32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */
-int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */
-int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */
+uint32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */
+int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */
+int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */
int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len);
@@ -92,12 +92,15 @@
void bios_getsmap(void);
void bios_getmem(void);
-extern u_int32_t bios_basemem; /* base memory in bytes */
-extern u_int32_t bios_extmem; /* extended memory in bytes */
+extern uint32_t bios_basemem; /* base memory in bytes */
+extern uint32_t bios_extmem; /* extended memory in bytes */
extern vm_offset_t memtop; /* last address of physical memory + 1 */
extern vm_offset_t memtop_copyin; /* memtop less heap size for the cases */
- /* when heap is at the top of extended memory */
- /* for other cases - just the same as memtop */
+ /* when heap is at the top of */
+ /* extended memory; for other cases */
+ /* just the same as memtop */
+extern uint32_t high_heap_size; /* extended memory region available */
+extern vm_offset_t high_heap_base; /* for use as the heap */
int biospci_find_devclass(uint32_t class, int index, uint32_t *locator);
int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val);
--- //depot/vendor/freebsd/src/sys/boot/i386/loader/main.c 2009/03/09 17:20:15
+++ //depot/user/jhb/boot/sys/boot/i386/loader/main.c 2009/12/04 22:09:08
@@ -102,14 +102,19 @@
*/
bios_getmem();
-#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
- heap_top = PTOV(memtop_copyin);
- memtop_copyin -= 0x300000;
- heap_bottom = PTOV(memtop_copyin);
-#else
- heap_top = (void *)bios_basemem;
- heap_bottom = (void *)end;
+#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \
+ defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
+ if (high_heap_size > 0) {
+ heap_top = PTOV(high_heap_base + high_heap_size);
+ heap_bottom = PTOV(high_heap_base);
+ if (high_heap_base < memtop_copyin)
+ memtop_copyin = high_heap_base;
+ } else
#endif
+ {
+ heap_top = (void *)PTOV(bios_basemem);
+ heap_bottom = (void *)end;
+ }
setheap(heap_bottom, heap_top);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[email protected]"