mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Reduce the cost of sysinfo(2).
- sysinfo(2) does not actually require a fine-grained breakdown of memory usage. Accordingly, instead of calling pgalloc.MemoryFile.UpdateUsage() to update the sentry's fine-grained memory accounting snapshot, just use pgalloc.MemoryFile.TotalUsage() (which is a single fstat(), and therefore far cheaper). - Use the number of threads in the root PID namespace (i.e. globally) rather than in the task's PID namespace for consistency with Linux (which just reads global variable nr_threads), and add a new method to kernel.PIDNamespace to allow this to be read directly from an underlying map rather than requiring the allocation and population of an intermediate slice. PiperOrigin-RevId: 336353100
This commit is contained in:
@@ -265,6 +265,13 @@ func (ns *PIDNamespace) Tasks() []*Task {
|
||||
return tasks
|
||||
}
|
||||
|
||||
// NumTasks returns the number of tasks in ns.
|
||||
func (ns *PIDNamespace) NumTasks() int {
|
||||
ns.owner.mu.RLock()
|
||||
defer ns.owner.mu.RUnlock()
|
||||
return len(ns.tids)
|
||||
}
|
||||
|
||||
// ThreadGroups returns a snapshot of the thread groups in ns.
|
||||
func (ns *PIDNamespace) ThreadGroups() []*ThreadGroup {
|
||||
return ns.ThreadGroupsAppend(nil)
|
||||
|
||||
@@ -26,8 +26,12 @@ func Sysinfo(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca
|
||||
addr := args[0].Pointer()
|
||||
|
||||
mf := t.Kernel().MemoryFile()
|
||||
mf.UpdateUsage()
|
||||
_, totalUsage := usage.MemoryAccounting.Copy()
|
||||
mfUsage, err := mf.TotalUsage()
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
memStats, _ := usage.MemoryAccounting.Copy()
|
||||
totalUsage := mfUsage + memStats.Mapped
|
||||
totalSize := usage.TotalMemory(mf.TotalSize(), totalUsage)
|
||||
memFree := totalSize - totalUsage
|
||||
if memFree > totalSize {
|
||||
@@ -37,12 +41,12 @@ func Sysinfo(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca
|
||||
|
||||
// Only a subset of the fields in sysinfo_t make sense to return.
|
||||
si := linux.Sysinfo{
|
||||
Procs: uint16(len(t.PIDNamespace().Tasks())),
|
||||
Procs: uint16(t.Kernel().TaskSet().Root.NumTasks()),
|
||||
Uptime: t.Kernel().MonotonicClock().Now().Seconds(),
|
||||
TotalRAM: totalSize,
|
||||
FreeRAM: memFree,
|
||||
Unit: 1,
|
||||
}
|
||||
_, err := si.CopyOut(t, addr)
|
||||
_, err = si.CopyOut(t, addr)
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user