PERF-AMD-IBS(1)
π perf-amd-ibs β from the perf Manual (section 1)
okay so bestie, gather round, because this one is genuinely one of my faves: this is the perf-amd-ibs page, and it's all about Support for AMD Instruction-Based Sampling (IBS) with perf tool. yes that's the NAME section, and yes it ate. π
β¨ SYNOPSIS β¨
perf record -e ibs_op//
perf record -e ibs_fetch//
that's it. that's the whole vibe. two lines. iconic. π¦
πΈ DESCRIPTION πΈ
okay so Instruction-Based Sampling (IBS) is the thing that gives you precise Instruction Pointer (IP) profiling support on AMD platforms. no cap. π₯
IBS has two independent components: IBS Op and IBS Fetch.
- IBS Op sampling hands you info about instruction execution (micro-op execution, to be precise π ) with the deets like d-cache hit/miss, d-TLB hit/miss, cache miss latency, load/store data source, branch behavior, etc.
- IBS Fetch sampling hands you info about instruction fetch, with deets like i-cache hit/miss, i-TLB hit/miss, fetch latency, etc.
and IBS is per-smt-thread, meaning each SMT hardware thread contains its own standalone IBS units. independent queens. π
Both IBS Op and IBS Fetch are exposed as PMUs by Linux and can be exploited using the Linux perf utility. these files get created at boot time if IBS is supported by the hardware and the kernel:
/sys/bus/event_source/devices/ibs_op/
/sys/bus/event_source/devices/ibs_fetch/
so like, what events do they have:
- IBS Op PMU supports two events:
cyclesandmicro ops. - IBS Fetch PMU supports one event:
fetch ops.
π«Ά real talk though: IBS PMUs do not have user/kernel filtering capability, and thus it requiresCAP_SYS_ADMINorCAP_PERFMONprivilege. so like, bestie, you need the permissions. periodt.
β IBS VS. REGULAR CORE PMU β
so the whole point of IBS: it gives samples with precise IP. meaning the IP recorded with an IBS sample has no skid. β¨
whereas the IP recorded by a regular core PMU will have some skid β the sample was generated at IP X but perf would record it at IP X+n. π so yeah, a regular core PMU might not help you when you're profiling with instruction level precision. further, IBS provides additional information about the sample in question.
on the other hand (and we're being fair here, we love everyone), a regular core PMU has its own advantages:
- plethora of events
- counting mode (less interference)
- up to 6 parallel counters
- event grouping support
- filtering capabilities
- etc.
and this part is so useful β three regular core PMU events are internally forwarded to IBS Op PMU when precise_ip attribute is set:
-e cpu-cycles:p becomes -e ibs_op//
-e r076:p becomes -e ibs_op//
-e r0C1:p becomes -e ibs_op/cnt_ctl=1/
like, it just does that. slay. π
π₯ EXAMPLES π₯
π§ IBS Op PMU
System-wide profile, cycles event, sampling period: 100000
# perf record -e ibs_op// -c 100000 -a
Per-cpu profile (cpu10), cycles event, sampling period: 100000
# perf record -e ibs_op// -c 100000 -C 10
Userspace only, per-cpu profile (cpu10), cycles event, sampling period: 100000
Zen6 onward (See NOTES):
# perf record -e ibs_op//u -c 100000 -C 10
Until Zen5:
# perf record -e ibs_op/swfilt=1/u -c 100000 -C 10
Per-cpu profile (cpu10), cycles event, sampling freq: 1000
# perf record -e ibs_op// -F 1000 -C 10
System-wide profile, uOps event, sampling period: 100000
# perf record -e ibs_op/cnt_ctl=1/ -c 100000 -a
Same command, but also capture IBS register raw dump along with perf sample
# perf record -e ibs_op/cnt_ctl=1/ -c 100000 -a --raw-samples
System-wide profile, uOps event, sampling period: 100000, L3MissOnly (Zen4 onward)
# perf record -e ibs_op/cnt_ctl=1,l3missonly=1/ -c 100000 -a
System-wide profile, cycles event, sampling period: 100000, LdLat filtering (Zen5 onward)
# perf record -e ibs_op/ldlat=128/ -c 100000 -a
β¨ Supported load latency threshold values are 128 to 2048 (both inclusive). a latency value which is a multiple of 128 incurs a little less profiling overhead compared to other values. noted, bestie. π
System-wide profile, cycles event, sampling period: 100000, streaming store filter (Zen6 onward)
# perf record -e ibs_op/strmst=1/ -c 100000 -a
Per process(upstream v6.2 onward), uOps event, sampling period: 100000
# perf record -e ibs_op/cnt_ctl=1/ -c 100000 -p 1234
Per process(upstream v6.2 onward), uOps event, sampling period: 100000
# perf record -e ibs_op/cnt_ctl=1/ -c 100000 -- ls
(yes the man page lists these two with the same one-liner. we don't edit the source, we just vibe with it π)
To analyse recorded profile in aggregate mode
# perf report
/* Select a line and press 'a' to drill down at instruction level. */
press a to drill down at instruction level. that's the good stuff. π«Ά
To go over each sample
# perf script
Raw dump of IBS registers when profiled with --raw-samples
# perf report -D
/* Look for PERF_RECORD_SAMPLE */
Example register raw dump:
ibs_op_ctl: 000002c30006186a MaxCnt 100000 L3MissOnly 0 En 1
Val 1 CntCtl 0=cycles CurCnt 707
IbsOpRip: ffffffff8204aea7
ibs_op_data: 0000010002550001 CompToRetCtr 1 TagToRetCtr 597
BrnRet 0 RipInvalid 0 BrnFuse 0 Microcode 1
ibs_op_data2: 0000000000000013 RmtNode 1 DataSrc 3=DRAM
ibs_op_data3: 0000000031960092 LdOp 0 StOp 1 DcL1TlbMiss 0
DcL2TlbMiss 0 DcL1TlbHit2M 1 DcL1TlbHit1G 0 DcL2TlbHit2M 0
DcMiss 1 DcMisAcc 0 DcWcMemAcc 0 DcUcMemAcc 0 DcLockedOp 0
DcMissNoMabAlloc 0 DcLinAddrValid 1 DcPhyAddrValid 1
DcL2TlbHit1G 0 L2Miss 1 SwPf 0 OpMemWidth 32 bytes
OpDcMissOpenMemReqs 12 DcMissLat 0 TlbRefillLat 0
IbsDCLinAd: ff110008a5398920
IbsDCPhysAd: 00000008a5398920
look at all those fields. highkey beautiful. π
IBS applied in a real world usecase
okay this story is so good: ~90% regression was observed in tbench with specific scheduler hint which was counter intuitive. the IBS profile of a good run and a bad run, captured using perf, helped in identifying the exact cause of the problem:
https://lore.kernel.org/r/20220921063638.2489-1-kprateek.nayak@amd.com
perf said "here's your problem" and the problem was found. main character energy. π
π IBS Fetch PMU
similar commands can be used with the Fetch PMU as well. π
System-wide profile, fetch ops event, sampling period: 100000
# perf record -e ibs_fetch// -c 100000 -a
Userspace only, system-wide profile, fetch ops event, sampling period: 100000
Zen6 onward (See NOTES):
# perf record -e ibs_fetch//u -c 100000 -a
Until Zen5:
# perf record -e ibs_fetch/swfilt=1/u -c 100000 -a
System-wide profile, fetch ops event, sampling period: 100000, Random enable
# perf record -e ibs_fetch/rand_en=1/ -c 100000 -a
π¦ random enable adds a small degree of variability to the sample period. this helps in cases like long running loops where the PMU is tagging the same instruction over and over because of a fixed sample period. literally the fix for "why am i seeing the same instruction 8000 times". π
System-wide profile, fetch ops event, sampling period: 10000, fetch latency filter (Zen6 onward)
# perf record -e ibs_fetch/fetchlat=128/ -c 10000 -a
β¨ Supported fetch latency threshold values are 128 to 1920 (both inclusive). a latency value which is a multiple of 128 incurs a little less profiling overhead compared to other values.
etc. π
π PERF MEM AND PERF C2C π
okay so perf mem is a memory access profiler tool and perf c2c is a shared data cacheline analyser tool. both of them internally use the IBS Op PMU on AMD. π€
below is a simple example of the perf mem tool:
# perf mem record -c 100000 -- make
# perf mem report
a normal perf mem report output will provide a detailed memory access profile. new output fields will show related access info together. for example:
# perf mem report -F overhead,cache,snoop,comm
...
# Samples: 92K of event 'ibs_op//'
# Total weight : 531104
#
# ---------- Cache ----------- --- Snoop ----
# Overhead L1 L2 L1-buf Other HitM Other Command
# ........ ............................ .............. ..........
#
76.07% 5.8% 35.7% 0.0% 34.6% 23.3% 52.8% cc1
5.79% 0.2% 0.0% 0.0% 5.6% 0.1% 5.7% make
5.78% 0.1% 4.4% 0.0% 1.2% 0.5% 5.3% gcc
5.33% 0.3% 3.9% 0.0% 1.1% 0.2% 5.2% as
5.00% 0.1% 3.8% 0.0% 1.0% 0.3% 4.7% sh
1.56% 0.1% 0.1% 0.0% 1.4% 0.6% 0.9% ld
0.28% 0.1% 0.0% 0.0% 0.2% 0.1% 0.2% pkg-config
0.09% 0.0% 0.0% 0.0% 0.1% 0.0% 0.1% git
0.03% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% rm
...
also, it can be aggregated based on various memory access info using the sort keys. for example:
# perf mem report -s mem,snoop
...
# Samples: 92K of event 'ibs_op//'
# Total weight : 531104
# Sort order : mem,snoop
#
# Overhead Samples Memory access Snoop
# ........ ............ ....................................... ............
#
47.99% 1509 L2 hit N/A
25.08% 338 core, same node Any cache hit HitM
10.24% 54374 N/A N/A
6.77% 35938 L1 hit N/A
6.39% 101 core, same node Any cache hit N/A
3.50% 69 RAM hit N/A
0.03% 158 LFB/MAB hit N/A
0.00% 2 Uncached hit N/A
please refer to their man page for more detail. π«Ά
π NOTES π
π okay so this part matters, pay attention bestie:
Hardware privilege filtering uses bit 63 to distinguish between kernel and userspace addresses. Hardware privilege filtering is not supported on 32-bit systems. Also, the bit 63 convention is not universal and can fail in specific environments, such as:
- using 64-bit host IBS to profile a 32-bit guest
- using 64-bit host IBS to profile non-Linux 64-bit guests that do not adhere to the bit 63 privilege standard
- etc.
like, it's giving "works on my machine" and we are aware. π
π SEE ALSO π
and that's the page!! this lovely little writeup is perf manual material, dated 10/31/2026 π β go profile something and text me the results, bestie πβ¨π¦
π¦ where this page comes from
- arch rolling: perf 7.3.1-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms