-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make perf ring buffer size configurable #997
Conversation
lgtm. thanks! |
[buildbot, ok to test] I should add this to cpuunclaimed, too (which sleeps during the kpoll loop to reduce overhead, which fills the buffers). |
@brendangregg I can add cpuunclaimed. Do you want 64 pages or more? Or |
Taking a look at others... I'd take it off execsnoop (doubt it needs it, unless you think otherwise). The potentially high buffer output tools where it could be added are: biosnoop, cpuunclaimed, dcsnoop, the *slower.py tools (especially when run with an arg of "0"), statsnoop, tcplife. If you want, go ahead and add it to them, thanks. I don't have an opinion yet on what they should all be. I guess we can start with 64 pages. I'd still avoid the -b unless we really need to, like with trace. |
Sounds good. I think I saw overflows on execsnoop but will check and update
the PR when I get home in a bit.
|
I won't get to this until tomorrow, unfortunately (computer issues at
home).
|
Hi @markdrayton! All function arguments are optional in Lua, and set to function PerfEventArray:_open_perf_buffer(cpu, callback, ctype, pages_per_buffer)
-- [...]
-- default to `pages_per_buffer`, or 8 if not given
local reader = libbcc.bpf_open_perf_buffer(_cb, nil, -1, cpu, pages_per_buffer or 8)
-- [...] |
I think I also figured out the Lua side. Update coming. |
I couldn't work out the Lua stuff :-( @vmg, the problem is not with function PerfEventArray:open_perf_buffer(callback, data_type, ...) I don't see how I can put an optional arg either side of the function PerfEventArray:open_perf_buffer(args, ...)
setmetatable(args, {__index={page_cnt=8}})
local callback = args[1]
local data_type = args[2]
assert(data_type, "a data type is needed for callback conversion")
local ctype = ffi.typeof(data_type.."*", ...)
for i = 0, Posix.cpu_count() - 1 do
self:_open_perf_buffer(i, callback, ctype, args.page_cnt)
end
end but that fails like so:
@vmg, any suggestions here? @brendangregg in the meantime I have updated the other scripts you mentioned. |
Apparently I did something stupid here and closed the PR. |
I was wondering! |
@markdrayton I understand now. Try this on for size: function PerfEventArray:open_perf_buffer(callback, data_type, data_params, buffer_size)
assert(data_type, "a data type is needed for callback conversion")
local ctype = ffi.typeof(data_type.."*", unpack(data_params or {}))
for i = 0, Posix.cpu_count() - 1 do
self:_open_perf_buffer(i, callback, ctype, buffer_size)
end
end Here's what's what going on: the varargs to If we want to add more optional arguments to this API, our only option is to actually pass in the data params in a table, and add the Here's how the API was used before this change: tbl:open_perf_buffer(my_callback, "struct kernel_type { uint8_t buffer[$]; }", SIZE_IN_KERNEL)
tbl:open_perf_buffer(my_callback, "struct custom_type { $ buffer[$]; }", "uint8_t", 1024) Notice how the templating is type-safe. In this example we're using it to reproduce a type from the kernel and "grab" the And here's how you'd use the API now: tbl:open_perf_buffer(my_callback, "struct kernel_type { uint8_t buffer[$]; }", {SIZE_IN_KERNEL}, 4096)
tbl:open_perf_buffer(my_callback, "struct custom_type { $ buffer[$]; }", {"uint8_t", 1024}, 4096)
tbl:open_perf_buffer(my_callback, "struct non_templated_type { int foo; }", nil, 4096) Here we're passing in a So yes, this is a breaking change. But I think it makes the API more consistent and more understandable. The old varargs were confusing, particularly since they were not documented. One last thing to note: we're passing Hope that clears things up and makes the build green. Let me know if I can help with anything else! |
As discussed in #966, this PR makes the size of the ring buffer used to send data to userspace configurable. It changes the Python, Lua and C++ APIs to expose this knob. It also defaults the buffer size to a larger value (64 pages per CPU, an 8x increase) for several tools which produce a lot of output, as well as making it configurable in `trace` via a `-b` flag.
@vmg hooray! That seems to work nicely. I just updated the Lua API and any Lua scripts that call @4ast, @brendangregg: this should be good to go now. re: the red tests: It looks like something's up with the fc25 buildbot — the errors seem to relate to basic git operations and not to the code itself: https://buildbot.iovisor.org/jenkins/job/bcc-pr/label=fc25/94/console |
🎉👌 |
[buildbot, retest this please] |
[buildbot, test this please] |
Excellent! |
As discussed in #966, this PR makes the size of the ring buffer used to send
data to userspace configurable. It changes the Python and C APIs to expose this
knob. It doesn't change the Lua API as I couldn't work out a clean way to
handle an optional parameter in the way that Python does (cc @vmg).
It also defaults the buffer size to a larger value (64 pages per CPU, an 8x
increase) for several tools which produce a lot of output, as well as making it
configurable in
trace
via a-b
flag.I didn't go for passing an argument for buffer size to the BPF constructor because there's already quite a few parameters there (
cflags
,usdt_contexts
etc) and the size of the buffer seems more specific toopen_perf_buffer()
than a BPF context. If that approach or adding a setter function likebpf.set_perf_buffer_page_cnt()
is preferable let me know.