Skip to content

Commit

Permalink
hbt/bperf: Only use lowest 48 bit of prev_count on x86
Browse files Browse the repository at this point in the history
Summary:
The upper 16 bits are not used by the kernel, and can be either ffff or
0000. Always clear them so that we get reliable numbers.

Differential Revision: D63348455
  • Loading branch information
liu-song-6 authored and facebook-github-bot committed Sep 24, 2024
1 parent ef40100 commit 8e271c0
Showing 1 changed file with 26 additions and 12 deletions.
38 changes: 26 additions & 12 deletions hbt/src/perf_event/bpf/bperf_leader_cgroup.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ const volatile int event_cnt = 0;
int cpu_cnt = 0;
int cgroup_update_level = 0;

static __always_inline __u64 event_offset(struct perf_event *event) {
__u64 val = event->hw.prev_count.a.a.counter;

#if __x86_64__
/* Only lower 48 bits are used. The upper bits could be either ffff or
* 0000. Always clear upper bits so the result is accurate.
*/
val &= 0xffffffffffffULL;
#endif
return val;
}

#define PF_IDLE 0x00000002

static void update_cgroup_output(struct bpf_perf_event_value* diff_val,
Expand Down Expand Up @@ -401,7 +413,7 @@ static void __always_inline update_next_task(struct task_struct *next, __u64 now
}

event = bpf_core_cast(pe_data->event, struct perf_event);
data->events[i].offset = event->hw.prev_count.a.a.counter;
data->events[i].offset = event_offset(event);
data->events[i].idx = pe_data->idx;
}
}
Expand Down Expand Up @@ -503,6 +515,15 @@ static int __always_inline _pmu_enable_exit(struct pmu *pmu)
struct pe_data *pe_data;
int *idx, i, pid;

pid = bpf_get_current_pid_tgid() & 0xffffffff;
idx = bpf_map_lookup_elem(&per_thread_idx, &pid);
if (!idx)
return 0;

data = bpf_map_lookup_elem(&per_thread_data, idx);
if (data)
data->lock += 1;

for (i = 0; i < BPERF_MAX_GROUP_SIZE && i < event_cnt; i++) {
struct perf_event *event;
int key = i, pmc_idx;
Expand All @@ -525,18 +546,11 @@ static int __always_inline _pmu_enable_exit(struct pmu *pmu)
*/
}
pe_data->idx = pmc_idx;
if (data) {
data->events[i].idx = pmc_idx;
data->events[i].offset = event_offset(event);
}
}

pid = bpf_get_current_pid_tgid() & 0xffffffff;
idx = bpf_map_lookup_elem(&per_thread_idx, &pid);
if (!idx)
return 0;

data = bpf_map_lookup_elem(&per_thread_data, idx);
if (!data)
return 0;
data->lock += 1;

return 0;
}

Expand Down

0 comments on commit 8e271c0

Please sign in to comment.