How to exercise the UP "flu" bug.

Romano Giannetti (romano@upco.es)
Thu, 19 Nov 1998 12:33:52 +0100


Well, I think I find when the "extremely slowdown of new processes" bug
come out. It happened to me when a
find . -type f -exec grep a_name {} \;
was running. I think the problem come out when new processes are
fork()ed too fast. Running the included program exercise the bug for me
(2.1.127 UP) every time around process number 12000. I think (I have not
waited long time, I will be trying now) that if you change NLOOP from
10 to 10000 it will not hang.

Behavior in my PC of the program.

1) Open a VC with a root shell, call it VC#1, login as root, do a
nice --19 bash
2) login as you on another VC, start X, start some program, start top,
then in an xterm run ./fast (compiled with no optimization)
3) load go to more or less 2, top shows a couple of fast running (OK).
system is perfectly responsive.
4) fast count arrive at about 12000: suddendly load goes up to 30,
every fast program running and share 100/30 % (more or less) of CPU.
"Old" programs were running OK. Alt-SysRQ-P shows an EIP in
schedule() most of the time (sometime, in user space... 081239a1 for
example).
5) Hit ctrl-c in the windows where you ran ./fast. ./fast's begin to
slowly exit, but system is doomed: every new process will run as a
fool sharing all CPU time and doing very few useful things.
6) Double check: go to the VC#1, do an "exec killall -v -KILL fast".
(without exec it doesn't work).
7) go to VC#1. Alt-SysRq-s, Alt-SysRq-u, AltSysRq-b

Here is the ./fast.c:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#define NLOOP 10

#define CHECK(r,str) \
if ( (r)==-1 ) { \
perror("f: str"); \
exit(1); \
}

void inthandle(int num) {
printf("Got signal %d: exiting\n",num);
exit(1);
}

void child() {

double f=2;
int i,j;

for(j=0; j<NLOOP; j++) {
for(i=0;i<10*NLOOP;i++) f += f/i;
usleep(5000);
}
exit(0);
}

int main() {

int j=0,l=0,dummy,pid;

signal(SIGINT,&inthandle);
signal(SIGHUP,&inthandle);
signal(SIGTERM,&inthandle);
signal(SIGUSR1,&inthandle);
signal(SIGUSR2,&inthandle);

for(;;) {
pid=fork();
CHECK(pid,fork);
j++;
l++;

if (pid==0) {
child();
} else {
if (j>30) {
wait(&dummy);
j--;
}
if ((l%100)==0) printf("processes: %d, last pid=%d\n",l,pid);
}
}

return 0;
}


-- 
Romano Giannetti, Professor  -  Univ. Pontificia Comillas (Madrid, Spain)
Electronic Engineer - phone +34 915 422 800 ext 2410  fax +34 915 596 569

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/