iovisor / bcc

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more
Apache License 2.0
20.4k stars 3.86k forks source link

Cannot access kernel percpu variables, LLVM error parsing inline asm because %gs is invalid register/token name #2914

Open wenbinzeng opened 4 years ago

wenbinzeng commented 4 years ago

I am trying to read preempt_count in a bcc program, but can't get it done, because preempt_count() ends up reading kernel percpu variables in asm code which accesses %gs register, but LLVM doesn't recognize it and reports invalid register error as follows:

<inline asm>:1:2: error: invalid register/token name movl %gs:(r1 + 0),r1 ^ LLVM ERROR: Error parsing inline asm

Not only preempt_count, any kernel percpu variables I don't know how to read via bcc programs. Appreciate very much if someone would kindly help.

The code looks like:

prg = """ ... int perf_cpu_clock(struct bpf_perf_event_data *ctx) { ... data.preempt_count = preempt_count(); ... } """ b = BPF(text=prog) b.attach_perf_event(ev_type=PerfType.SOFTWARE, ev_config=PerfSWConfig.CPU_CLOCK, fn_name="perf_cpu_clock", sample_period=0, sample_freq=99, cpu=-1) b["events"].open_perf_buffer(process_event) ...

yonghong-song commented 4 years ago

native inline assembly code (x64) won't work for bpf. If necessary, we need a helper here. What is your use case for preempt_count()?

wenbinzeng commented 4 years ago

Thanks Yonghong. I am working on an performance profiling and analysis tool, during data collection phase some kernel states are needed, actually I also want to read some other percpu variables like kernel_cpustat -- which also couldn't be done so far. I am thinking what kind of helper it would be, a helper to read kernel percpu variables or a helper to run native inline asm code?

yonghong-song commented 4 years ago

Easy accesss percpu globals are not available yet. There is a proposal here https://lore.kernel.org/bpf/20200522142813.GF14034@kernel.org/T/#m1ce13856132738b6dc9253a8222e38803913fd7c it may take time to implement.

But you can do it today with sufficient kernel knowledge with __per_cpu_offset_addr and kernel_cpustat and with bpf_probe_read().

For inline asm code, a helper is needed. Why you need this information? A strong use case is needed in order to add a helper.

Anjali05 commented 1 week ago

@yonghong-song I need to read preempt_count in my bcc program too. Do you know if this has been implemented yet?

Adding a little bit of context here. I raised an issue regarding recognizing process context while collecting stack traces (https://github.com/iovisor/bcc/issues/5114). I was trying to use in_task() (https://elixir.bootlin.com/linux/v6.1/source/include/linux/preempt.h#L121), but its not working as it calls preempt_count() (https://elixir.bootlin.com/linux/v6.1/source/include/linux/preempt.h#L101).

@wenbinzeng Were you able to resolve this?