Skip to content

Conversation

@kernel-patches-daemon-bpf
Copy link

Pull request for series with
subject: libbpf: Make optimized uprobes backward compatible
version: 1
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1024135

We can currently optimize uprobes on top of nop5 instructions,
so application can define USDT_NOP to nop5 and use USDT macro
to define optimized usdt probes.

This works fine on new kernels, but could have performance penalty
on older kernels, that do not have the support to optimize and to
emulate nop5 instruction.

  execution of the usdt probe on top of nop:
  - nop -> trigger usdt -> emulate nop -> continue

  execution of the usdt probe on top of nop5:
  - nop5 -> trigger usdt -> single step nop5 -> continue

Note the 'single step nop5' as the source of performance regression.

To workaround that we change the USDT macro to emit nop,nop5 for
the probe (instead of default nop) and make record of that in
USDT record (more on that below).

This can be detected by application (libbpf) and it can place the
uprobe either on nop or nop5 based on the optimization support in
the kernel.

We make record of using the nop,nop5 instructions in the USDT ELF
note data.

Current elf note format is as follows:

  namesz (4B) | descsz (4B) | type (4B) | name | desc

And current usdt record (with "stapsdt" name) placed in the note's
desc data look like:

  loc_addr  | 8 bytes
  base_addr | 8 bytes
  sema_addr | 8 bytes
  provider  | zero terminated string
  name      | zero terminated string
  args      | zero terminated string

None of the tested parsers (bpftrace-bcc, libbpf) checked that the args
zero terminated byte is the actual end of the 'desc' data. As Andrii
suggested we could use this and place extra zero byte right there as an
indication for the parser we use the nop,nop5 instructions.

It's bit tricky, but the other way would be to introduce new elf note type
or note name and change all existing parsers to recognize it. With the change
above the existing parsers would still recognize such usdt probes.

Note we do not emit this extra byte if app defined its own nop through
USDT_NOP macro.

Suggested-by: Andrii Nakryiko <[email protected]>
Signed-off-by: Jiri Olsa <[email protected]>
Adding uprobe syscall feature detection that will be used
in following changes.

Signed-off-by: Jiri Olsa <[email protected]>
Adding support to parse extra info in usdt note record that
indicates there's nop,nop5 emitted for probe.

We detect this by checking extra zero byte placed in between
args zero termination byte and desc data end. Please see [1]
for more details.

Together with uprobe syscall feature detection we can decide
if we want to place the probe on top of nop or nop5.

[1] https://github.com/libbpf/usdt
Signed-off-by: Jiri Olsa <[email protected]>
Adding test that attaches bpf program on usdt probe in 2 scenarios;

- attach program on top of usdt_1 which is standard nop probe
  incidentally followed by nop5. The usdt probe does not have
  extra data in elf note record, so we expect the probe to land
  on the first nop without being optimized.

- attach program on top of usdt_2 which is probe defined on top
  of nop,nop5 combo. The extra data in the elf note record and
  presence of upeobe syscall ensures that the probe is placed
  on top of nop5 and optimized.

Signed-off-by: Jiri Olsa <[email protected]>
@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: 4722981
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1024135
version: 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants