Skip to content

Commit

Permalink
v8: only remove prefix when mapping is removed
Browse files Browse the repository at this point in the history
prior to this change we were tracking generation number (i.e.
count of SynchronizeMappings call where the object was found) for
both mappings and prefixes.

if the mapping did not change, we would not re-calculate prefixes
for the mapping, hence we would not increase the generation of the
prefix object.

as such, we would end up cleaning the prefix on the second call of
SynchronizeMappings (if mappings did not change), removing the prefix
from the ebpf map, and making unwinding fail for PC in the JIT area.

to fix this, we only track the generation for mappings. when mappings
are removed, we computed all the prefixes associated to those mappings
and we remove them. this should be safe because different mappings
should have different prefixes.
  • Loading branch information
Gandem committed Jul 19, 2024
1 parent a4c5383 commit 4b30e4f
Showing 1 changed file with 12 additions and 13 deletions.
25 changes: 12 additions & 13 deletions interpreter/nodev8/v8.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,8 @@ type v8Instance struct {

// mappings is indexed by the Mapping to its generation
mappings map[process.Mapping]uint32
// prefixes is indexed by the prefix added to ebpf maps (to be cleaned up) to its generation
prefixes map[lpm.Prefix]uint32
// prefixes is indexed by the prefix added to ebpf maps (to be cleaned up)
prefixes map[lpm.Prefix]struct{}
// mappingGeneration is the current generation (so old entries can be pruned)
mappingGeneration uint32
}
Expand Down Expand Up @@ -573,30 +573,29 @@ func (i *v8Instance) SynchronizeMappings(ebpf interpreter.EbpfHandler,

for _, prefix := range prefixes {
if _, exists := i.prefixes[prefix]; exists {
i.prefixes[prefix] = i.mappingGeneration
continue
}
err := ebpf.UpdatePidInterpreterMapping(pid, prefix, support.ProgUnwindV8, 0, 0)
if err != nil {
return err
}
i.prefixes[prefix] = i.mappingGeneration
i.prefixes[prefix] = struct{}{}
}
}

// Remove prefixes not seen
for prefix, generation := range i.prefixes {
if generation == i.mappingGeneration {
continue
}
_ = ebpf.DeletePidInterpreterMapping(pid, prefix)
delete(i.prefixes, prefix)
}
for m, generation := range i.mappings {
if generation == i.mappingGeneration {
continue
}
log.Debugf("Disabling V8 for %#x/%#x", m.Vaddr, m.Length)
prefixes, err := lpm.CalculatePrefixList(m.Vaddr, m.Vaddr+m.Length)
if err != nil {
return fmt.Errorf("new anonymous mapping lpm failure %#x/%#x", m.Vaddr, m.Length)
}
for _, prefix := range prefixes {
_ = ebpf.DeletePidInterpreterMapping(pid, prefix)
delete(i.prefixes, prefix)
}
delete(i.mappings, m)
}

Expand Down Expand Up @@ -1820,7 +1819,7 @@ func (d *v8Data) Attach(ebpf interpreter.EbpfHandler, pid util.PID, _ libpf.Addr
d: d,
rm: rm,
mappings: make(map[process.Mapping]uint32),
prefixes: make(map[lpm.Prefix]uint32),
prefixes: make(map[lpm.Prefix]struct{}),
addrToString: addrToString,
addrToCode: addrToCode,
addrToSFI: addrToSFI,
Expand Down

0 comments on commit 4b30e4f

Please sign in to comment.