From 4e9f0e91d724b547e1ecaeeb210017f4c0b3fd0d Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Wed, 20 Jun 2018 11:01:32 -0700 Subject: sentry: pending signals S/R optimization. Almost all of the hundreds of pending signal queues are empty upon save. PiperOrigin-RevId: 201380318 Change-Id: I40747072435299de681d646e0862efac0637e172 --- pkg/sentry/kernel/BUILD | 8 +++++-- pkg/sentry/kernel/pending_signals.go | 4 ++-- pkg/sentry/kernel/pending_signals_state.go | 37 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 pkg/sentry/kernel/pending_signals_state.go diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 377c94e4c..b2a55ddff 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -13,7 +13,7 @@ go_stateify( "ipc_namespace.go", "kernel.go", "pending_signals.go", - "pending_signals_list.go", + "pending_signals_state.go", "process_group_list.go", "ptrace.go", "rseq.go", @@ -46,7 +46,10 @@ go_stateify( "version.go", ], out = "kernel_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs"], + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/arch", + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + ], package = "kernel", ) @@ -117,6 +120,7 @@ go_library( "kernel_state.go", "pending_signals.go", "pending_signals_list.go", + "pending_signals_state.go", "process_group_list.go", "ptrace.go", "rseq.go", diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index d8701f47a..5dc0f266c 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -44,11 +44,11 @@ type pendingSignals struct { // Note that signals is zero-indexed, but signal 1 is the first valid // signal, so signals[0] contains signals with signo 1 etc. This offset is // usually handled by using Signal.index(). - signals [linux.SignalMaximum]pendingSignalQueue + signals [linux.SignalMaximum]pendingSignalQueue `state:".([]*arch.SignalInfo)"` // Bit i of pendingSet is set iff there is at least one signal with signo // i+1 pending. - pendingSet linux.SignalSet + pendingSet linux.SignalSet `state:"manual"` } // pendingSignalQueue holds a pendingSignalList for a single signal number. diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go new file mode 100644 index 000000000..af61f6e8e --- /dev/null +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -0,0 +1,37 @@ +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kernel + +import ( + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" +) + +// saveSignals is invoked by stateify. +func (p *pendingSignals) saveSignals() []*arch.SignalInfo { + var pending []*arch.SignalInfo + for _, q := range p.signals { + for ps := q.pendingSignalList.Front(); ps != nil; ps = ps.Next() { + pending = append(pending, ps.SignalInfo) + } + } + return pending +} + +// loadSignals is invoked by stateify. +func (p *pendingSignals) loadSignals(pending []*arch.SignalInfo) { + for _, si := range pending { + p.enqueue(si) + } +} -- cgit v1.2.3