Skip to content

Commit d8b5297

Browse files
committed
Merge tag 'perf-core-for-mingo-5.1-20190321' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo: BPF: Song Liu: - Add support for annotating BPF programs, using the PERF_RECORD_BPF_EVENT and PERF_RECORD_KSYMBOL recently added to the kernel and plugging binutils's libopcodes disassembly of BPF programs with the existing annotation interfaces in 'perf annotate', 'perf report' and 'perf top' various output formats (--stdio, --stdio2, --tui). perf list: Andi Kleen: - Filter metrics when using substring search. perf record: Andi Kleen: - Allow to limit number of reported perf.data files - Clarify help for --switch-output. perf report: Andi Kleen - Indicate JITed code better. - Show all sort keys in help output. perf script: Andi Kleen: - Support relative time. perf stat: Andi Kleen: - Improve scaling. General: Changbin Du: - Fix some mostly error path memory and reference count leaks found using gcc's ASan and UBSan. Vendor events: Mamatha Inamdar: - Remove P8 HW events which are not supported. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2 parents 4a98be8 + f8dfeae commit d8b5297

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1794
-1028
lines changed

tools/bpf/bpftool/prog.c

Lines changed: 59 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -401,41 +401,31 @@ static int do_show(int argc, char **argv)
401401

402402
static int do_dump(int argc, char **argv)
403403
{
404-
unsigned int finfo_rec_size, linfo_rec_size, jited_linfo_rec_size;
405-
void *func_info = NULL, *linfo = NULL, *jited_linfo = NULL;
406-
unsigned int nr_finfo, nr_linfo = 0, nr_jited_linfo = 0;
404+
struct bpf_prog_info_linear *info_linear;
407405
struct bpf_prog_linfo *prog_linfo = NULL;
408-
unsigned long *func_ksyms = NULL;
409-
struct bpf_prog_info info = {};
410-
unsigned int *func_lens = NULL;
406+
enum {DUMP_JITED, DUMP_XLATED} mode;
411407
const char *disasm_opt = NULL;
412-
unsigned int nr_func_ksyms;
413-
unsigned int nr_func_lens;
408+
struct bpf_prog_info *info;
414409
struct dump_data dd = {};
415-
__u32 len = sizeof(info);
410+
void *func_info = NULL;
416411
struct btf *btf = NULL;
417-
unsigned int buf_size;
418412
char *filepath = NULL;
419413
bool opcodes = false;
420414
bool visual = false;
421415
char func_sig[1024];
422416
unsigned char *buf;
423417
bool linum = false;
424-
__u32 *member_len;
425-
__u64 *member_ptr;
418+
__u32 member_len;
419+
__u64 arrays;
426420
ssize_t n;
427-
int err;
428421
int fd;
429422

430423
if (is_prefix(*argv, "jited")) {
431424
if (disasm_init())
432425
return -1;
433-
434-
member_len = &info.jited_prog_len;
435-
member_ptr = &info.jited_prog_insns;
426+
mode = DUMP_JITED;
436427
} else if (is_prefix(*argv, "xlated")) {
437-
member_len = &info.xlated_prog_len;
438-
member_ptr = &info.xlated_prog_insns;
428+
mode = DUMP_XLATED;
439429
} else {
440430
p_err("expected 'xlated' or 'jited', got: %s", *argv);
441431
return -1;
@@ -474,175 +464,50 @@ static int do_dump(int argc, char **argv)
474464
return -1;
475465
}
476466

477-
err = bpf_obj_get_info_by_fd(fd, &info, &len);
478-
if (err) {
479-
p_err("can't get prog info: %s", strerror(errno));
480-
return -1;
481-
}
482-
483-
if (!*member_len) {
484-
p_info("no instructions returned");
485-
close(fd);
486-
return 0;
487-
}
467+
if (mode == DUMP_JITED)
468+
arrays = 1UL << BPF_PROG_INFO_JITED_INSNS;
469+
else
470+
arrays = 1UL << BPF_PROG_INFO_XLATED_INSNS;
488471

489-
buf_size = *member_len;
472+
arrays |= 1UL << BPF_PROG_INFO_JITED_KSYMS;
473+
arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS;
474+
arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO;
475+
arrays |= 1UL << BPF_PROG_INFO_LINE_INFO;
476+
arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO;
490477

491-
buf = malloc(buf_size);
492-
if (!buf) {
493-
p_err("mem alloc failed");
494-
close(fd);
478+
info_linear = bpf_program__get_prog_info_linear(fd, arrays);
479+
close(fd);
480+
if (IS_ERR_OR_NULL(info_linear)) {
481+
p_err("can't get prog info: %s", strerror(errno));
495482
return -1;
496483
}
497484

498-
nr_func_ksyms = info.nr_jited_ksyms;
499-
if (nr_func_ksyms) {
500-
func_ksyms = malloc(nr_func_ksyms * sizeof(__u64));
501-
if (!func_ksyms) {
502-
p_err("mem alloc failed");
503-
close(fd);
504-
goto err_free;
505-
}
506-
}
507-
508-
nr_func_lens = info.nr_jited_func_lens;
509-
if (nr_func_lens) {
510-
func_lens = malloc(nr_func_lens * sizeof(__u32));
511-
if (!func_lens) {
512-
p_err("mem alloc failed");
513-
close(fd);
485+
info = &info_linear->info;
486+
if (mode == DUMP_JITED) {
487+
if (info->jited_prog_len == 0) {
488+
p_info("no instructions returned");
514489
goto err_free;
515490
}
516-
}
517-
518-
nr_finfo = info.nr_func_info;
519-
finfo_rec_size = info.func_info_rec_size;
520-
if (nr_finfo && finfo_rec_size) {
521-
func_info = malloc(nr_finfo * finfo_rec_size);
522-
if (!func_info) {
523-
p_err("mem alloc failed");
524-
close(fd);
491+
buf = (unsigned char *)(info->jited_prog_insns);
492+
member_len = info->jited_prog_len;
493+
} else { /* DUMP_XLATED */
494+
if (info->xlated_prog_len == 0) {
495+
p_err("error retrieving insn dump: kernel.kptr_restrict set?");
525496
goto err_free;
526497
}
498+
buf = (unsigned char *)info->xlated_prog_insns;
499+
member_len = info->xlated_prog_len;
527500
}
528501

529-
linfo_rec_size = info.line_info_rec_size;
530-
if (info.nr_line_info && linfo_rec_size && info.btf_id) {
531-
nr_linfo = info.nr_line_info;
532-
linfo = malloc(nr_linfo * linfo_rec_size);
533-
if (!linfo) {
534-
p_err("mem alloc failed");
535-
close(fd);
536-
goto err_free;
537-
}
538-
}
539-
540-
jited_linfo_rec_size = info.jited_line_info_rec_size;
541-
if (info.nr_jited_line_info &&
542-
jited_linfo_rec_size &&
543-
info.nr_jited_ksyms &&
544-
info.nr_jited_func_lens &&
545-
info.btf_id) {
546-
nr_jited_linfo = info.nr_jited_line_info;
547-
jited_linfo = malloc(nr_jited_linfo * jited_linfo_rec_size);
548-
if (!jited_linfo) {
549-
p_err("mem alloc failed");
550-
close(fd);
551-
goto err_free;
552-
}
553-
}
554-
555-
memset(&info, 0, sizeof(info));
556-
557-
*member_ptr = ptr_to_u64(buf);
558-
*member_len = buf_size;
559-
info.jited_ksyms = ptr_to_u64(func_ksyms);
560-
info.nr_jited_ksyms = nr_func_ksyms;
561-
info.jited_func_lens = ptr_to_u64(func_lens);
562-
info.nr_jited_func_lens = nr_func_lens;
563-
info.nr_func_info = nr_finfo;
564-
info.func_info_rec_size = finfo_rec_size;
565-
info.func_info = ptr_to_u64(func_info);
566-
info.nr_line_info = nr_linfo;
567-
info.line_info_rec_size = linfo_rec_size;
568-
info.line_info = ptr_to_u64(linfo);
569-
info.nr_jited_line_info = nr_jited_linfo;
570-
info.jited_line_info_rec_size = jited_linfo_rec_size;
571-
info.jited_line_info = ptr_to_u64(jited_linfo);
572-
573-
err = bpf_obj_get_info_by_fd(fd, &info, &len);
574-
close(fd);
575-
if (err) {
576-
p_err("can't get prog info: %s", strerror(errno));
577-
goto err_free;
578-
}
579-
580-
if (*member_len > buf_size) {
581-
p_err("too many instructions returned");
582-
goto err_free;
583-
}
584-
585-
if (info.nr_jited_ksyms > nr_func_ksyms) {
586-
p_err("too many addresses returned");
587-
goto err_free;
588-
}
589-
590-
if (info.nr_jited_func_lens > nr_func_lens) {
591-
p_err("too many values returned");
592-
goto err_free;
593-
}
594-
595-
if (info.nr_func_info != nr_finfo) {
596-
p_err("incorrect nr_func_info %d vs. expected %d",
597-
info.nr_func_info, nr_finfo);
598-
goto err_free;
599-
}
600-
601-
if (info.func_info_rec_size != finfo_rec_size) {
602-
p_err("incorrect func_info_rec_size %d vs. expected %d",
603-
info.func_info_rec_size, finfo_rec_size);
604-
goto err_free;
605-
}
606-
607-
if (linfo && info.nr_line_info != nr_linfo) {
608-
p_err("incorrect nr_line_info %u vs. expected %u",
609-
info.nr_line_info, nr_linfo);
610-
goto err_free;
611-
}
612-
613-
if (info.line_info_rec_size != linfo_rec_size) {
614-
p_err("incorrect line_info_rec_size %u vs. expected %u",
615-
info.line_info_rec_size, linfo_rec_size);
616-
goto err_free;
617-
}
618-
619-
if (jited_linfo && info.nr_jited_line_info != nr_jited_linfo) {
620-
p_err("incorrect nr_jited_line_info %u vs. expected %u",
621-
info.nr_jited_line_info, nr_jited_linfo);
622-
goto err_free;
623-
}
624-
625-
if (info.jited_line_info_rec_size != jited_linfo_rec_size) {
626-
p_err("incorrect jited_line_info_rec_size %u vs. expected %u",
627-
info.jited_line_info_rec_size, jited_linfo_rec_size);
628-
goto err_free;
629-
}
630-
631-
if ((member_len == &info.jited_prog_len &&
632-
info.jited_prog_insns == 0) ||
633-
(member_len == &info.xlated_prog_len &&
634-
info.xlated_prog_insns == 0)) {
635-
p_err("error retrieving insn dump: kernel.kptr_restrict set?");
636-
goto err_free;
637-
}
638-
639-
if (info.btf_id && btf__get_from_id(info.btf_id, &btf)) {
502+
if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
640503
p_err("failed to get btf");
641504
goto err_free;
642505
}
643506

644-
if (nr_linfo) {
645-
prog_linfo = bpf_prog_linfo__new(&info);
507+
func_info = (void *)info->func_info;
508+
509+
if (info->nr_line_info) {
510+
prog_linfo = bpf_prog_linfo__new(info);
646511
if (!prog_linfo)
647512
p_info("error in processing bpf_line_info. continue without it.");
648513
}
@@ -655,47 +520,46 @@ static int do_dump(int argc, char **argv)
655520
goto err_free;
656521
}
657522

658-
n = write(fd, buf, *member_len);
523+
n = write(fd, buf, member_len);
659524
close(fd);
660-
if (n != *member_len) {
525+
if (n != member_len) {
661526
p_err("error writing output file: %s",
662527
n < 0 ? strerror(errno) : "short write");
663528
goto err_free;
664529
}
665530

666531
if (json_output)
667532
jsonw_null(json_wtr);
668-
} else if (member_len == &info.jited_prog_len) {
533+
} else if (mode == DUMP_JITED) {
669534
const char *name = NULL;
670535

671-
if (info.ifindex) {
672-
name = ifindex_to_bfd_params(info.ifindex,
673-
info.netns_dev,
674-
info.netns_ino,
536+
if (info->ifindex) {
537+
name = ifindex_to_bfd_params(info->ifindex,
538+
info->netns_dev,
539+
info->netns_ino,
675540
&disasm_opt);
676541
if (!name)
677542
goto err_free;
678543
}
679544

680-
if (info.nr_jited_func_lens && info.jited_func_lens) {
545+
if (info->nr_jited_func_lens && info->jited_func_lens) {
681546
struct kernel_sym *sym = NULL;
682547
struct bpf_func_info *record;
683548
char sym_name[SYM_MAX_NAME];
684549
unsigned char *img = buf;
685550
__u64 *ksyms = NULL;
686551
__u32 *lens;
687552
__u32 i;
688-
689-
if (info.nr_jited_ksyms) {
553+
if (info->nr_jited_ksyms) {
690554
kernel_syms_load(&dd);
691-
ksyms = (__u64 *) info.jited_ksyms;
555+
ksyms = (__u64 *) info->jited_ksyms;
692556
}
693557

694558
if (json_output)
695559
jsonw_start_array(json_wtr);
696560

697-
lens = (__u32 *) info.jited_func_lens;
698-
for (i = 0; i < info.nr_jited_func_lens; i++) {
561+
lens = (__u32 *) info->jited_func_lens;
562+
for (i = 0; i < info->nr_jited_func_lens; i++) {
699563
if (ksyms) {
700564
sym = kernel_syms_search(&dd, ksyms[i]);
701565
if (sym)
@@ -707,7 +571,7 @@ static int do_dump(int argc, char **argv)
707571
}
708572

709573
if (func_info) {
710-
record = func_info + i * finfo_rec_size;
574+
record = func_info + i * info->func_info_rec_size;
711575
btf_dumper_type_only(btf, record->type_id,
712576
func_sig,
713577
sizeof(func_sig));
@@ -744,49 +608,37 @@ static int do_dump(int argc, char **argv)
744608
if (json_output)
745609
jsonw_end_array(json_wtr);
746610
} else {
747-
disasm_print_insn(buf, *member_len, opcodes, name,
611+
disasm_print_insn(buf, member_len, opcodes, name,
748612
disasm_opt, btf, NULL, 0, 0, false);
749613
}
750614
} else if (visual) {
751615
if (json_output)
752616
jsonw_null(json_wtr);
753617
else
754-
dump_xlated_cfg(buf, *member_len);
618+
dump_xlated_cfg(buf, member_len);
755619
} else {
756620
kernel_syms_load(&dd);
757-
dd.nr_jited_ksyms = info.nr_jited_ksyms;
758-
dd.jited_ksyms = (__u64 *) info.jited_ksyms;
621+
dd.nr_jited_ksyms = info->nr_jited_ksyms;
622+
dd.jited_ksyms = (__u64 *) info->jited_ksyms;
759623
dd.btf = btf;
760624
dd.func_info = func_info;
761-
dd.finfo_rec_size = finfo_rec_size;
625+
dd.finfo_rec_size = info->func_info_rec_size;
762626
dd.prog_linfo = prog_linfo;
763627

764628
if (json_output)
765-
dump_xlated_json(&dd, buf, *member_len, opcodes,
629+
dump_xlated_json(&dd, buf, member_len, opcodes,
766630
linum);
767631
else
768-
dump_xlated_plain(&dd, buf, *member_len, opcodes,
632+
dump_xlated_plain(&dd, buf, member_len, opcodes,
769633
linum);
770634
kernel_syms_destroy(&dd);
771635
}
772636

773-
free(buf);
774-
free(func_ksyms);
775-
free(func_lens);
776-
free(func_info);
777-
free(linfo);
778-
free(jited_linfo);
779-
bpf_prog_linfo__free(prog_linfo);
637+
free(info_linear);
780638
return 0;
781639

782640
err_free:
783-
free(buf);
784-
free(func_ksyms);
785-
free(func_lens);
786-
free(func_info);
787-
free(linfo);
788-
free(jited_linfo);
789-
bpf_prog_linfo__free(prog_linfo);
641+
free(info_linear);
790642
return -1;
791643
}
792644

0 commit comments

Comments
 (0)