From 85c1c3ed4b8d32c499c53917765acef20cb16248 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Tue, 29 Dec 2020 16:21:27 -0800 Subject: Make profiling commands synchronous. This allows for a model of profiling when you can start collection, and it will terminate when the sandbox terminates. Without this synchronous call, it is effectively impossible to collect length blocking and mutex profiles. PiperOrigin-RevId: 349483418 --- runsc/boot/controller.go | 28 +++++++++++++++------------- runsc/boot/loader.go | 4 ++-- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'runsc/boot') diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 865126ac5..9008e1282 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -104,13 +104,11 @@ const ( // Profiling related commands (see pprof.go for more details). const ( - StartCPUProfile = "Profile.StartCPUProfile" - StopCPUProfile = "Profile.StopCPUProfile" - HeapProfile = "Profile.HeapProfile" - BlockProfile = "Profile.BlockProfile" - MutexProfile = "Profile.MutexProfile" - StartTrace = "Profile.StartTrace" - StopTrace = "Profile.StopTrace" + CPUProfile = "Profile.CPU" + HeapProfile = "Profile.Heap" + BlockProfile = "Profile.Block" + MutexProfile = "Profile.Mutex" + Trace = "Profile.Trace" ) // Logging related commands (see logging.go for more details). @@ -132,8 +130,13 @@ type controller struct { // manager holds the containerManager methods. manager *containerManager - // pprop holds the profile instance if enabled. It may be nil. + // pprof holds the profile instance if enabled. It may be nil. pprof *control.Profile + + // stopProfiling has the callback to stop profiling calls. As + // this may be executed only once at most, it will be set to nil + // after it is executed for the first time. + stopProfiling func() } // newController creates a new controller. The caller must call @@ -164,7 +167,7 @@ func newController(fd int, l *Loader) (*controller, error) { ctrl.srv.Register(&control.Logging{}) if l.root.conf.ProfileEnable { - ctrl.pprof = &control.Profile{Kernel: l.k} + ctrl.pprof, ctrl.stopProfiling = control.NewProfile(l.k) ctrl.srv.Register(ctrl.pprof) } @@ -172,10 +175,9 @@ func newController(fd int, l *Loader) (*controller, error) { } func (c *controller) stop() { - if c.pprof != nil { - // These are noop if there is nothing being profiled. - _ = c.pprof.StopCPUProfile(nil, nil) - _ = c.pprof.StopTrace(nil, nil) + if c.stopProfiling != nil { + c.stopProfiling() + c.stopProfiling = nil } } diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 98ea8db64..f41d6c665 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -598,7 +598,6 @@ func (l *Loader) run() error { if err != nil { return err } - } ep.tg = l.k.GlobalInit() @@ -1045,9 +1044,10 @@ func (l *Loader) WaitExit() kernel.ExitStatus { // Wait for container. l.k.WaitExited() - // Cleanup + // Stop the control server. l.ctrl.stop() + // Check all references. refs.OnExit() return l.k.GlobalInit().ExitStatus() -- cgit v1.2.3