From dc183990ca1a092aef786742699a718eefe53d88 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 30 Sep 2002 21:13:54 +0000 Subject: [PATCH] - Add a new per-process flag PS_XCPU to indicate that at least one thread has exceeded its CPU time limit. - In mi_switch(), set PS_XCPU when the CPU time limit is exceeded. - Perform actual CPU time limit exceeded work in ast() when PS_XCPU is set. Requested by: many --- sys/kern/kern_synch.c | 30 ++---------------------------- sys/kern/subr_trap.c | 14 ++++++++++++++ sys/sys/proc.h | 1 + 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 445936bedb09..6b37181f5cc0 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -753,9 +753,6 @@ mi_switch(void) struct thread *td = curthread; /* XXX */ struct proc *p = td->td_proc; /* XXX */ struct kse *ke = td->td_kse; -#if 0 - register struct rlimit *rlim; -#endif u_int sched_nest; mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); @@ -788,36 +785,13 @@ mi_switch(void) } #endif -#if 0 /* * Check if the process exceeds its cpu resource allocation. - * If over max, kill it. - * - * XXX drop sched_lock, pickup Giant */ if (p->p_state != PRS_ZOMBIE && p->p_limit->p_cpulimit != RLIM_INFINITY && - p->p_runtime > p->p_limit->p_cpulimit) { - rlim = &p->p_rlimit[RLIMIT_CPU]; - if (p->p_runtime / (rlim_t)1000000 >= rlim->rlim_max) { - mtx_unlock_spin(&sched_lock); - PROC_LOCK(p); - killproc(p, "exceeded maximum CPU limit"); - mtx_lock_spin(&sched_lock); - PROC_UNLOCK(p); - } else { - mtx_unlock_spin(&sched_lock); - PROC_LOCK(p); - psignal(p, SIGXCPU); - mtx_lock_spin(&sched_lock); - PROC_UNLOCK(p); - if (rlim->rlim_cur < rlim->rlim_max) { - /* XXX: we should make a private copy */ - rlim->rlim_cur += 5; - } - } - } -#endif + p->p_runtime.sec > p->p_limit->p_cpulimit) + p->p_sflag |= PS_XCPU; /* * Finish up stats for outgoing thread. diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 0a165e9ee1bb..3220732dd076 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -153,6 +153,7 @@ ast(struct trapframe *framep) struct proc *p = td->td_proc; struct kse *ke; struct ksegrp *kg = td->td_ksegrp; + struct rlimit *rlim; u_int prticks, sticks; int sflag; int flags; @@ -224,6 +225,19 @@ ast(struct trapframe *framep) psignal(p, SIGPROF); PROC_UNLOCK(p); } + if (sflag & PS_XCPU) { + PROC_LOCK(p); + rlim = &p->p_rlimit[RLIMIT_CPU]; + if (p->p_runtime.sec >= rlim->rlim_max) + killproc(p, "exceeded maximum CPU limit"); + else { + psignal(p, SIGXCPU); + if (rlim->rlim_cur < rlim->rlim_max) + /* XXX: we should make a private copy */ + rlim->rlim_cur += 5; + } + PROC_UNLOCK(p); + } if (flags & KEF_NEEDRESCHED) { mtx_lock_spin(&sched_lock); td->td_priority = kg->kg_user_pri; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 12ae34e05ac4..707baa4fe0b5 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -630,6 +630,7 @@ struct proc { /* These flags are kept in p_sflag and are protected with sched_lock. */ #define PS_INMEM 0x00001 /* Loaded into memory. */ +#define PS_XCPU 0x00002 /* Exceeded CPU limit. */ #define PS_PROFIL 0x00004 /* Has started profiling. */ #define PS_ALRMPEND 0x00020 /* Pending SIGVTALRM needs to be posted. */ #define PS_PROFPEND 0x00040 /* Pending SIGPROF needs to be posted. */