diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-01-05 13:00:52 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-01-09 11:47:02 +0000 |
| commit | 668b1c2966ea9e411e3c21a47e07eecfcc05b989 (patch) | |
| tree | 33d90f5390fc1d055f6e411cfdf9594f859d7cc8 | |
| parent | 733560f97a3f420de1ca02202227b6b3a30c7fcd (diff) | |
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.
| -rw-r--r-- | syz-fuzzer/fuzzer.go | 24 |
1 files 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) { |
