Unimplemented syscall counter: Pre-allocate 1-element slices of field values.

This is necessary in order to avoid a heap allocation when calling
`unimplementedSyscallCounter.Increment`. Prior to this CL, this code actually
allocated a 1-element slice, because the `Increment` method takes in a
variadic number of arguments.

Somehow this had not tripped up the `+checkescape` check at submission time,
but running `nogo` manually confirms the problem. This CL fixes it.

PiperOrigin-RevId: 539737956
This commit is contained in:
Etienne Perot
2023-06-12 13:02:43 -07:00
committed by gVisor bot
parent 8ec8dbe7e8
commit bb105d7a4e
+10 -7
View File
@@ -43,7 +43,7 @@ const (
// outOfRangeSyscallNumber is used to represent a syscall number that is out of the
// range [0, maxSyscallNum] in monitoring.
var outOfRangeSyscallNumber = metric.FieldValue{"-1"}
var outOfRangeSyscallNumber = []*metric.FieldValue{&metric.FieldValue{"-1"}}
// SyscallSupportLevel is a syscall support levels.
type SyscallSupportLevel int
@@ -359,7 +359,10 @@ var (
// unimplementedSyscallNumbers maps syscall numbers to their string representation.
// Used such that incrementing unimplementedSyscallCounter does not require allocating memory.
unimplementedSyscallNumbers map[uintptr]*metric.FieldValue
// Each element in the mapped slices are of length 1, as there is only one field for the
// unimplemented syscall counter metric. Allocating a slice is necessary as it is passed as a
// variadic argument to the metric library.
unimplementedSyscallNumbers map[uintptr][]*metric.FieldValue
// unimplementedSyscallCounter tracks the number of times each unimplemented syscall has been
// called by the sandboxed application.
@@ -392,13 +395,13 @@ func RegisterSyscallTable(s *SyscallTable) {
allSyscallTables = append(allSyscallTables, s)
unimplementedSyscallCounterInit.Do(func() {
allowedValues := make([]*metric.FieldValue, maxSyscallNum+2)
unimplementedSyscallNumbers = make(map[uintptr]*metric.FieldValue, len(allowedValues))
unimplementedSyscallNumbers = make(map[uintptr][]*metric.FieldValue, len(allowedValues))
for i := uintptr(0); i <= maxSyscallNum; i++ {
s := &metric.FieldValue{strconv.Itoa(int(i))}
allowedValues[i] = s
unimplementedSyscallNumbers[i] = s
unimplementedSyscallNumbers[i] = []*metric.FieldValue{s}
}
allowedValues[len(allowedValues)-1] = &outOfRangeSyscallNumber
allowedValues[len(allowedValues)-1] = outOfRangeSyscallNumber[0]
unimplementedSyscallCounter = metric.MustCreateNewUint64Metric("unimplemented_syscalls", true, "Number of times the application tried to call an unimplemented syscall, broken down by syscall number", metric.NewField("sysno", allowedValues...))
})
s.Init()
@@ -501,7 +504,7 @@ type SyscallInfo struct {
func IncrementUnimplementedSyscallCounter(sysno uintptr) {
s, found := unimplementedSyscallNumbers[sysno]
if !found {
s = &outOfRangeSyscallNumber
s = outOfRangeSyscallNumber
}
unimplementedSyscallCounter.Increment(s)
unimplementedSyscallCounter.Increment(s...)
}