All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Boqun Feng <boqun.feng@gmail.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Prakash Sangappa <prakash.sangappa@oracle.com>,
	Madadi Vineeth Reddy <vineethr@linux.ibm.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Arnd Bergmann <arnd@arndb.de>,
	linux-arch@vger.kernel.org, Randy Dunlap <rdunlap@infradead.org>,
	Ron Geva <rongevarg@gmail.com>, Waiman Long <longman@redhat.com>
Subject: Re: [patch V6 07/11] rseq: Implement time slice extension enforcement timer
Date: Fri, 16 Jan 2026 19:15:24 +0100	[thread overview]
Message-ID: <20260116181524.GF831285@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20251219100517.GA1132199@noisy.programming.kicks-ass.net>

On Fri, Dec 19, 2025 at 11:05:17AM +0100, Peter Zijlstra wrote:

> I was thinking that perhaps the hrtimer tracepoints, filtered on this
> specific timer, might just do. Arming the timer is the point where the
> extension is granted, cancelling the timer is on the slice_yield() (or
> any other random syscall :/), and the timer actually firing is on fail.

Here, I google pasted this together. I don't actually speak much snake
(as you well know). Nor does it fully work; the handle_expire() thing is
busted, I definitely have expire entries in the trace, but they're not
showing up.

$ trace-cmd record -e hrtimer_start -e hrtimer_cancel -e hrtimer_expire_entry -- ./slice_test
$ ./foo.py

========================================
RSEQ SLICE HISTOGRAM (us)
========================================

Task: slice_test    Mean: 375.577 ns
  Latency (us)    | Count
  ------------------------------
  0 us            | 142031
  1 us            | 292
  2 us            | 67
  3 us            | 33
  4 us            | 34
  5 us            | 27
  6 us            | 15
  7 us            | 14
  8 us            | 24
  9 us            | 33
  10 us           | 691


---
#!/usr/bin/python3

#
# trace-cmd record -e hrtimer_start -e hrtimer_cancel -e hrtimer_expire_entry -- $cmd
#

from tracecmd import *

def load_kallsyms(file_path='/proc/kallsyms'):
    """
    Parses /proc/kallsyms into a dictionary.
    Returns: { address_int: symbol_name }
    """
    kallsyms_map = {}

    try:
        with open(file_path, 'r') as f:
            for line in f:
                # The format is: [address] [type] [name] [module]
                parts = line.split()
                if len(parts) < 3:
                    continue

                addr = int(parts[0], 16)
                name = parts[2]

                kallsyms_map[addr] = name

    except PermissionError:
        print(f"Error: Permission denied reading {file_path}. Try running with sudo.")
    except FileNotFoundError:
        print(f"Error: {file_path} not found.")

    return kallsyms_map

ksyms = load_kallsyms()

# pending[timer_ptr] = {'ts': timestamp, 'comm': comm}
pending = {}

# histograms[comm][bucket] = count
histograms = {}

class OnlineHarmonicMean:
    def __init__(self):
        self.n = 0          # Count of elements
        self.S = 0.0        # Cumulative sum of reciprocals

    def update(self, x):
        if x == 0:
            raise ValueError("Harmonic mean is undefined for zero.")

        self.n += 1
        self.S += 1.0 / x
        return self.n / self.S

    @property
    def mean(self):
        return self.n / self.S if self.n > 0 else 0

ohms = {}

def handle_start(record):
    func_name = ksyms[record.num_field("function")]
    if "rseq_slice_expired" in func_name:
        timer_ptr = record.num_field("hrtimer")
        pending[timer_ptr] = {
            'ts': record.ts,
            'comm': record.comm
        }
    return None 

def handle_cancel(record):
    timer_ptr = record.num_field("hrtimer")
    
    if timer_ptr in pending:
        start_data = pending.pop(timer_ptr)
        duration_ns = record.ts - start_data['ts']
        duration_us = duration_ns // 1000

        comm = start_data['comm']

        if comm not in ohms:
            ohms[comm] = OnlineHarmonicMean()

        ohms[comm].update(duration_ns)
        
        if comm not in histograms:
            histograms[comm] = {}
        
        histograms[comm][duration_us] = histograms[comm].get(duration_us, 0) + 1
    return None

def handle_expire(record):
    timer_ptr = record.num_field("hrtimer")

    if timer_ptr in pending:
        start_data = pending.pop(timer_ptr)
        comm = start_data['comm']
        
        if comm not in histograms:
            histograms[comm] = {}
            
        # Record -1 bucket for expired (failed to cancel)
        histograms[comm][-1] = histograms[comm].get(-1, 0) + 1
    return None

