From 4ac68196f128fe22ddd1e5b57d021c70f19e4894 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Mon, 2 Jan 2023 17:49:22 +0100 Subject: syz-ci: move build semaphore closer to builds Currently it's held during the whole job processing, which can take too long. Adjust it so that it's only taken when we really begin to build the kernel or syzkaller. --- pkg/instance/instance.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'pkg/instance/instance.go') diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index b393991d0..1a504fdd7 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -36,6 +36,7 @@ type Env interface { type env struct { cfg *mgrconfig.Config optionalFlags bool + buildSem *Semaphore } type BuildKernelConfig struct { @@ -48,7 +49,7 @@ type BuildKernelConfig struct { KernelConfig []byte } -func NewEnv(cfg *mgrconfig.Config) (Env, error) { +func NewEnv(cfg *mgrconfig.Config, buildSem *Semaphore) (Env, error) { if !vm.AllowsOvercommit(cfg.Type) { return nil, fmt.Errorf("test instances are not supported for %v VMs", cfg.Type) } @@ -67,11 +68,16 @@ func NewEnv(cfg *mgrconfig.Config) (Env, error) { env := &env{ cfg: cfg, optionalFlags: true, + buildSem: buildSem, } return env, nil } func (env *env) BuildSyzkaller(repoURL, commit string) (string, error) { + if env.buildSem != nil { + env.buildSem.Wait() + defer env.buildSem.Signal() + } cfg := env.cfg srcIndex := strings.LastIndex(cfg.Syzkaller, "/src/") if srcIndex == -1 { @@ -126,6 +132,10 @@ func (env *env) BuildSyzkaller(repoURL, commit string) (string, error) { func (env *env) BuildKernel(buildCfg *BuildKernelConfig) ( string, build.ImageDetails, error) { + if env.buildSem != nil { + env.buildSem.Wait() + defer env.buildSem.Signal() + } imageDir := filepath.Join(env.cfg.Workdir, "image") params := build.Params{ TargetOS: env.cfg.TargetOS, @@ -536,3 +546,43 @@ func RunnerCmd(prog, fwdAddr, os, arch string, poolIdx, vmIdx int, threaded, new return fmt.Sprintf("%s -addr=%s -os=%s -arch=%s -pool=%d -vm=%d "+ "-threaded=%t -new-env=%t", prog, fwdAddr, os, arch, poolIdx, vmIdx, threaded, newEnv) } + +type Semaphore struct { + ch chan struct{} +} + +func NewSemaphore(count int) *Semaphore { + s := &Semaphore{ + ch: make(chan struct{}, count), + } + for i := 0; i < count; i++ { + s.Signal() + } + return s +} + +func (s *Semaphore) Wait() { + <-s.ch +} + +func (s *Semaphore) WaitAll() { + for i := 0; i < cap(s.ch); i++ { + s.Wait() + } +} + +func (s *Semaphore) WaitC() <-chan struct{} { + return s.ch +} + +func (s *Semaphore) Available() int { + return len(s.ch) +} + +func (s *Semaphore) Signal() { + if av := s.Available(); av == cap(s.ch) { + // Not super reliable, but let it be here just in case. + panic(fmt.Sprintf("semaphore capacity (%d) is exceeded (%d)", cap(s.ch), av)) + } + s.ch <- struct{}{} +} -- cgit mrf-deployment