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/bisect/bisect.go | 3 ++- pkg/instance/instance.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'pkg') diff --git a/pkg/bisect/bisect.go b/pkg/bisect/bisect.go index 28e8c56d0..d24bb8f00 100644 --- a/pkg/bisect/bisect.go +++ b/pkg/bisect/bisect.go @@ -31,6 +31,7 @@ type Config struct { Syzkaller SyzkallerConfig Repro ReproConfig Manager *mgrconfig.Config + BuildSemaphore *instance.Semaphore } type KernelConfig struct { @@ -120,7 +121,7 @@ func Run(cfg *Config) (*Result, error) { if err != nil { return nil, err } - inst, err := instance.NewEnv(cfg.Manager) + inst, err := instance.NewEnv(cfg.Manager, cfg.BuildSemaphore) if err != nil { return nil, err } 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