Skip to content

Commit

Permalink
Merge pull request #104 from xh4n3/kallsyms-binary-search
Browse files Browse the repository at this point in the history
perf: use a binary search for kallsyms lookup
  • Loading branch information
Lyt99 authored Sep 5, 2023
2 parents 6e62502 + 0686d81 commit 67be2b8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 16 deletions.
50 changes: 34 additions & 16 deletions pkg/exporter/bpfutil/kallsyms.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
20 changes: 20 additions & 0 deletions pkg/exporter/bpfutil/kallsyms_test.go
Original file line number Diff line number Diff line change
@@ -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))
}

0 comments on commit 67be2b8

Please sign in to comment.