diff options
author | Jamie Liu <jamieliu@google.com> | 2018-10-17 15:48:55 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-10-17 15:50:02 -0700 |
commit | b2a88ff4713325fca736f6a3bf200be02d2d72a7 (patch) | |
tree | 489e54828c2bfe0bf326976920e5d5e612f877a0 /pkg/sentry/kernel/task_signals.go | |
parent | 6922eee6499212a009fdc254224f916bd1c46f29 (diff) |
Check thread group CPU timers in the CPU clock ticker.
This reduces the number of goroutines and runtime timers when
ITIMER_VIRTUAL or ITIMER_PROF are enabled, or when RLIMIT_CPU is set.
This also ensures that thread group CPU timers only advance if running
tasks are observed at the time the CPU clock advances, mostly
eliminating the possibility that a CPU timer expiration observes no
running tasks and falls back to the group leader.
PiperOrigin-RevId: 217603396
Change-Id: Ia24ce934d5574334857d9afb5ad8ca0b6a6e65f4
Diffstat (limited to 'pkg/sentry/kernel/task_signals.go')
-rw-r--r-- | pkg/sentry/kernel/task_signals.go | 66 |
1 files changed, 0 insertions, 66 deletions
diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index afb010f60..e2925a708 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -359,72 +359,6 @@ func (tg *ThreadGroup) SendSignal(info *arch.SignalInfo) error { return tg.leader.sendSignalLocked(info, true /* group */) } -// Preconditions: The TaskSet mutex must be locked. -func (t *Task) onCPULocked(includeSys bool) bool { - // Task is exiting. - if t.exitState != TaskExitNone { - return false - } - - switch t.TaskGoroutineSchedInfo().State { - case TaskGoroutineRunningSys: - return includeSys - case TaskGoroutineRunningApp: - return true - default: - return false - } -} - -// SendTimerSignal mimics the process timer signal delivery behavior in linux: -// signals are delivered to the thread that triggers the timer expiration (see -// kernel/time/posix-cpu-timers.c:check_process_timers(). This -// means -// 1) the thread is running on cpu at the time. -// 2) a thread runs more frequently will get more of those signals. -// -// We approximate this behavior by selecting a running task in a round-robin -// fashion. Statistically, a thread running more often should have a higher -// probability to be selected. -func (tg *ThreadGroup) SendTimerSignal(info *arch.SignalInfo, includeSys bool) error { - tg.pidns.owner.mu.RLock() - defer tg.pidns.owner.mu.RUnlock() - tg.signalHandlers.mu.Lock() - defer tg.signalHandlers.mu.Unlock() - - // Find the next running threads. - var t *Task - if tg.lastTimerSignalTask == nil { - t = tg.tasks.Front() - } else { - t = tg.lastTimerSignalTask.Next() - } - - // Iterate from lastTimerSignalTask.Next() to the last task in the task list. - for t != nil { - if t.onCPULocked(includeSys) { - tg.lastTimerSignalTask = t - return t.sendSignalLocked(info, true /* group */) - } - t = t.Next() - } - - // t is nil when we reach here. If lastTimerSignalTask is not nil, iterate - // from Front to lastTimerSignalTask. - if tg.lastTimerSignalTask != nil { - for t := tg.tasks.Front(); t != tg.lastTimerSignalTask.Next(); t = t.Next() { - if t.onCPULocked(includeSys) { - tg.lastTimerSignalTask = t - return t.sendSignalLocked(info, true /* group */) - } - } - } - - // No running threads? Just try the leader. - tg.lastTimerSignalTask = tg.leader - return tg.leader.sendSignalLocked(info, true /* group */) -} - func (t *Task) sendSignalLocked(info *arch.SignalInfo, group bool) error { return t.sendSignalTimerLocked(info, group, nil) } |