Skip to content

Commit 4401467

Browse files
committed
Fix syscall numbers for non-x86_64 architectures
This gets LinuxPerf.jl working for me on `aarch64-linux`: ``` julia> @pstats nothing ┌ Warning: LinuxPerf.EventTypeExt(hw:branches, false, 0x0000000000000006) not supported, skipping └ @ LinuxPerf ~/.julia/dev/LinuxPerf/src/LinuxPerf.jl:299 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┌ cpu-cycles 2.50e+02 100.0% # 0.0 cycles per ns │ stalled-cycles-frontend 2.18e+02 100.0% # 87.2% of cycles └ stalled-cycles-backend 2.30e+01 100.0% # 9.2% of cycles ┌ instructions 1.80e+01 100.0% # 0.1 insns per cycle └ branch-misses 2.00e+00 100.0% ┌ task-clock 1.64e+05 100.0% # 164.5 μs │ context-switches 0.00e+00 100.0% │ cpu-migrations 0.00e+00 100.0% └ page-faults 0.00e+00 100.0% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` The warning is due to a bug in that hasn't been fixed yet in my kernel: https://patchwork.kernel.org/project/linux-arm-kernel/patch/[email protected]/
1 parent 47111c4 commit 4401467

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

src/LinuxPerf.jl

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,24 @@ function Base.show(io::IO, e::EventType)
155155
end
156156
end
157157

158-
const SYS_perf_event_open = 298
158+
const SYS_perf_event_open = if Sys.ARCH === :x86_64
159+
Clong(298)
160+
elseif Sys.ARCH === :i686
161+
Clong(336)
162+
elseif Sys.ARCH === :aarch64
163+
Clong(241)
164+
elseif Sys.ARCH === :arm
165+
Clong(364)
166+
else
167+
Clong(-1) # sentinel for unknown syscall ID
168+
end
159169

160170
"""
161171
perf_event_open(attr::perf_event_attr, pid, cpu, fd, flags)
162172
"""
163173
function perf_event_open(attr::perf_event_attr, pid, cpu, leader_fd, flags)
164174
r_attr = Ref(attr)
175+
SYS_perf_event_open == -1 && error("perf_event_open error : unknown architecture")
165176
GC.@preserve r_attr begin
166177
# Have to do a manual conversion, since the ABI is a vararg call
167178
ptr = Base.unsafe_convert(Ptr{Cvoid}, Base.cconvert(Ptr{Cvoid}, r_attr))
@@ -325,16 +336,28 @@ function Base.show(io::IO, g::EventGroup)
325336
print(io, "\t", g.event_types[end], ")")
326337
end
327338

328-
const SYS_prctl = Clong(157)
339+
const SYS_prctl = if Sys.ARCH === :x86_64
340+
Clong(157)
341+
elseif Sys.ARCH === :i686
342+
Clong(172)
343+
elseif Sys.ARCH === :aarch64
344+
Clong(167)
345+
elseif Sys.ARCH === :arm
346+
Clong(172)
347+
else
348+
Clong(-1) # sentinel for unknown syscall ID
349+
end
329350
const PR_TASK_PERF_EVENTS_DISABLE = Cint(31)
330351
const PR_TASK_PERF_EVENTS_ENABLE = Cint(32)
331352

332353
# syscall is lower overhead than calling libc's prctl
333354
function enable_all!()
355+
SYS_prctl == -1 && error("prctl error : unknown architecture")
334356
res = ccall(:syscall, Cint, (Clong, Clong...), SYS_prctl, PR_TASK_PERF_EVENTS_ENABLE)
335357
Base.systemerror(:prctl, res < 0)
336358
end
337359
function disable_all!()
360+
SYS_prctl == -1 && error("prctl error : unknown architecture")
338361
res = ccall(:syscall, Cint, (Clong, Clong...), SYS_prctl, PR_TASK_PERF_EVENTS_DISABLE)
339362
Base.systemerror(:prctl, res < 0)
340363
end

0 commit comments

Comments
 (0)