You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`opts`: `perf_options` value — only `perf_type` and `perf_config` are required; all other fields have defaults, including no group (`group`invalid and `group_fd=-1`)
101
+
-`opts`: `perf_options` value — only `event` is required; all other fields have defaults, including no group (`group`defaults to an invalid attachment)
102
102
-`flags`: Must be `0` for perf attaches; nonzero values are rejected
103
103
104
104
**Return Value:**
105
105
- Standard form returns `0` on success and an error code on failure
106
-
- Perf event form returns a `PerfAttachment` value with the open counter/link identity and an internal stale-handle token
106
+
- Perf event form returns a `perf_attachment` value with the open counter/link identity and an internal stale-handle token
107
107
108
108
**Examples:**
109
109
```kernelscript
@@ -113,26 +113,25 @@ if (result != 0) {
113
113
print("Failed to attach program")
114
114
}
115
115
116
-
// Minimal perf attach — all non-perf_type/perf_config fields use defaults:
116
+
// Minimal perf attach — all non-event fields use defaults:
117
117
// pid=-1 (all procs), cpu=0, period=1_000_000, wakeup=1; perf attach flags must be 0
var cache = attach(perf_prog, perf_options { event: cache_misses }, 0)
126
126
var branch = attach(perf_prog, perf_options {
127
-
perf_type: perf_type_hardware,
128
-
perf_config: branch_misses,
127
+
event: branch_misses,
129
128
group: cache,
130
129
}, 0)
131
130
detach(branch)
132
131
detach(cache)
133
132
```
134
133
135
-
Grouped events are scheduled as one atomic PMU unit. Separate events and separate groups may be multiplexed, but members inside one group cannot be independently multiplexed. Static groups that exceed the target PMU counter limit are rejected at compile time; override the detected/default limit with `KERNELSCRIPT_PERF_GROUP_MAX_EVENTS` when compiling for a different target. The effective limit is capped at 16 to match `PerfRead`.
134
+
Grouped events are scheduled as one atomic PMU unit. Separate events and separate groups may be multiplexed, but members inside one group cannot be independently multiplexed. A group that needs more hardware PMU counters than the running host provides is rejected by the kernel at `perf_event_open(2)`, and `attach()` reports the error at runtime. `read(att)` exposes up to 16 group entries (`perf_read`).
136
135
137
136
**Context-specific implementations:**
138
137
-**eBPF:** Not available
@@ -143,14 +142,14 @@ Grouped events are scheduled as one atomic PMU unit. Separate events and separat
Copy file name to clipboardExpand all lines: README.md
+19-32Lines changed: 19 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -294,7 +294,7 @@ fn main() -> i32 {
294
294
295
295
### Hardware Performance Counter Programs
296
296
297
-
Use `@perf_event` to attach eBPF programs to hardware or software performance counters. `perf_options` keeps the kernel's tagged `perf_type + perf_config` model, so adding new perf event families does not require flattening everything into one enum. Only `perf_type` and `perf_config` are required; all other fields have sensible defaults. Perf attaches return a first-class attachment value, so if you need the current count in userspace, call `read(att).scaled`:
297
+
Use `@perf_event` to attach eBPF programs to hardware or software performance counters. Each event is named by a single `event` value that carries both the kernel`perf_event_attr.type` tag and its config, so the type can never be mismatched with the config. Only `event` is required; all other fields have sensible defaults. Perf attaches return a first-class attachment value, so if you need the current count in userspace, call `read(att).scaled`:
298
298
299
299
```kernelscript
300
300
// eBPF program fires on every hardware branch-miss sample
@@ -308,7 +308,7 @@ fn main() -> i32 {
308
308
309
309
// Minimal form — defaults: pid=-1 (all procs), cpu=0, no group,
310
310
// period=1_000_000, wakeup=1; perf attach flags must be 0
311
-
var att = attach(prog, perf_options { perf_type: perf_type_hardware, perf_config: branch_misses }, 0)
311
+
var att = attach(prog, perf_options { event: branch_misses }, 0)
312
312
var count = read(att).scaled
313
313
print("branch misses: %lld", count)
314
314
@@ -318,48 +318,35 @@ fn main() -> i32 {
318
318
}
319
319
```
320
320
321
-
Perf events can share a kernel scheduling group by passing the leader attachment directly with `group`.
322
-
The lower-level `group_fd: cache.perf_fd` form is still supported for compatibility:
321
+
Perf events can share a kernel scheduling group by passing the leader attachment with `group`:
var cache = attach(prog, perf_options { event: cache_misses }, 0)
326
325
var branch = attach(prog, perf_options {
327
-
perf_type: perf_type_hardware,
328
-
perf_config: branch_misses,
326
+
event: branch_misses,
329
327
group: cache,
330
328
}, 0)
331
329
```
332
330
333
-
Adding a member restarts the whole group from zero. Detaching a leader cascades to any live members. A group competes for PMU counters as one atomic unit: different groups can be multiplexed over time, but members inside one group are not independently multiplexed. For statically visible groups, the compiler rejects groups that need more PMU counter slots than the target limit. The limit is read from known sysfs PMU caps when available, defaults to 4, can be overridden with `KERNELSCRIPT_PERF_GROUP_MAX_EVENTS`, and is capped at 16 to match `PerfRead`.
331
+
Adding a member restarts the whole group from zero. Detaching a leader cascades to any live members. A group competes for PMU counters as one atomic unit: different groups can be multiplexed over time, but members inside one group are not independently multiplexed. A group that needs more hardware PMU counters than the running host provides is rejected by the kernel at `perf_event_open(2)`, and `attach()` surfaces the error at runtime — on the actual deployment host, where the real counter count is known. `read(att)` exposes up to 16 group entries (`perf_read`).
334
332
335
-
`read(att)` returns a `PerfRead` snapshot with raw, multiplex-scaled, timing, and group fields. Use `read(att).scaled` for that attachment's counter value, `read(att).raw` for its unscaled value, and `read(att).values` / `read(att).ids` for a same-time group snapshot.
333
+
`read(att)` returns a `perf_read` snapshot with raw, multiplex-scaled, timing, and group fields. Use `read(att).scaled` for that attachment's counter value, `read(att).raw` for its unscaled value, and `read(att).values` / `read(att).ids` for a same-time group snapshot.
336
334
337
-
**Available `perf_type` values:**
335
+
**Available `event` constants:**
338
336
339
-
| Enum value | Hardware/software event |
340
-
|---|---|
341
-
|`perf_type_hardware`|`PERF_TYPE_HARDWARE`|
342
-
|`perf_type_software`|`PERF_TYPE_SOFTWARE`|
343
-
|`perf_type_tracepoint`|`PERF_TYPE_TRACEPOINT`|
344
-
|`perf_type_hw_cache`|`PERF_TYPE_HW_CACHE`|
345
-
|`perf_type_raw`|`PERF_TYPE_RAW`|
346
-
|`perf_type_breakpoint`|`PERF_TYPE_BREAKPOINT`|
337
+
Each constant packs its `perf_event_attr.type` tag in the high 32 bits and its config in the low 32 bits, so naming the event fixes both.
0 commit comments