summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakolb <none@none>2007-07-20 18:17:14 -0700
committerakolb <none@none>2007-07-20 18:17:14 -0700
commit8c34bbb743f69040b9eb165ea639dddb7bb91f37 (patch)
tree558520f70968f1cbbeb9f749a905ff14b3d04006
parent04513c0b3b5268af9e410449184684b2b4424829 (diff)
downloadillumos-joyent-8c34bbb743f69040b9eb165ea639dddb7bb91f37.tar.gz
6577453 Java CPU hogs can escape CPU Caps enforcement by sleeping a lot
-rw-r--r--usr/src/uts/common/disp/fss.c13
-rw-r--r--usr/src/uts/common/disp/fx.c13
-rw-r--r--usr/src/uts/common/disp/ts.c11
3 files changed, 28 insertions, 9 deletions
diff --git a/usr/src/uts/common/disp/fss.c b/usr/src/uts/common/disp/fss.c
index a409ebc800..e132ff3397 100644
--- a/usr/src/uts/common/disp/fss.c
+++ b/usr/src/uts/common/disp/fss.c
@@ -1799,6 +1799,13 @@ fss_exit(kthread_t *t)
mutex_exit(&fsspset->fssps_lock);
mutex_exit(&fsspsets_lock);
+ /*
+ * A thread could be exiting in between clock ticks, so we need to
+ * calculate how much CPU time it used since it was charged last time.
+ *
+ * CPU caps are not enforced on exiting processes - it is usually
+ * desirable to exit as soon as possible to free resources.
+ */
if (CPUCAPS_ON()) {
thread_lock(t);
fssproc = FSSPROC(t);
@@ -1993,7 +2000,7 @@ fss_preempt(kthread_t *t)
*/
if (CPUCAPS_ON()) {
(void) cpucaps_charge(t, &fssproc->fss_caps,
- CPUCAPS_CHARGE_ONLY);
+ CPUCAPS_CHARGE_ENFORCE);
if (!(fssproc->fss_flags & FSSKPRI) && CPUCAPS_ENFORCE(t))
return;
@@ -2109,7 +2116,7 @@ fss_sleep(kthread_t *t)
/*
* Account for time spent on CPU before going to sleep.
*/
- (void) CPUCAPS_CHARGE(t, &fssproc->fss_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &fssproc->fss_caps, CPUCAPS_CHARGE_ENFORCE);
fss_inactive(t);
@@ -2412,7 +2419,7 @@ fss_yield(kthread_t *t)
/*
* Collect CPU usage spent before yielding
*/
- (void) CPUCAPS_CHARGE(t, &fssproc->fss_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &fssproc->fss_caps, CPUCAPS_CHARGE_ENFORCE);
/*
* Clear the preemption control "yield" bit since the user is
diff --git a/usr/src/uts/common/disp/fx.c b/usr/src/uts/common/disp/fx.c
index 53bfb46e2a..b4899e0edf 100644
--- a/usr/src/uts/common/disp/fx.c
+++ b/usr/src/uts/common/disp/fx.c
@@ -543,6 +543,13 @@ fx_exit(kthread_t *t)
thread_lock(t);
fxpp = (fxproc_t *)(t->t_cldata);
+ /*
+ * A thread could be exiting in between clock ticks, so we need to
+ * calculate how much CPU time it used since it was charged last time.
+ *
+ * CPU caps are not enforced on exiting processes - it is usually
+ * desirable to exit as soon as possible to free resources.
+ */
(void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ONLY);
if (FX_HAS_CB(fxpp)) {
@@ -1115,7 +1122,7 @@ fx_preempt(kthread_t *t)
ASSERT(t == curthread);
ASSERT(THREAD_LOCK_HELD(curthread));
- (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ENFORCE);
/*
* Check to see if we're doing "preemption control" here. If
@@ -1209,7 +1216,7 @@ fx_sleep(kthread_t *t)
/*
* Account for time spent on CPU before going to sleep.
*/
- (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ENFORCE);
if (FX_HAS_CB(fxpp)) {
FX_CB_SLEEP(FX_CALLB(fxpp), fxpp->fx_cookie);
@@ -1428,7 +1435,7 @@ fx_yield(kthread_t *t)
/*
* Collect CPU usage spent before yielding CPU.
*/
- (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &fxpp->fx_caps, CPUCAPS_CHARGE_ENFORCE);
if (FX_HAS_CB(fxpp)) {
clock_t new_quantum = (clock_t)fxpp->fx_pquantum;
diff --git a/usr/src/uts/common/disp/ts.c b/usr/src/uts/common/disp/ts.c
index a55b890e83..e071a80ab5 100644
--- a/usr/src/uts/common/disp/ts.c
+++ b/usr/src/uts/common/disp/ts.c
@@ -1320,6 +1320,10 @@ ts_exit(kthread_t *t)
* A thread could be exiting in between clock ticks,
* so we need to calculate how much CPU time it used
* since it was charged last time.
+ *
+ * CPU caps are not enforced on exiting processes - it is
+ * usually desirable to exit as soon as possible to free
+ * resources.
*/
thread_lock(t);
tspp = (tsproc_t *)t->t_cldata;
@@ -1382,7 +1386,8 @@ ts_preempt(kthread_t *t)
* Do not enforce CPU caps on threads running at a kernel priority
*/
if (CPUCAPS_ON()) {
- (void) cpucaps_charge(t, &tspp->ts_caps, CPUCAPS_CHARGE_ONLY);
+ (void) cpucaps_charge(t, &tspp->ts_caps,
+ CPUCAPS_CHARGE_ENFORCE);
if (!(tspp->ts_flags & TSKPRI) && CPUCAPS_ENFORCE(t))
return;
}
@@ -1509,7 +1514,7 @@ ts_sleep(kthread_t *t)
/*
* Account for time spent on CPU before going to sleep.
*/
- (void) CPUCAPS_CHARGE(t, &tspp->ts_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &tspp->ts_caps, CPUCAPS_CHARGE_ENFORCE);
flags = tspp->ts_flags;
if (t->t_kpri_req) {
@@ -2026,7 +2031,7 @@ ts_yield(kthread_t *t)
/*
* Collect CPU usage spent before yielding
*/
- (void) CPUCAPS_CHARGE(t, &tspp->ts_caps, CPUCAPS_CHARGE_ONLY);
+ (void) CPUCAPS_CHARGE(t, &tspp->ts_caps, CPUCAPS_CHARGE_ENFORCE);
/*
* Clear the preemption control "yield" bit since the user is