@@ -197,8 +197,8 @@ loop:
197
197
if ret .Repro .Report .Title == origTitle {
198
198
origTitle = "-SAME-"
199
199
}
200
- log .Logf (1 , "found repro for %q (orig title: %q), took %.2f minutes" ,
201
- ret .Repro .Report .Title , origTitle , ret .Stats .TotalTime .Minutes ())
200
+ log .Logf (1 , "found repro for %q (orig title: %q, reliability: %2.f ), took %.2f minutes" ,
201
+ ret .Repro .Report .Title , origTitle , ret .Repro . Reliability , ret . Stats .TotalTime .Minutes ())
202
202
g .Go (func () error {
203
203
runner .Run (ctx , ret .Repro )
204
204
return nil
@@ -575,12 +575,30 @@ type reproRunnerResult struct {
575
575
repro * repro.Result
576
576
}
577
577
578
+ const (
579
+ // We want to avoid false positives as much as possible, so let's use
580
+ // a stricter relibability cut-off than what's used inside pkg/repro.
581
+ reliabilityCutOff = 0.4
582
+ // 80% reliability x 3 runs is a 0.8% chance of false positives.
583
+ // 6 runs at 40% reproducibility gives a ~4% false positive chance.
584
+ reliabilityThreshold = 0.8
585
+ )
586
+
578
587
// Run executes the reproducer 3 times with slightly different options.
579
588
// The objective is to verify whether the bug triggered by the reproducer affects the base kernel.
580
589
// To avoid reporting false positives, the function does not require the kernel to crash with exactly
581
590
// the same crash title as in the original crash report. Any single crash is accepted.
582
591
// The result is sent back over the rr.done channel.
583
592
func (rr * reproRunner ) Run (ctx context.Context , r * repro.Result ) {
593
+ if r .Reliability < reliabilityCutOff {
594
+ log .Logf (1 , "%s: repro is too unreliable, skipping" , r .Report .Title )
595
+ return
596
+ }
597
+ needRuns := 3
598
+ if r .Reliability < reliabilityThreshold {
599
+ needRuns = 6
600
+ }
601
+
584
602
pool := rr .kernel .pool
585
603
cnt := int (rr .running .Add (1 ))
586
604
pool .ReserveForRun (min (cnt , pool .Total ()))
@@ -590,13 +608,13 @@ func (rr *reproRunner) Run(ctx context.Context, r *repro.Result) {
590
608
}()
591
609
592
610
ret := reproRunnerResult {origReport : r .Report , repro : r }
593
- for doneRuns := 0 ; doneRuns < 3 ; {
611
+ for doneRuns := 0 ; doneRuns < needRuns ; {
594
612
if ctx .Err () != nil {
595
613
return
596
614
}
597
615
opts := r .Opts
598
616
opts .Repeat = true
599
- if doneRuns < 2 {
617
+ if doneRuns % 3 != 2 {
600
618
// Two times out of 3, test with Threaded=true.
601
619
// The third time we leave it as it was in the reproducer (in case it was important).
602
620
opts .Threaded = true
0 commit comments