Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 04 Aug 2005 11:23:54 +0800
From:      "Howard.Wang" <Howard@163.com>
To:        freebsd-stable@freebsd.org
Cc:        delphij@freebsd.org
Subject:   Mysterous fork related panic with RELENG_5
Message-ID:  <op.suyrp40zxvidtv@h>

next in thread | raw e-mail | index | archive | help
Hi, Guys,

Recently I have found a mysterous fork related panic with RELENG_5 which
does not affect -HEAD.

With some track down we have simplified the program to trigger the kernel
map exhausting:  The program fork(2)'s only one child, then sleep; and the
child will do the same thing, until a designated depth.  On RELENG_5, a depth
of 252 would be enough to trigger the panic within a Xeon box equipped with
3.2GB of RAM (actually 4GB, but PAE is not enabled so kernel drops part of
the memory).

We tried the same experiment on other boxes, with different CPU/Memory Type/
Memory Size/Storage Controller, and the panic can be reliabily reproduced.
However, fortunatelly, it seems that 7.0-CURRENT is not affected.

A further investigation about KVA_PAGES, and other related KMEM settings in
the kernel configuration shows that they do little about the panics.

It seems that user_ldt_alloc() in sys/i386/i386/sys_machdep.c is getting a
quickly increasing parameter of 'len', which will then translate to a failed
kmem_alloc (due to exhaustion of the kernel map), and subsequently,
a NULL pointer deference with panic "Could not copy LDT", in line 255 of
sys/i386/i386/vm_machdep.c (RELENG_5_4).


//Below is a copy of the trigger program (executed as "./chain_fork 1024 1 15")

/* chain_fork.c 1.0 by Howard. */

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
         int N,M,T;
         int pid;
         char *p;
         int j;

         if(argc!=4)
         {
                 printf("Usage: %s <number_of_proc> <memsize_per_proc> <proc_keep_alive_in_seconds>\n",argv[0]);
                 return (0);
         }

         N = atoi(argv[1]);			//How many depth.
         M = atoi(argv[2])*1024*1024;	//Size per Proc.
         T = atoi(argv[3]);			//Life per Proc.

         while(N>0)
         {
                 pid = fork();
                 if (pid != 0)
                 {
                         p = malloc(M);
                         memset(p,0,M);
                         sleep(T);
                         exit(0);
                 }
                 else
                 {
                         printf("I forked a child No.%d\n",N);
                         N--;
                 }
         }
         return (0);
}

/* end of file */


---
regards,
Howard.wang




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?op.suyrp40zxvidtv>