diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 6b0553d5..38b7d4ad 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1956,6 +1956,10 @@ int main(int argc, char **argv) n_threads = ncpu; } + /* Quick fix for #900: Limit the number of clone() */ + desc->rlimit[MCK_RLIMIT_NPROC].rlim_cur = n_threads; + desc->rlimit[MCK_RLIMIT_NPROC].rlim_max = n_threads; + /* * XXX: keep thread_data ncpu sized despite that there are only * n_threads worker threads in the pool so that signaling code diff --git a/kernel/include/rusage.h b/kernel/include/rusage.h index e31ad1f6..c7e984fc 100644 --- a/kernel/include/rusage.h +++ b/kernel/include/rusage.h @@ -147,6 +147,12 @@ rusage_num_threads_dec() { __sync_sub_and_fetch(&monitor->rusage_num_threads, 1); } + +static inline unsigned long +rusage_num_threads_get() +{ + return monitor->rusage_num_threads; +} #else static inline void rusage_total_memory_add(unsigned long size) @@ -192,6 +198,12 @@ static inline void rusage_num_threads_dec() { } + +static inline unsigned long +rusage_num_threads_get() +{ + return -1; +} #endif // ENABLE_RUSAGE #endif diff --git a/kernel/syscall.c b/kernel/syscall.c index 7526bb48..9a0acaa9 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2124,6 +2124,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, { int cpuid; int parent_cpuid; + int nr_threads; struct thread *old = cpu_local_var(current); struct process *oldproc = old->proc; struct process *newproc; @@ -2170,6 +2171,17 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, return -EINVAL; } + /* FIXME: It is not appropriate to enforce rlimit only when rusage is enabled */ + nr_threads = rusage_num_threads_get(); + if(nr_threads != -1) { + struct rlimit *rlim; + rlim = &oldproc->rlimit[MCK_RLIMIT_NPROC]; + if (nr_threads >= rlim->rlim_cur) { + ekprintf("%s,resource limit exceeded,RLIMIT_NPROC=%d,nr_threads=%d\n", __FUNCTION__, rlim->rlim_cur, nr_threads); + return -EAGAIN; + } + } + cpuid = obtain_clone_cpuid(&old->cpu_set); if (cpuid == -1) { kprintf("do_fork,core not available\n");