On Mon, 2002-01-28 at 11:53, Geert Uytterhoeven wrote: > On Mon, 28 Jan 2002, Phil Thompson wrote: > > - USER_PTRS_PER_PGD is defined as TASK_SIZE/PGDIR_SIZE. However, > > because, TASK_SIZE is actually defined as one less that the maximum task > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > size there is a rounding error that means that USER_PTRS_PER_PGD works > ^^^^ > > out at 511 rather than 512. This means that entries 511 and 1023 of > > swapper_pg_dir don't get initialised. > > > > The corresponding mips64 code has only the first call to pgd_init() and > > each implementation of pgd_init() initialises PTRS_PER_PGD entries, > > where PTRS_PER_PGD is simple defined as 1024. > > > > The attached patch applies the mips64 approach to the mips code. > > > > Should USER_PTRS_PER_PGD be defined as (TASK_SIZE/PGDIR_SIZE) + 1? > > You mean ((TASK_SIZE)+1)/PGDIR_SIZE? Or how about: #define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE + 1) The above patch fixes a rather serious memory leak. When a parent process forks a large number of children and then it exits before the children exit, we lose one page per child. I was able to narrow down the problem and reproduce it with the attached program. Ralf has the fix, but was examining related issues before applying the patch. Pete
#include <signal.h> #define NUM_TSK 200 int main() { int i, lastp; int pids[NUM_TSK]; printf("mypid %d\n", getpid()); for (i=0; i<NUM_TSK; i++) { switch (pids[i] = fork()) { case -1: printf("fork failed, lastp %d\n", lastp); goto killall; case 0: sleep(4); return 0; break; default: lastp = i; } } killall: return 0; }