Bpftrace: top and divisor arguments don't work when printing an avg() map

Created on 15 Jun 2020  路  3Comments  路  Source: iovisor/bpftrace

bpftrace --info

System
  OS: Linux 5.7.2-arch1-1 #1 SMP PREEMPT Wed, 10 Jun 2020 20:36:24 +0000
  Arch: x86_64

Build
  version: v0.10.0-182-gadf93
  LLVM: 10
  foreach_sym: yes
  unsafe uprobe: no
  bfd: yes
  bpf_attach_kfunc: yes
  libbpf: yes
  libbpf btf dump: yes
  libbpf btf dump type decl: yes

Kernel helpers
  probe_read: yes
  probe_read_str: yes
  probe_read_user: yes
  probe_read_user_str: yes
  probe_read_kernel: yes
  probe_read_kernel_str: yes
  get_current_cgroup_id: yes
  send_signal: yes
  override_return: yes

Kernel features
  Instruction limit: 1000000
  Loop support: yes
  btf: yes

Map types
  hash: yes
  percpu hash: yes
  array: yes
  percpu array: yes
  stack_trace: yes
  perf_event_array: yes

Probe types
  kprobe: yes
  tracepoint: yes
  perf_event: yes
  kfunc: yes
  lsm: yes

What reproduces the bug?

Not exactly sure if this should be a bug report or feature request, as it might be intended behavior.
When printing a map whose values have been generated with avg(), I should be able to specify a top and div argument like print(@, 10, 1000) to print the top 10 results divided by 1000. The current implementation does not support this.

An example use case would be measuring average execution times for system calls.

Minimal example:

t:raw_syscalls:sys_enter {
    @start[tid] = nsecs;
}

t:raw_syscalls:sys_exit {
    $start_t = @start[tid];
    $id = args->id;

    if ($id != $start_id) {
        return;
    }

    $dur = (nsecs - $start_t);
    @avg_t[$id] = avg($dur);
}

END {
    clear(@start);

    printf("Printing top 10 average times (us):\n");
    print(@avg_t, 10, 1000);
    clear(@avg_t);
}

Expected output:

Printing top 10 average times (us):
@avg_t[28]: 45
@avg_t[230]: 74
@avg_t[35]: 82
@avg_t[217]: 117
@avg_t[202]: 89641762
@avg_t[7]: 630540603
@avg_t[232]: 761679852
@avg_t[281]: 1390053830
@avg_t[271]: 3706822648
@avg_t[23]: 3971615699

Actual output:

Printing top 10 average times (us):
@avg_t[38]: 2276
@avg_t[89]: 2362
@avg_t[4]: 2374
@avg_t[24]: 2485
@avg_t[286]: 3485
@avg_t[39]: 4216
@avg_t[233]: 4322
@avg_t[102]: 4345
..... (omitted)
@avg_t[28]: 45934
@avg_t[230]: 74438
@avg_t[35]: 82891
@avg_t[217]: 117918
@avg_t[202]: 89641762244
@avg_t[7]: 630540603371
@avg_t[232]: 761679852015
@avg_t[281]: 1390053830002
@avg_t[271]: 3706822648732
@avg_t[23]: 3971615699056
bug

Most helpful comment

@suyuee possibly an easy fix here

All 3 comments

avg() and stats() does not support "div" and "top". (just forgotten to implement it?)
https://github.com/iovisor/bpftrace/blob/60d77c26423c3bda5923d8493224041d74ba10eb/src/bpftrace.cpp#L1281-L1282

@mmisono Yes I saw this too, which is what makes me think it may be intentional. You could certainly make the case for stats that a top/divisor argument doesn't make sense (which field(s) would you target?), but I see no reason why avg() shouldn't support it.

@suyuee possibly an easy fix here

Was this page helpful?
0 / 5 - 0 ratings