Em Mon, Mar 11, 2019 at 10:30:43PM -0700, Song Liu escreveu: > +static int write_bpf_prog_info(struct feat_fd *ff, > + struct perf_evlist *evlist __maybe_unused) > +{ > + struct perf_env *env = &ff->ph->env; > + struct rb_root *root; > + struct rb_node *next; > + int ret; > + > + down_read(&env->bpf_progs.lock); > + > + ret = do_write(ff, &env->bpf_progs.infos_cnt, > + sizeof(env->bpf_progs.infos_cnt)); > + if (ret < 0) > + goto out; > + > + root = &env->bpf_progs.infos; > + next = rb_first(root); > + while (next) { > + struct bpf_prog_info_node *node; > + size_t len; > + > + node = rb_entry(next, struct bpf_prog_info_node, rb_node); > + next = rb_next(&node->rb_node); > + len = sizeof(struct bpf_prog_info_linear) + > + node->info_linear->data_len; > + > + /* before writing to file, translate address to offset */ > + bpf_program__bpil_addr_to_offs(node->info_linear); > + ret = do_write(ff, node->info_linear, len); > + /* > + * translate back to address even when do_write() fails, > + * so that this function never changes the data. > + */ > + bpf_program__bpil_offs_to_addr(node->info_linear); > + if (ret < 0) > + goto out; > + } > +out: > + up_read(&env->bpf_progs.lock); > + return ret; > +} The above uses libbpf functions unconditionally, leading to build failures when NO_LIBBPF=1 is passed or libbpf somehow is not available or can't be built. So I added this: +#else // HAVE_LIBBPF_SUPPORT +static int write_bpf_prog_info(struct feat_fd *ff __maybe_unused, + struct perf_evlist *evlist __maybe_unused) +{ + return 0; +} +#endif // HAVE_LIBBPF_SUPPORT And added this committer notes: Committer notes: We can't use the libbpf unconditionally, as the build may have been with NO_LIBBPF, when we end up with linking errors, so provide a dummy write_bpf_prog_info() wrapped by HAVE_LIBBPF_SUPPORT for that case. Reading and printing are not affected by this, so can continue as is.