From 0686d815ab3aa5cfceb08ca9b2b16e8b7756ba1b Mon Sep 17 00:00:00 2001 From: xh4n3 Date: Tue, 5 Sep 2023 18:46:50 +0800 Subject: [PATCH] perf: do a binary search for kallsyms Signed-off-by: xh4n3 --- pkg/exporter/bpfutil/kallsyms.go | 50 ++++++++++++++++++--------- pkg/exporter/bpfutil/kallsyms_test.go | 20 +++++++++++ 2 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 pkg/exporter/bpfutil/kallsyms_test.go diff --git a/pkg/exporter/bpfutil/kallsyms.go b/pkg/exporter/bpfutil/kallsyms.go index 4fc182ea..1533dd4e 100644 --- a/pkg/exporter/bpfutil/kallsyms.go +++ b/pkg/exporter/bpfutil/kallsyms.go @@ -87,25 +87,43 @@ func GetSymPtFromBpfLocation(pt uint64) (*KernelSymbol, error) { if ok { return &sym, nil } - if pt > kallsyms[len(kallsyms)-1].start { - return nil, errors.New("addr out of range") + // since getAllSyms is already sorted, we can do a binary search here + var i, j, mid int + var midVal uint64 + j = len(kallsyms) - 1 + found := -1 + for i < j { + mid = i + (j-i)/2 + midVal = kallsyms[mid].start + if pt < midVal { + j = mid + } else if pt > midVal { + i = mid + 1 + } else { + found = mid + break + } } - - for idx := range kallsyms { - if kallsyms[idx].start <= pt && kallsyms[idx+1].start > pt { - ks := KernelSymbol{ - start: kallsyms[idx].start, - symboltype: kallsyms[idx].symbol, - symbol: kallsyms[idx].symbol, - offset: int(pt - kallsyms[idx].start), - module: kallsyms[idx].module, - } - locationCache.Add(pt, ks) - return &ks, nil + if found == -1 { + if i >= 1 && pt > kallsyms[i-1].start && pt < kallsyms[i].start { + found = i - 1 + } + if pt >= kallsyms[i].start { + found = i } } - - return nil, errors.New("addr not found") + if found == -1 { + return nil, errors.New("addr not found") + } + ks := KernelSymbol{ + start: kallsyms[found].start, + symboltype: kallsyms[found].symbol, + symbol: kallsyms[found].symbol, + offset: int(pt - kallsyms[found].start), + module: kallsyms[found].module, + } + locationCache.Add(pt, ks) + return &ks, nil } func getAllSyms() error { diff --git a/pkg/exporter/bpfutil/kallsyms_test.go b/pkg/exporter/bpfutil/kallsyms_test.go new file mode 100644 index 00000000..e4005198 --- /dev/null +++ b/pkg/exporter/bpfutil/kallsyms_test.go @@ -0,0 +1,20 @@ +package bpfutil + +import ( + "math/rand" + "testing" + "time" +) + +func TestGetSymPtFromBpfLocation(t *testing.T) { + now := time.Now() + for i := 0; i < len(kallsyms)-1; i++ { + offset := rand.Intn(100) + _, err := GetSymPtFromBpfLocation(kallsyms[i].start + uint64(offset)) + if err != nil { + t.Fatal("failed to get symbol point", kallsyms[i], err) + } + } + t1 := time.Now() + t.Logf("time cost: %v\n", t1.Sub(now)) +}