github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/fsmetric/fsmetric.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package fsmetric defines filesystem metrics. 16 package fsmetric 17 18 import ( 19 "time" 20 21 "github.com/metacubex/gvisor/pkg/metric" 22 ) 23 24 // RecordWaitTime enables the ReadWait, GoferReadWait9P, GoferReadWaitHost, and 25 // TmpfsReadWait metrics. Enabling this comes at a CPU cost due to performing 26 // three clock reads per read call. 27 // 28 // Note that this is only performed in the direct read path, and may not be 29 // consistently applied for other forms of reads, such as splice. 30 var RecordWaitTime = false 31 32 // Metrics that apply to all filesystems. 33 var ( 34 Opens = metric.MustCreateNewUint64Metric("/fs/opens", false /* sync */, "Number of file opens.") 35 Reads = metric.MustCreateNewUint64Metric("/fs/reads", false /* sync */, "Number of file reads.") 36 ReadWait = metric.MustCreateNewUint64NanosecondsMetric("/fs/read_wait", false /* sync */, "Time waiting on file reads, in nanoseconds.") 37 ) 38 39 // Metrics that only apply to fs/gofer and fsimpl/gofer. 40 var ( 41 GoferOpens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a file was opened from a gofer and did not have a host file descriptor.") 42 GoferOpensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a file was opened from a gofer and did have a host file descriptor.") 43 GoferReads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.") 44 GoferReadWait9P = metric.MustCreateNewUint64NanosecondsMetric("/gofer/read_wait_9p", false /* sync */, "Time waiting on 9P file reads from a gofer, in nanoseconds.") 45 GoferReadsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.") 46 GoferReadWaitHost = metric.MustCreateNewUint64NanosecondsMetric("/gofer/read_wait_host", false /* sync */, "Time waiting on host file reads from a gofer, in nanoseconds.") 47 ) 48 49 // Metrics that only apply to fs/tmpfs and fsimpl/tmpfs. 50 var ( 51 TmpfsOpensRO = metric.MustCreateNewUint64Metric("/in_memory_file/opens_ro", false /* sync */, "Number of times an in-memory file was opened in read-only mode.") 52 TmpfsOpensW = metric.MustCreateNewUint64Metric("/in_memory_file/opens_w", false /* sync */, "Number of times an in-memory file was opened in write mode.") 53 TmpfsReads = metric.MustCreateNewUint64Metric("/in_memory_file/reads", false /* sync */, "Number of in-memory file reads.") 54 TmpfsReadWait = metric.MustCreateNewUint64NanosecondsMetric("/in_memory_file/read_wait", false /* sync */, "Time waiting on in-memory file reads, in nanoseconds.") 55 ) 56 57 // StartReadWait indicates the beginning of a file read. 58 func StartReadWait() time.Time { 59 if !RecordWaitTime { 60 return time.Time{} 61 } 62 return time.Now() 63 } 64 65 // FinishReadWait indicates the end of a file read whose time is accounted by 66 // m. start must be the value returned by the corresponding call to 67 // StartReadWait. 68 // 69 // FinishReadWait is marked nosplit for performance since it's often called 70 // from defer statements, which prevents it from being inlined 71 // (https://github.com/golang/go/issues/38471). 72 // 73 //go:nosplit 74 func FinishReadWait(m *metric.Uint64Metric, start time.Time) { 75 if !RecordWaitTime { 76 return 77 } 78 m.IncrementBy(uint64(time.Since(start).Nanoseconds())) 79 }