do_fork(): RLIMIT_NPROC check

1. mcexec sets RLIMIT_NPROC to the number of mcexec threads.
2. do_fork() gets the current number of threads by calling rusage function.
3. do_fork() returns -EAGAIN when the limit is exceeded.
This commit is contained in:
Masamichi Takagi
2017-07-12 20:33:49 +09:00
parent 7d38c7c147
commit 035e7913d8
3 changed files with 28 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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");