Commit Graph
8 Commits
Author SHA1 Message Date
Adin ScannellandgVisor bot 2911d8c3b8 Add default_applicable_licenses rules to packages.
PiperOrigin-RevId: 513581243
2023-03-02 10:50:04 -08:00
Adin ScannellandgVisor bot 8f1c2481b7 Update checklinkname to avoid hard-coded names.
PiperOrigin-RevId: 510524474
2023-02-17 14:40:10 -08:00
Kevin KrakauerandgVisor bot 3a76efe831 convert uses of interface{} to any
Done via:
  find . -name "*.go" | xargs sed -i -E 's/interface\{\}/any/g'

PiperOrigin-RevId: 487033228
2022-11-08 13:14:06 -08:00
Andrei VaginandgVisor bot 4ab6e27a69 Internal change
PiperOrigin-RevId: 477905095
2022-09-29 22:51:40 -07:00
Ayush RanjanandgVisor bot 2987d9cb0a Simplify codebase.
Ran gofmt -w -s ./

PiperOrigin-RevId: 449415155
2022-05-18 00:56:31 -07:00
Etienne PerotandgVisor bot 4a0488fa49 Sentry: Implement timer metrics.
Timer metrics are metrics that measure nanosecond-precision operations within
the sentry, and present the results in an aggregated manner using distribution
bucketing.

They have a more convenient API than using distribution metrics directly, but
otherwise are just a convenient wrapper on top of them.

This requires exposing `runtime.nanotime()` from the Go runtime in order to
get the current time without causing system calls.

Intended usage:

```go
m := NewTimerMetric(...)
...
op := m.Start()  // Starts measuring time from this point
... do something interesting...
op.Finish()      // End the stopwatch.
```

Operation structs are meant to be self-contained to be able to be passed
around in code. Additionally, the timer metrics support multiple fields,
specifiable both at operation `Start` and `Finish` time.
This can be useful for measuring operations that can go down multiple
distinct branches, and creating aggregates that can selectively
differentiate between them. For example:

```go
m := NewTimerMetric("/packet_processing_time", ..., "protocol", "path")
...
func HandleTCPPacket(pkt TCPPacket) {
  op := m.Start("tcp")
  if fast path {
    ... do fast TCP handling...
    op.Finish("fast")
    return
  }
  doSlowTCPHandling(pkt, op)  // `op` can be passed around
}
func doSlowTCPHandling(pkt TCPPacket, op TimerOperation) {
  ... do slow TCP handling...
  op.Finish("slow")
}
func HandleUDPPacket(pkt UDPPacket) {
  op := m.Start("udp")
  ... do UDP packet handling...
  op.Finish("")
}
```
PiperOrigin-RevId: 436641265
2022-03-22 20:59:48 -07:00
Adin ScannellandgVisor bot d1281902ba Support synchronous AssertAndFetch for sleep package.
Some synchronization patterns require the ability to simultaneously wake and
sleep a goroutine. For the sleep package, this is the case when a waker must be
asserted when a subsequent fetch is imminent.

Currently, this operation results in significant P churn in the runtime, which
ping-pongs execution between multiple system threads and cores and consumes a
significant amount of host CPU (and because of the context switches, this can
be significant worse with mitigations for side channel vulnerabilities).

The solution is to introduce a dedicated mechanism for a synchronous switch
which does not wake another runtime P (see golang/go#32113). This can be used
by the `AssertAndFetch` API in the sleep package.

The benchmark results for this package are very similiar to raw channel
operations for all cases, with the exception of operations that do not wait.
The primary advantage is more precise control over scheduling. This will be
used in a subsequent change.

```
BenchmarkGoAssertNonWaiting
BenchmarkGoAssertNonWaiting-8                   261364384                4.976 ns/op
BenchmarkGoSingleSelect
BenchmarkGoSingleSelect-8                       20946358                57.77 ns/op
BenchmarkGoMultiSelect
BenchmarkGoMultiSelect-8                         6071697               197.0 ns/op
BenchmarkGoWaitOnSingleSelect
BenchmarkGoWaitOnSingleSelect-8                  4978051               235.4 ns/op
BenchmarkGoWaitOnMultiSelect
BenchmarkGoWaitOnMultiSelect-8                   2309224               520.2 ns/op

BenchmarkSleeperAssertNonWaiting
BenchmarkSleeperAssertNonWaiting-8              447325033                2.657 ns/op
BenchmarkSleeperSingleSelect
BenchmarkSleeperSingleSelect-8                  21488844                55.19 ns/op
BenchmarkSleeperMultiSelect
BenchmarkSleeperMultiSelect-8                   21851674                54.89 ns/op
BenchmarkSleeperWaitOnSingleSelect
BenchmarkSleeperWaitOnSingleSelect-8             2860327               416.4 ns/op
BenchmarkSleeperWaitOnSingleSelectSync
BenchmarkSleeperWaitOnSingleSelectSync-8         2741733               427.1 ns/op
BenchmarkSleeperWaitOnMultiSelect
BenchmarkSleeperWaitOnMultiSelect-8              2867484               418.1 ns/op
BenchmarkSleeperWaitOnMultiSelectSync
BenchmarkSleeperWaitOnMultiSelectSync-8          2789158               427.9 ns/op
```

PiperOrigin-RevId: 415581417
2021-12-10 12:25:25 -08:00
Michael PrattandgVisor bot d25dccd2f8 checklinkname: rudimentary type-checking of linkname directives
This CL introduces a 'checklinkname' analyzer, which provides rudimentary
type-checking that verifies that function signatures on the local and remote
sides of //go:linkname directives match expected values.

If the Go standard library changes the definitions of any of these function,
checklinkname will flag the change as a finding, providing an error informing
the gVisor team to adapt to the upstream changes. This allows us to eliminate
the majority of gVisor's forward-looking negative build tags, as we can catch
mismatches in testing [1].

The remaining forward-looking negative build tags are covering shared struct
definitions, which I hope to add to checklinkname in a future CL.

[1] Of course, semantics/requirements can change without the signature
changing, so we still must be careful, but this covers the common case.

PiperOrigin-RevId: 387873847
2021-07-30 13:42:15 -07:00