Linux Perf Users
 help / color / mirror / Atom feed
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 --]

           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