From 668b1c2966ea9e411e3c21a47e07eecfcc05b989 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Fri, 5 Jan 2024 13:00:52 +0100 Subject: syz-fuzzer: report new inputs asynchronously On a local qemu-based instance, sendInputToManager() takes ~100-150ms, during which a proc is blocked waiting. On GCE it presumably takes even longer. Let's save this time by performing these requests in background. To control memory consumption and to adjust the execution speed in case of an overloaded syz-manager, let's limit the queue size by 3 * procs. --- syz-fuzzer/fuzzer.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index f6f3b415c..f0b6d9c23 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -28,7 +28,6 @@ import ( "github.com/google/syzkaller/prog" _ "github.com/google/syzkaller/sys" "github.com/google/syzkaller/sys/targets" - "golang.org/x/sync/semaphore" ) type Fuzzer struct { @@ -69,7 +68,7 @@ type Fuzzer struct { logMu sync.Mutex // Let's limit the number of concurrent NewInput requests. - newInputSem *semaphore.Weighted + parallelNewInputs chan struct{} } type FuzzerSnapshot struct { @@ -291,7 +290,8 @@ func main() { fetchRawCover: *flagRawCover, noMutate: r.NoMutateCalls, stats: make([]uint64, StatCount), - newInputSem: semaphore.NewWeighted(int64(2 * *flagProcs)), + // Queue no more than ~3 new inputs / proc. + parallelNewInputs: make(chan struct{}, int64(3**flagProcs)), } gateCallback := fuzzer.useBugFrames(r, *flagProcs) fuzzer.gate = ipc.NewGate(gateSize, gateCallback) @@ -454,13 +454,17 @@ func (fuzzer *Fuzzer) poll(needCandidates bool, stats map[string]uint64) bool { } func (fuzzer *Fuzzer) sendInputToManager(inp rpctype.Input) { - a := &rpctype.NewInputArgs{ - Name: fuzzer.name, - Input: inp, - } - if err := fuzzer.manager.Call("Manager.NewInput", a, nil); err != nil { - log.SyzFatalf("Manager.NewInput call failed: %v", err) - } + fuzzer.parallelNewInputs <- struct{}{} + go func() { + defer func() { <-fuzzer.parallelNewInputs }() + a := &rpctype.NewInputArgs{ + Name: fuzzer.name, + Input: inp, + } + if err := fuzzer.manager.Call("Manager.NewInput", a, nil); err != nil { + log.SyzFatalf("Manager.NewInput call failed: %v", err) + } + }() } func (fuzzer *Fuzzer) addInputFromAnotherFuzzer(inp rpctype.Input) { -- cgit mrf-deployment