mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
kernel: use lockdep mutexes
PiperOrigin-RevId: 449877248
This commit is contained in:
@@ -1,8 +1,65 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test", "proto_library")
|
||||
load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
load("//pkg/sync/locking:locking.bzl", "declare_mutex", "declare_rwmutex")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
declare_mutex(
|
||||
name = "user_counters_mutex",
|
||||
out = "user_counters_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "userCounters",
|
||||
)
|
||||
|
||||
declare_rwmutex(
|
||||
name = "taskset_mutex",
|
||||
out = "taskset_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "taskSet",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "task_mutex",
|
||||
out = "task_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "task",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "cgroup_mutex",
|
||||
out = "cgroup_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "cgroup",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "fd_table_mutex",
|
||||
out = "fd_table_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "fdTable",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "running_tasks_mutex",
|
||||
out = "running_tasks_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "runningTasks",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "signal_handlers_mutex",
|
||||
out = "signal_handlers_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "signalHandlers",
|
||||
)
|
||||
|
||||
declare_mutex(
|
||||
name = "thread_group_timer_mutex",
|
||||
out = "thread_group_timer_mutex.go",
|
||||
package = "kernel",
|
||||
prefix = "threadGroupTimer",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "pending_signals_list",
|
||||
out = "pending_signals_list.go",
|
||||
@@ -142,8 +199,10 @@ go_library(
|
||||
"abstract_socket_namespace.go",
|
||||
"aio.go",
|
||||
"cgroup.go",
|
||||
"cgroup_mutex.go",
|
||||
"context.go",
|
||||
"fd_table.go",
|
||||
"fd_table_mutex.go",
|
||||
"fd_table_refs.go",
|
||||
"fd_table_unsafe.go",
|
||||
"fs_context.go",
|
||||
@@ -165,6 +224,7 @@ go_library(
|
||||
"ptrace_amd64.go",
|
||||
"ptrace_arm64.go",
|
||||
"rseq.go",
|
||||
"running_tasks_mutex.go",
|
||||
"seccheck.go",
|
||||
"seccomp.go",
|
||||
"seqatomic_taskgoroutineschedinfo_unsafe.go",
|
||||
@@ -173,6 +233,7 @@ go_library(
|
||||
"sessions.go",
|
||||
"signal.go",
|
||||
"signal_handlers.go",
|
||||
"signal_handlers_mutex.go",
|
||||
"socket_list.go",
|
||||
"syscalls.go",
|
||||
"syscalls_state.go",
|
||||
@@ -190,6 +251,7 @@ go_library(
|
||||
"task_image.go",
|
||||
"task_list.go",
|
||||
"task_log.go",
|
||||
"task_mutex.go",
|
||||
"task_net.go",
|
||||
"task_run.go",
|
||||
"task_sched.go",
|
||||
@@ -199,12 +261,15 @@ go_library(
|
||||
"task_syscall.go",
|
||||
"task_usermem.go",
|
||||
"task_work.go",
|
||||
"taskset_mutex.go",
|
||||
"thread_group.go",
|
||||
"thread_group_timer_mutex.go",
|
||||
"threads.go",
|
||||
"threads_impl.go",
|
||||
"timekeeper.go",
|
||||
"timekeeper_state.go",
|
||||
"tty.go",
|
||||
"user_counters_mutex.go",
|
||||
"uts_namespace.go",
|
||||
"vdso.go",
|
||||
"version.go",
|
||||
@@ -286,6 +351,7 @@ go_library(
|
||||
"//pkg/state/statefile",
|
||||
"//pkg/state/wire",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
"//pkg/syserr",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/stack",
|
||||
|
||||
@@ -42,6 +42,17 @@ go_template_instance(
|
||||
},
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "user_namespace_mutex",
|
||||
out = "user_namespace_mutex.go",
|
||||
package = "auth",
|
||||
prefix = "userNamespace",
|
||||
substrs = {
|
||||
"genericMark": "userNamespace",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "auth",
|
||||
srcs = [
|
||||
@@ -56,6 +67,7 @@ go_library(
|
||||
"id_map_range.go",
|
||||
"id_map_set.go",
|
||||
"user_namespace.go",
|
||||
"user_namespace_mutex.go",
|
||||
],
|
||||
marshal = True,
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
@@ -68,5 +80,6 @@ go_library(
|
||||
"//pkg/sentry/seccheck",
|
||||
"//pkg/sentry/seccheck/points:points_go_proto",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -69,8 +69,8 @@ func (ns *UserNamespace) mapID(m *idMapSet, id uint32) uint32 {
|
||||
//
|
||||
// Preconditions: end >= start.
|
||||
func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool {
|
||||
ns.mu.Lock()
|
||||
defer ns.mu.Unlock()
|
||||
ns.mu.NestedLock()
|
||||
defer ns.mu.NestedUnlock()
|
||||
return m.SpanRange(idMapRange{start, end}) == end-start
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// A UserNamespace represents a user namespace. See user_namespaces(7) for
|
||||
@@ -38,7 +37,7 @@ type UserNamespace struct {
|
||||
//
|
||||
// If mu will be locked in multiple UserNamespaces, it must be locked in
|
||||
// descendant namespaces before ancestors.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu userNamespaceMutex `state:"nosave"`
|
||||
|
||||
// Mappings of user/group IDs between this namespace and its parent.
|
||||
//
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// InvalidCgroupHierarchyID indicates an uninitialized hierarchy ID.
|
||||
@@ -218,7 +217,7 @@ type CgroupRegistry struct {
|
||||
//
|
||||
lastHierarchyID atomicbitops.Uint32
|
||||
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu cgroupMutex `state:"nosave"`
|
||||
|
||||
// controllers is the set of currently known cgroup controllers on the
|
||||
// system. Protected by mu.
|
||||
|
||||
@@ -3,6 +3,28 @@ load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_template_instance(
|
||||
name = "epoll_mutex",
|
||||
out = "epoll_mutex.go",
|
||||
package = "epoll",
|
||||
prefix = "epoll",
|
||||
substrs = {
|
||||
"genericMark": "epoll",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "epoll_list_mutex",
|
||||
out = "epoll_list_mutex.go",
|
||||
package = "epoll",
|
||||
prefix = "epollList",
|
||||
substrs = {
|
||||
"genericMark": "epollList",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "epoll_list",
|
||||
out = "epoll_list.go",
|
||||
@@ -20,6 +42,8 @@ go_library(
|
||||
srcs = [
|
||||
"epoll.go",
|
||||
"epoll_list.go",
|
||||
"epoll_list_mutex.go",
|
||||
"epoll_mutex.go",
|
||||
"epoll_state.go",
|
||||
],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
@@ -31,6 +55,7 @@ go_library(
|
||||
"//pkg/sentry/fs/anon",
|
||||
"//pkg/sentry/fs/fsutil",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
|
||||
@@ -109,7 +109,7 @@ type EventPoll struct {
|
||||
|
||||
// files is the map of all the files currently being observed, it is
|
||||
// protected by mu.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu epollMutex `state:"nosave"`
|
||||
files map[FileIdentifier]*pollEntry
|
||||
|
||||
// listsMu protects manipulation of the lists below. It needs to be a
|
||||
@@ -129,7 +129,7 @@ type EventPoll struct {
|
||||
// called on it before it gets moved to the readyList.
|
||||
// disabledList -- when the entry is disabled. This happens when
|
||||
// a one-shot entry gets delivered via readEvents().
|
||||
listsMu sync.Mutex `state:"nosave"`
|
||||
listsMu epollListMutex `state:"nosave"`
|
||||
readyList pollEntryList
|
||||
waitingList pollEntryList
|
||||
disabledList pollEntryList
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/lock"
|
||||
"gvisor.dev/gvisor/pkg/sentry/limits"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// FDFlags define flags for an individual descriptor.
|
||||
@@ -85,7 +84,7 @@ type FDTable struct {
|
||||
k *Kernel
|
||||
|
||||
// mu protects below.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu fdTableMutex `state:"nosave"`
|
||||
|
||||
// fdBitmap shows which fds are already in use.
|
||||
fdBitmap bitmap.Bitmap `state:"nosave"`
|
||||
|
||||
@@ -3,6 +3,17 @@ load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_template_instance(
|
||||
name = "futex_mutex",
|
||||
out = "futex_mutex.go",
|
||||
package = "futex",
|
||||
prefix = "futexBucket",
|
||||
substrs = {
|
||||
"genericMark": "futexBucket",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "atomicptr_bucket",
|
||||
out = "atomicptr_bucket_unsafe.go",
|
||||
@@ -31,6 +42,7 @@ go_library(
|
||||
srcs = [
|
||||
"atomicptr_bucket_unsafe.go",
|
||||
"futex.go",
|
||||
"futex_mutex.go",
|
||||
"waiter_list.go",
|
||||
],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
@@ -42,6 +54,7 @@ go_library(
|
||||
"//pkg/log",
|
||||
"//pkg/sentry/memmap",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
"//pkg/usermem",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// KeyKind indicates the type of a Key.
|
||||
@@ -252,7 +251,7 @@ func (w *Waiter) woken() bool {
|
||||
// +stateify savable
|
||||
type bucket struct {
|
||||
// mu protects waiters and contained Waiter state. See comment in Waiter.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu futexBucketMutex `state:"nosave"`
|
||||
|
||||
waiters waiterList `state:"zerovalue"`
|
||||
}
|
||||
@@ -426,10 +425,10 @@ func (m *Manager) lockBuckets(k1, k2 *Key) (b1 *bucket, b2 *bucket) {
|
||||
switch {
|
||||
case i1 < i2:
|
||||
b1.mu.Lock()
|
||||
b2.mu.Lock()
|
||||
b2.mu.NestedLock()
|
||||
case i2 < i1:
|
||||
b2.mu.Lock()
|
||||
b1.mu.Lock()
|
||||
b1.mu.NestedLock()
|
||||
default:
|
||||
b1.mu.Lock()
|
||||
}
|
||||
@@ -452,7 +451,7 @@ func (m *Manager) lockBuckets(k1, k2 *Key) (b1 *bucket, b2 *bucket) {
|
||||
// +checklocksrelease:b1.mu
|
||||
// +checklocksrelease:b2.mu
|
||||
func (m *Manager) unlockBuckets(b1, b2 *bucket) {
|
||||
b1.mu.Unlock()
|
||||
b1.mu.NestedUnlock()
|
||||
if b1 != b2 {
|
||||
b2.mu.Unlock()
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ type Kernel struct {
|
||||
// runningTasksMu is used to exclude critical sections when the timer
|
||||
// disables itself and when the first active task enables the timer,
|
||||
// ensuring that tasks always see a valid cpuClock value.
|
||||
runningTasksMu sync.Mutex `state:"nosave"`
|
||||
runningTasksMu runningTasksMutex `state:"nosave"`
|
||||
|
||||
// runningTasks is the total count of tasks currently in
|
||||
// TaskGoroutineRunningSys or TaskGoroutineRunningApp. i.e., they are
|
||||
@@ -330,9 +330,9 @@ type Kernel struct {
|
||||
// the system.
|
||||
cgroupRegistry *CgroupRegistry
|
||||
|
||||
// userCountersMa maps auth.KUID into a set of user counters.
|
||||
// userCountersMap maps auth.KUID into a set of user counters.
|
||||
userCountersMap map[auth.KUID]*userCounters
|
||||
userCountersMapMu sync.Mutex `state:"nosave"`
|
||||
userCountersMapMu userCountersMutex `state:"nosave"`
|
||||
}
|
||||
|
||||
// InitKernelArgs holds arguments to Init.
|
||||
|
||||
@@ -1,13 +1,49 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_template_instance(
|
||||
name = "vfs_mutex",
|
||||
out = "vfs_mutex.go",
|
||||
package = "pipe",
|
||||
prefix = "vfs",
|
||||
substrs = {
|
||||
"genericMark": "vfs",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "pipe_mutex",
|
||||
out = "pipe_mutex.go",
|
||||
package = "pipe",
|
||||
prefix = "pipe",
|
||||
substrs = {
|
||||
"genericMark": "pipe",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_template_instance(
|
||||
name = "inode_mutex",
|
||||
out = "inode_mutex.go",
|
||||
package = "pipe",
|
||||
prefix = "inode",
|
||||
substrs = {
|
||||
"genericMark": "inode",
|
||||
},
|
||||
template = "//pkg/sync/locking:generic_mutex",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "pipe",
|
||||
srcs = [
|
||||
"device.go",
|
||||
"inode_mutex.go",
|
||||
"node.go",
|
||||
"pipe.go",
|
||||
"pipe_mutex.go",
|
||||
"pipe_unsafe.go",
|
||||
"pipe_util.go",
|
||||
"reader.go",
|
||||
@@ -31,6 +67,7 @@ go_library(
|
||||
"//pkg/sentry/fs/fsutil",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/safemem"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
@@ -132,7 +131,7 @@ type Pipe struct {
|
||||
totalWriters atomicbitops.Int32
|
||||
|
||||
// mu protects all pipe internal state below.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu pipeMutex `state:"nosave"`
|
||||
|
||||
// buf holds the pipe's data. buf is a circular buffer; the first valid
|
||||
// byte in buf is at offset off, and the pipe contains size valid bytes.
|
||||
|
||||
@@ -29,9 +29,9 @@ func lockTwoPipes(x, y *Pipe) {
|
||||
// Lock the two pipes in order of increasing address.
|
||||
if uintptr(unsafe.Pointer(x)) < uintptr(unsafe.Pointer(y)) {
|
||||
x.mu.Lock()
|
||||
y.mu.Lock()
|
||||
y.mu.NestedLock()
|
||||
} else {
|
||||
y.mu.Lock()
|
||||
x.mu.Lock()
|
||||
x.mu.NestedLock()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ func spliceOrTee(ctx context.Context, dst, src *VFSPipeFD, count int64, removeFr
|
||||
return uint64(n), err
|
||||
})
|
||||
dst.pipe.mu.Unlock()
|
||||
src.pipe.mu.Unlock()
|
||||
src.pipe.mu.NestedUnlock()
|
||||
|
||||
if n > 0 {
|
||||
dst.pipe.queue.Notify(waiter.ReadableEvents)
|
||||
|
||||
@@ -202,11 +202,11 @@ func (pg *ProcessGroup) handleOrphan() {
|
||||
if tg.processGroup != pg {
|
||||
return
|
||||
}
|
||||
tg.signalHandlers.mu.Lock()
|
||||
tg.signalHandlers.mu.NestedLock()
|
||||
if tg.groupStopComplete {
|
||||
hasStopped = true
|
||||
}
|
||||
tg.signalHandlers.mu.Unlock()
|
||||
tg.signalHandlers.mu.NestedUnlock()
|
||||
})
|
||||
if !hasStopped {
|
||||
return
|
||||
@@ -217,10 +217,10 @@ func (pg *ProcessGroup) handleOrphan() {
|
||||
if tg.processGroup != pg {
|
||||
return
|
||||
}
|
||||
tg.signalHandlers.mu.Lock()
|
||||
tg.signalHandlers.mu.NestedLock()
|
||||
tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGHUP), true /* group */)
|
||||
tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGCONT), true /* group */)
|
||||
tg.signalHandlers.mu.Unlock()
|
||||
tg.signalHandlers.mu.NestedUnlock()
|
||||
})
|
||||
|
||||
return
|
||||
|
||||
@@ -16,7 +16,6 @@ package kernel
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// SignalHandlers holds information about signal actions.
|
||||
@@ -26,7 +25,7 @@ type SignalHandlers struct {
|
||||
// mu protects actions, as well as the signal state of all tasks and thread
|
||||
// groups using this SignalHandlers object. (See comment on
|
||||
// ThreadGroup.signalHandlers.)
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu signalHandlersMutex `state:"nosave"`
|
||||
|
||||
// actions is the action to be taken upon receiving each signal.
|
||||
actions map[linux.Signal]linux.SigAction
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
load("//tools:defs.bzl", "go_library")
|
||||
load("//pkg/sync/locking:locking.bzl", "declare_mutex")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
declare_mutex(
|
||||
name = "signal_operations_mutex",
|
||||
out = "signal_operations_mutex.go",
|
||||
package = "signalfd",
|
||||
prefix = "operations",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "signalfd",
|
||||
srcs = ["signalfd.go"],
|
||||
srcs = [
|
||||
"signal_operations_mutex.go",
|
||||
"signalfd.go",
|
||||
],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
@@ -15,6 +26,7 @@ go_library(
|
||||
"//pkg/sentry/fs/fsutil",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sync",
|
||||
"//pkg/sync/locking",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
@@ -55,7 +54,7 @@ type SignalOperations struct {
|
||||
queue waiter.Queue
|
||||
|
||||
// mu protects below.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu operationsMutex `state:"nosave"`
|
||||
|
||||
// entry is the entry reigstered with the target.
|
||||
entry waiter.Entry
|
||||
|
||||
@@ -255,7 +255,7 @@ type Task struct {
|
||||
containerID string
|
||||
|
||||
// mu protects some of the following fields.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
mu taskMutex `state:"nosave"`
|
||||
|
||||
// image holds task data provided by the ELF loader.
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user