When using this program (as root):
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/types.h>
#include <sys/wait.h>
#define ITER 1000
#define FORKERS 15
#define THREADS (6000/FORKERS) // 1850 is proc max
static void fork_100_wait()
{
unsigned a, to_wait = 0;
printf("\t%d forking %d\n", THREADS, getpid());
for (a = 0; a < THREADS; a++) {
switch (fork()) {
case 0:
usleep(1000);
exit(0);
break;
case -1:
break;
default:
to_wait++;
break;
}
}
printf("\t%d forked from %d, waiting for %d\n", THREADS, getpid(),
to_wait);
for (a = 0; a < to_wait; a++)
wait(NULL);
printf("\t%d waited from %d\n", THREADS, getpid());
}
static void run_forkers()
{
pid_t forkers[FORKERS];
unsigned a;
for (a = 0; a < FORKERS; a++) {
switch ((forkers[a] = fork())) {
case 0:
fork_100_wait();
exit(0);
break;
case -1:
err(1, "DIE fork of %d'th forker", a);
break;
default:
break;
}
}
for (a = 0; a < FORKERS; a++)
waitpid(forkers[a], NULL, 0);
}
int main()
{
unsigned a;
int ret;
ret = ioperm(10, 20, 0);
if (ret < 0)
err(1, "ioperm");
for (a = 0; a < ITER; a++)
run_forkers();
return 0;
}
kmemleak reports many occurences of this leak:
unreferenced object 0xffff8805917c8000 (size 8192):
comm "fork-leak", pid 2932, jiffies
4295354292 (age 1871.028s)
hex dump (first 32 bytes):
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
backtrace:
[<
ffffffff814cfbf5>] kmemdup+0x25/0x50
[<
ffffffff8103ab43>] copy_thread_tls+0x6c3/0x9a0
[<
ffffffff81150174>] copy_process+0x1a84/0x5790
[<
ffffffff811dc375>] wake_up_new_task+0x2d5/0x6f0
[<
ffffffff8115411d>] _do_fork+0x12d/0x820
...
Due to the leakage of the memory items which should have been freed in
arch/x86/kernel/process.c:exit_thread().
Make sure the memory is freed when fork fails later in copy_process.
This is done by calling exit_thread with the thread to kill.
Signed-off-by: Jiri Slaby <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: "James E.J. Bottomley" <[email protected]>
Cc: Aurelien Jacquiot <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Chen Liqin <[email protected]>
Cc: Chris Metcalf <[email protected]>
Cc: Chris Zankel <[email protected]>
Cc: David Howells <[email protected]>
Cc: Fenghua Yu <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Guan Xuetao <[email protected]>
Cc: Haavard Skinnemoen <[email protected]>
Cc: Hans-Christian Egtvedt <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Helge Deller <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Ivan Kokshaysky <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Jeff Dike <[email protected]>
Cc: Jesper Nilsson <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Jonas Bonn <[email protected]>
Cc: Koichi Yasutake <[email protected]>
Cc: Lennox Wu <[email protected]>
Cc: Ley Foon Tan <[email protected]>
Cc: Mark Salter <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Matt Turner <[email protected]>
Cc: Max Filippov <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Mikael Starvik <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Rich Felker <[email protected]>
Cc: Richard Henderson <[email protected]>
Cc: Richard Kuo <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Russell King <[email protected]>
Cc: Steven Miao <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Vineet Gupta <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Yoshinori Sato <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>