if __name__ == "__main__":
    t = Trace("trace.dat")
    for cpu in range(0, t.cpus):
        ev = t.read_event(cpu)
        while ev:
            if "hrtimer_start" in ev.name:
                handle_start(ev)
            if "hrtimer_cancel" in ev.name:
                handle_cancel(ev)
            if "hrtimer_expire_entry" in ev.name:
                handle_expire(ev)

            ev = t.read_event(cpu)

    print("\n" + "="*40)
    print("RSEQ SLICE HISTOGRAM (us)")
    print("="*40)
    for comm, buckets in histograms.items():
        print(f"\nTask: {comm}    Mean: {ohms[comm].mean:.3f} ns")
        print(f"  {'Latency (us)':<15} | {'Count'}")
        print(f"  {'-'*30}")
        # Sort buckets numerically, putting -1 at the top
        for bucket in sorted(buckets.keys()):
            label = "EXPIRED" if bucket == -1 else f"{bucket} us"
            print(f"  {label:<15} | {buckets[bucket]}")

  reply	other threads:[~2026-01-16 18:15 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-15 16:52 [patch V6 00/11] rseq: Implement time slice extension mechanism Thomas Gleixner
2025-12-15 18:24 ` Thomas Gleixner
2025-12-15 16:52 ` [patch V6 01/11] rseq: Add fields and constants for time slice extension Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 14:36   ` Mathieu Desnoyers
2025-12-18 23:21     ` Thomas Gleixner
2026-01-07 21:11       ` Mathieu Desnoyers
2026-01-11 17:11         ` Thomas Gleixner
2026-01-13 23:45           ` Florian Weimer
2026-01-14 21:59             ` Thomas Gleixner
2026-01-17 16:16             ` Mathieu Desnoyers
2026-01-19 10:21               ` Peter Zijlstra
2026-01-19 10:30                 ` Mathieu Desnoyers
2026-01-19 11:03                   ` Peter Zijlstra
2026-01-19 11:10                     ` Mathieu Desnoyers
2026-01-19 11:27                       ` Peter Zijlstra
2026-01-19 10:46                 ` Florian Weimer
2026-01-17  9:36       ` Peter Zijlstra
2026-01-19 10:10   ` Peter Zijlstra
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 02/11] rseq: Provide static branch for time slice extensions Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 03/11] rseq: Add statistics " Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 04/11] rseq: Add prctl() to enable " Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 05/11] rseq: Implement sys_rseq_slice_yield() Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 14:59   ` Mathieu Desnoyers
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 06/11] rseq: Implement syscall entry work for time slice extensions Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 15:05   ` Mathieu Desnoyers
2025-12-18 22:28     ` Thomas Gleixner
2025-12-18 22:30       ` Mathieu Desnoyers
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 07/11] rseq: Implement time slice extension enforcement timer Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16  7:18   ` Randy Dunlap
2025-12-16 17:55     ` Prakash Sangappa
2025-12-16  8:26   ` [patch V6.1 " Thomas Gleixner
2025-12-16 15:13   ` [patch V6 " Mathieu Desnoyers
2025-12-18 15:05   ` Peter Zijlstra
2025-12-18 23:26     ` Thomas Gleixner
2025-12-19 10:05       ` Peter Zijlstra
2026-01-16 18:15         ` Peter Zijlstra [this message]
2026-01-18 10:46           ` Thomas Gleixner
2026-01-19 10:01             ` Peter Zijlstra
2025-12-18 15:18   ` Peter Zijlstra
2025-12-18 23:25     ` Thomas Gleixner
2026-01-17  9:57   ` Peter Zijlstra
2026-01-23 17:38     ` Prakash Sangappa
2026-01-23 17:41     ` Prakash Sangappa
2026-01-27 18:48       ` Peter Zijlstra
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 08/11] rseq: Reset slice extension when scheduled Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 15:17   ` Mathieu Desnoyers
2026-01-22 10:16   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 09/11] rseq: Implement rseq_grant_slice_extension() Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 15:25   ` Mathieu Desnoyers
2025-12-18 23:28     ` Thomas Gleixner
2026-01-11 10:22       ` Thomas Gleixner
2026-01-22 10:15   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 10/11] entry: Hook up rseq time slice extension Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2025-12-16 15:37   ` Mathieu Desnoyers
2025-12-19 11:07     ` Peter Zijlstra
2026-01-11 11:01       ` Thomas Gleixner
2026-01-17  9:51         ` Peter Zijlstra
2026-01-22 10:15   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2025-12-15 16:52 ` [patch V6 11/11] selftests/rseq: Implement time slice extension test Thomas Gleixner
2025-12-15 18:24   ` Thomas Gleixner
2026-01-22 10:15   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner

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=20260116181524.GF831285@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=arnd@arndb.de \
    --cc=bigeasy@linutronix.de \
    --cc=boqun.feng@gmail.com \
    --cc=corbet@lwn.net \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=paulmck@kernel.org \
    --cc=prakash.sangappa@oracle.com \
    --cc=rdunlap@infradead.org \
    --cc=rongevarg@gmail.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=vineethr@linux.ibm.com \
    /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.