From nobody Mon Jun 8 05:26:09 2026 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C198A3F4832 for ; Fri, 5 Jun 2026 13:06:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780664784; cv=none; b=GBwn1Upymv9BfHo9e8TaE0zSd1Sy+ZJGLe/4LVvXR+7pF221mktD1AYPD6LkuSdAMVavvMNDM4iUYq3v8xhWf/YtSI273No4FPjGJwY6FVZuVwl+hcbGsgCUpCR+TkLW/f4IqKIUshQiwIRkK+V47xyRBQs8Z3R+yJtpnoAHN9o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780664784; c=relaxed/simple; bh=V1KPIqz+cAv/hDDxeMaj4eYYqkV7BU1cT6Za+pvDzUw=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=W/ZG0qKq1Wgvk3PXcCxUthQx/4rDGSsChycM94963vRPtVgwWW7gycOaVlVuIHtZxBVYa13QJWSx8mPRP1etEPzIDjL5pWc+CRVhlIunFreQ8Ej7U42NueAfOzIdPJQKv76EcoPyq6+o9r4qljnAh3eL/d1V3XhKL+3uXHE7DJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mayamatuszczyk.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=IxGw24H/; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mayamatuszczyk.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="IxGw24H/" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-bed2dca324fso196567666b.3 for ; Fri, 05 Jun 2026 06:06:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780664781; x=1781269581; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=lNb5wVpo/bFV/HKibQ5BVngRtUeTJAYuMZQhxMplvwI=; b=IxGw24H/oNZuJ9NvSJ5zLe1tCzw/HM48x7N3JTN4+WfVOJSgp+PhNHBMgqRC/ryTEF h/JolJ1BpIbOtz3o3ueLCRXgp/ZPojsrwYwHTMwmA2sqhoCuFQz9iAO6SrOpDQlhIaN1 J35ccmKXb9yeQshI7W0WM79ADNrG7ZVfGZdA0xNeTVwICEQJ3T/X4Z5ogONPgdJfEb0r Siik+e5F0qSmYkhEbWPvXouREWCcrpGPV8ULnnge+ZeCVL2q1BnkunEFQKgNZKRRkn3w YWOpvymmQamMMlC18hIxJpHkX9+7fOHQ1ClJ+xVIjQx2RRiCiM9Bhudi7Rz6SrZ3sJSQ VMng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780664781; x=1781269581; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=lNb5wVpo/bFV/HKibQ5BVngRtUeTJAYuMZQhxMplvwI=; b=BgjbOb/e/dmC8UBe4rrBZBjRr0DGz0zlsfjlCf3BkaQN4D3T9y3yJS6mAkYsnlxQvT 6npz8SmGOQaOFX1oVJpJ9z4q0qHirYmk0uhLrK0eLSP9scmes1kZ6NmGBjgtY/EkKIsU OaTVs5rGE/zugF+MOWrNq5knov3rC/RLbFC3wya9YtiZLA/0dQP6vvS9i8NC4wQH7/jG RSzyiLF3qItp7hOrONpmYggU+th8WzG8oSMNnTP3u4+OuUztT+3jUiCcNnNUTonOfzOD nLDGDh0EqbEY9tvBqz4Zw1Sk9SuVL6r4tRJhADXurU3XPezdPBzaQbASMmsYv6dvDzhU /psA== X-Forwarded-Encrypted: i=1; AFNElJ+xjMGZFwi94xUzkWHgC6p4ir4u/50HNli532rE3Qdl0+iLuaczpHlEAh7mlohRBvGitbR3KnsPnBoKPC0=@vger.kernel.org X-Gm-Message-State: AOJu0YwFdwG2wPEjKSvb+hnBDBvZm/tqJvi9WNjzHZSJ/9xaywQlzB7T hqyEfLA8TnjcUASRdATAsCeK4z+yIUythsl7xN3xL+jN09vtKcIbu8xExUe6RlNIvR+mPUo5XuE JOqLKKhhN9em7Hcdn4LTaaD0tBnwzjBahq/EOhw== X-Received: from edpd18.prod.google.com ([2002:aa7:c1d2:0:b0:67b:b3e7:d6a8]) (user=mayamatuszczyk job=prod-delivery.src-stubby-dispatcher) by 2002:a17:906:4fcd:b0:bda:e47:70c7 with SMTP id a640c23a62f3a-bf37018943dmr167456666b.12.1780664773844; Fri, 05 Jun 2026 06:06:13 -0700 (PDT) Date: Fri, 5 Jun 2026 13:06:01 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.54.0.1032.g2f8565e1d1-goog Message-ID: <20260605130601.2699172-1-mayamatuszczyk@google.com> Subject: [PATCH bpf-next v2] selftests/bpf: Run test_perf_branches more than 1 time From: Maya Matuszczyk To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman Cc: Matt Bobrowski , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Maya Matuszczyk Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" test_perf_branches bpf program was only being ran once, and perf_branches test would fail if the only sample that was passed to test_perf_branches didn't have branch data. Fix those failures by running it a few more times and waiting until a valid sample shows up, and leave the perf event only enabled for the duration of test spins. Signed-off-by: Maya Matuszczyk Acked-by: Mykyta Yatsenko --- Changes from v1: - Switched from CHECK to ASSERT_OK (Alexei Starovoitov) - bpf -> bpf-next v1: https://lore.kernel.org/bpf/20260408095710.4090495-1-mayamatuszczyk@goo= gle.com/ --- .../selftests/bpf/prog_tests/perf_branches.c | 57 +++++++++++++------ .../selftests/bpf/progs/test_perf_branches.c | 11 ++-- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools= /testing/selftests/bpf/prog_tests/perf_branches.c index 0a7ef770c487..153afcdc082e 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c @@ -15,10 +15,6 @@ static void check_good_sample(struct test_perf_branches = *skel) int pbe_size =3D sizeof(struct perf_branch_entry); int duration =3D 0; =20 - if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", - "checked sample validity before prog run")) - return; - if (CHECK(!skel->bss->valid, "output not valid", "no valid sample from prog")) return; @@ -49,10 +45,6 @@ static void check_bad_sample(struct test_perf_branches *= skel) int written_stack =3D skel->bss->written_stack_out; int duration =3D 0; =20 - if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", - "checked sample validity before prog run")) - return; - if (CHECK(!skel->bss->valid, "output not valid", "no valid sample from prog")) return; @@ -73,7 +65,6 @@ static void test_perf_branches_common(int perf_fd, bool detached =3D false; struct bpf_link *link; volatile int j =3D 0; - cpu_set_t cpu_set; =20 skel =3D test_perf_branches__open_and_load(); if (CHECK(!skel, "test_perf_branches_load", @@ -85,19 +76,35 @@ static void test_perf_branches_common(int perf_fd, if (!ASSERT_OK_PTR(link, "attach_perf_event")) goto out_destroy_skel; =20 - /* generate some branches on cpu 0 */ - CPU_ZERO(&cpu_set); - CPU_SET(0, &cpu_set); - err =3D pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); - if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + err =3D ioctl(perf_fd, PERF_EVENT_IOC_RESET, 0); + if (!ASSERT_OK(err, "ioctl(PERF_EVENT_IOC_RESET)")) goto out_destroy; =20 - /* Spin the loop for a while by using a high iteration count, and by - * checking whether the specific run count marker has been explicitly - * incremented at least once by the backing perf_event BPF program. + err =3D ioctl(perf_fd, PERF_EVENT_IOC_REFRESH, 10); + if (!ASSERT_OK(err, "ioctl(PERF_EVENT_IOC_REFRESH)")) + goto out_destroy; + + /* Make up a bunch of branch events until we time out or bpf prog sets a = flag + * that it caught a valid event. To be completely sure that required_size= _out, + * written_stack_out or written_global_out writes and reads won't get + * reordered by anyone in a way that would fail this test, use atomic + * operations */ - for (i =3D 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + for (i =3D 0; i < 100000000; ++i) { + /* This technically should be an atomic load with acquire + * ordering, but we don't want to clog up memory bus while + * spinning + */ + if (READ_ONCE(skel->bss->valid) > 0) + break; ++j; + } + + __atomic_thread_fence(__ATOMIC_ACQUIRE); + + err =3D ioctl(perf_fd, PERF_EVENT_IOC_DISABLE, 0); + if (!ASSERT_OK(err, "ioctl(PERF_EVENT_IOC_DISABLE)")) + goto out_destroy; =20 test_perf_branches__detach(skel); detached =3D true; @@ -121,6 +128,7 @@ static void test_perf_branches_hw(void) attr.size =3D sizeof(attr); attr.type =3D PERF_TYPE_HARDWARE; attr.config =3D PERF_COUNT_HW_CPU_CYCLES; + attr.disabled =3D 1; attr.freq =3D 1; attr.sample_freq =3D 1000; attr.sample_type =3D PERF_SAMPLE_BRANCH_STACK; @@ -162,6 +170,7 @@ static void test_perf_branches_no_hw(void) attr.size =3D sizeof(attr); attr.type =3D PERF_TYPE_SOFTWARE; attr.config =3D PERF_COUNT_SW_CPU_CLOCK; + attr.disabled =3D 1; attr.freq =3D 1; attr.sample_freq =3D 1000; pfd =3D syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOE= XEC); @@ -175,6 +184,18 @@ static void test_perf_branches_no_hw(void) =20 void test_perf_branches(void) { + int err, duration =3D 0; + cpu_set_t cpu_set; + + /* Pin ourselves to cpu0 so that all branches we generate would be + * also on cpu0 + */ + CPU_ZERO(&cpu_set); + CPU_SET(0, &cpu_set); + err =3D pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (!ASSERT_OK(err, "pthread_set_affinity")) + return; + if (test__start_subtest("perf_branches_hw")) test_perf_branches_hw(); if (test__start_subtest("perf_branches_no_hw")) diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools= /testing/selftests/bpf/progs/test_perf_branches.c index 05ac9410cd68..9806414cebc4 100644 --- a/tools/testing/selftests/bpf/progs/test_perf_branches.c +++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c @@ -8,7 +8,6 @@ #include =20 int valid =3D 0; -int run_cnt =3D 0; int required_size_out =3D 0; int written_stack_out =3D 0; int written_global_out =3D 0; @@ -25,13 +24,11 @@ int perf_branches(void *ctx) __u64 entries[4 * 3] =3D {0}; int required_size, written_stack, written_global; =20 - ++run_cnt; - /* write to stack */ written_stack =3D bpf_read_branch_records(ctx, entries, sizeof(entries), = 0); /* ignore spurious events */ if (!written_stack) - return 1; + return 0; =20 /* get required size */ required_size =3D bpf_read_branch_records(ctx, NULL, 0, @@ -40,14 +37,14 @@ int perf_branches(void *ctx) written_global =3D bpf_read_branch_records(ctx, fpbe, sizeof(fpbe), 0); /* ignore spurious events */ if (!written_global) - return 1; + return 0; =20 required_size_out =3D required_size; written_stack_out =3D written_stack; written_global_out =3D written_global; - valid =3D 1; + __atomic_add_fetch(&valid, 1, __ATOMIC_RELEASE); =20 - return 0; + return 1; } =20 char _license[] SEC("license") =3D "GPL"; --=20 2.54.0.1032.g2f8565e1d1-goog