diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-01-02 17:49:22 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-01-19 11:26:54 +0100 |
| commit | 4ac68196f128fe22ddd1e5b57d021c70f19e4894 (patch) | |
| tree | 2afb6304deb57af561271568c4adf58d8ba9584a /pkg | |
| parent | 4bd62a18b32a876e5ef2b024e454ccf793849050 (diff) | |
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.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/bisect/bisect.go | 3 | ||||
| -rw-r--r-- | pkg/instance/instance.go | 52 |
2 files changed, 53 insertions, 2 deletions
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{}{} +} |
