From: Alejandro Colomar <alx+linux-man@kernel.org>
To: Nick Krichevsky <nick@ollien.com>
Cc: linux-man@vger.kernel.org, linux-perf-users@vger.kernel.org,
Vince Weaver <vincent.weaver@maine.edu>
Subject: Re: Behavior of wakeup_events being 0 in perf_event_open(2)
Date: Mon, 9 Nov 2026 10:16:36 +0100 [thread overview]
Message-ID: <avGNA14jLDjGNw6O@debian> (raw)
In-Reply-To: <CAN8n623GU-VbFJF1O7nDWhty-dUeTdo7HwPe31m1xDbU=hQVjA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5108 bytes --]
[CC += linux-perf-users@]
Hi Nick,
> Date: 2026-11-08 21:08:44-0500
> From: Nick Krichevsky <nick@ollien.com>
>
> Hi,
>
> I was experimenting with perf_event_open(2) and caught this sentence in the
> man page.
>
> Prior to Linux 3.0, setting wakeup_events to 0 resulted in no overflow
> notifications; more recent kernels treat 0 the same as 1.
>
> I wrote a small test program (below) to test this behavior. On
> kernel 7.1.13-200.fc44.x86_64, my experience seems to contradict the man page;
> it seems that when wakeup_events is 0, it actually notifies the file descriptor
> when the ring buffer is half filled (4096 byte size buffer here, (4096 bytes /
> 2) / (8 bytes per event) = 256 events). Setting this to 1 sends a notification
> after every event.
>
> My (rough) reading of the source code supports this understanding:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/events/ring_buffer.c?id=7475ea8b58616b33c04afb976cf0fbaad9dd63fb#n322
>
> Is this a stale entry in the man page, or is my understanding of this facility
> incorrect? If it is indeed stale, perhaps this could read
I don't know; it could be stale, or it could be a misunderstanding of
the author of the text, or it could be that you're misunderstanding it. :)
The commit that added that text was:
21977c9d2ac8 (2015-01-21; "perf_event_open.2: Clarify description of overflow events")
by Vincent. I've added him to CC. Let's see if he or some maintainer
can help clarify what happened.
> Prior to Linux 3.0, setting wakeup_events to 0 resulted in no overflow
> notifications; more recent kernels generate notifications based on a default
> watermark of half the ring buffer size.
If this is true, we should clarify the exact version in which the
behavior changed.
> Test run of program:
> $ gcc main.c
> $ ./a.out 0
> wakeup_events = 0
> wakeup 1: 257 samples of 8 bytes
> wakeup 2: 256 samples of 8 bytes
> wakeup 3: 256 samples of 8 bytes
> wakeup 4: 256 samples of 8 bytes
> $ ./a.out 1
> wakeup_events = 1
> wakeup 1: 1 samples of 8 bytes
> wakeup 2: 1 samples of 8 bytes
> wakeup 3: 1 samples of 8 bytes
> wakeup 4: 1 samples of 8 bytes
>
> Program:
> #define _GNU_SOURCE
> #include <linux/perf_event.h>
> #include <poll.h>
> #include <pthread.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/ioctl.h>
> #include <sys/mman.h>
> #include <sys/syscall.h>
> #include <unistd.h>
>
> #define PAGE_SIZE 4096
>
> static void *workload(void *unused) {
> for (;;) {
> }
>
> return unused;
> }
>
> int main(int argc, char **argv) {
> unsigned wakeup_events = argc > 1 ? atoi(argv[1]) : 0;
>
> pthread_t workload_thread;
> pthread_create(&workload_thread, NULL, workload, NULL);
> // Needs glibc >= 2.42
> pid_t workload_tid = pthread_gettid_np(workload_thread);
>
> struct perf_event_attr attrs = {.size = sizeof(attrs)};
> attrs.type = PERF_TYPE_SOFTWARE;
> attrs.config = PERF_COUNT_SW_CPU_CLOCK;
> attrs.freq = 1;
> attrs.sample_freq = 49;
> attrs.disabled = 1;
> attrs.exclude_kernel = 1;
> attrs.wakeup_events = wakeup_events;
>
> int fd = syscall(SYS_perf_event_open, &attrs, workload_tid, -1, -1, 0);
> if (fd < 0) {
> perror("perf_event_open");
> return 1;
> }
>
> void *buffer =
> mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> if (buffer == MAP_FAILED) {
> perror("mmap");
> return 1;
> }
>
> struct perf_event_mmap_page *meta = buffer;
> char *data = (char *)buffer + meta->data_offset;
>
> ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
> printf("wakeup_events = %u\n", wakeup_events);
>
> for (int i = 1; i <= 4; i++) {
> struct pollfd poll_fd = {.fd = fd, .events = POLLIN};
> poll(&poll_fd, 1, -1);
>
> uint64_t head = __atomic_load_n(&meta->data_head, __ATOMIC_ACQUIRE);
> uint64_t tail = meta->data_tail;
> int sample_count = 0;
> int sample_size = 0;
>
> while (tail < head) {
> struct perf_event_header *header =
> (struct perf_event_header *)(data + tail % meta->data_size);
>
> if (header->type == PERF_RECORD_SAMPLE) {
> sample_count++;
> sample_size = header->size;
> }
>
> tail += header->size;
> }
> __atomic_store_n(&meta->data_tail, tail, __ATOMIC_RELEASE);
>
> printf(
> "wakeup %d: %d samples of %d bytes\n",
> i, sample_count, sample_size
> );
> }
>
> return 0;
> }
Thanks a lot for the program!
Have a lovely day!
Alex
>
>
>
>
> -Nick Krichevsky
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
parent reply other threads:[~2026-11-09 9:16 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <CAN8n623GU-VbFJF1O7nDWhty-dUeTdo7HwPe31m1xDbU=hQVjA@mail.gmail.com>]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=avGNA14jLDjGNw6O@debian \
--to=alx+linux-man@kernel.org \
--cc=linux-man@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=nick@ollien.com \
--cc=vincent.weaver@maine.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox