All of lore.kernel.org
 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: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-09  2:08 Behavior of wakeup_events being 0 in perf_event_open(2) Nick Krichevsky
2026-11-09  9:16 ` Alejandro Colomar [this message]

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.