Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/powerpc: Relax L1d miss targets for rfi_flush test

When running the rfi_flush test, if the system is loaded, we see two
issues:
1. The L1d misses when rfi_flush is disabled increase significantly due
to other workloads interfering with the cache.
2. The L1d misses when rfi_flush is enabled sometimes goes slightly
below the expected number of misses.

To address these, let's relax the expected number of L1d misses:
1. When rfi_flush is disabled, we allow upto half the expected number of
the misses for when rfi_flush is enabled.
2. When rfi_flush is enabled, we allow ~1% lower number of cache misses.

Reported-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tested-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Naveen N. Rao and committed by
Michael Ellerman
a95ecac5 3b9672ff

+13 -5
+13 -5
tools/testing/selftests/powerpc/security/rfi_flush.c
··· 49 49 struct perf_event_read v; 50 50 __u64 l1d_misses_total = 0; 51 51 unsigned long iterations = 100000, zero_size = 24 * 1024; 52 + unsigned long l1d_misses_expected; 52 53 int rfi_flush_org, rfi_flush; 53 54 54 55 SKIP_IF(geteuid() != 0); ··· 72 71 73 72 iter = repetitions; 74 73 74 + /* 75 + * We expect to see l1d miss for each cacheline access when rfi_flush 76 + * is set. Allow a small variation on this. 77 + */ 78 + l1d_misses_expected = iterations * (zero_size / CACHELINE_SIZE - 2); 79 + 75 80 again: 76 81 FAIL_IF(perf_event_reset(fd)); 77 82 ··· 85 78 86 79 FAIL_IF(read(fd, &v, sizeof(v)) != sizeof(v)); 87 80 88 - /* Expect at least zero_size/CACHELINE_SIZE misses per iteration */ 89 - if (v.l1d_misses >= (iterations * zero_size / CACHELINE_SIZE) && rfi_flush) 81 + if (rfi_flush && v.l1d_misses >= l1d_misses_expected) 90 82 passes++; 91 - else if (v.l1d_misses < iterations && !rfi_flush) 83 + else if (!rfi_flush && v.l1d_misses < (l1d_misses_expected / 2)) 92 84 passes++; 93 85 94 86 l1d_misses_total += v.l1d_misses; ··· 98 92 if (passes < repetitions) { 99 93 printf("FAIL (L1D misses with rfi_flush=%d: %llu %c %lu) [%d/%d failures]\n", 100 94 rfi_flush, l1d_misses_total, rfi_flush ? '<' : '>', 101 - rfi_flush ? (repetitions * iterations * zero_size / CACHELINE_SIZE) : iterations, 95 + rfi_flush ? repetitions * l1d_misses_expected : 96 + repetitions * l1d_misses_expected / 2, 102 97 repetitions - passes, repetitions); 103 98 rc = 1; 104 99 } else 105 100 printf("PASS (L1D misses with rfi_flush=%d: %llu %c %lu) [%d/%d pass]\n", 106 101 rfi_flush, l1d_misses_total, rfi_flush ? '>' : '<', 107 - rfi_flush ? (repetitions * iterations * zero_size / CACHELINE_SIZE) : iterations, 102 + rfi_flush ? repetitions * l1d_misses_expected : 103 + repetitions * l1d_misses_expected / 2, 108 104 passes, repetitions); 109 105 110 106 if (rfi_flush == rfi_flush_org) {