kernel: allow to access Task.netns without taking Task.mu

This allows to avoind unnecessary lock-ordering dependencies on task.mu.
This commit is contained in:
Andrei Vagin 2021-09-23 18:14:10 -07:00
parent 586f147cd6
commit dcbbd67cac
5 changed files with 19 additions and 12 deletions

View File

@ -1,13 +1,26 @@
load("//tools:defs.bzl", "go_library")
load("//tools/go_generics:defs.bzl", "go_template_instance")
package(
default_visibility = ["//:sandbox"],
licenses = ["notice"],
)
go_template_instance(
name = "atomicptr_netns",
out = "atomicptr_netns_unsafe.go",
package = "inet",
prefix = "Namespace",
template = "//pkg/sync/atomicptr:generic_atomicptr",
types = {
"Value": "Namespace",
},
)
go_library(
name = "inet",
srcs = [
"atomicptr_netns_unsafe.go",
"context.go",
"inet.go",
"namespace.go",

View File

@ -513,7 +513,7 @@ type Task struct {
// netns is the task's network namespace. netns is never nil.
//
// netns is protected by mu.
netns *inet.Namespace
netns inet.NamespaceAtomicPtr
// If rseqPreempted is true, before the next call to p.Switch(),
// interrupt rseq critical regions as defined by rseqAddr and

View File

@ -444,7 +444,7 @@ func (t *Task) Unshare(flags int32) error {
t.mu.Unlock()
return linuxerr.EPERM
}
t.netns = inet.NewNamespace(t.netns)
t.netns.Store(inet.NewNamespace(t.netns.Load()))
}
if flags&linux.CLONE_NEWUTS != 0 {
if !haveCapSysAdmin {

View File

@ -20,9 +20,7 @@ import (
// IsNetworkNamespaced returns true if t is in a non-root network namespace.
func (t *Task) IsNetworkNamespaced() bool {
t.mu.Lock()
defer t.mu.Unlock()
return !t.netns.IsRoot()
return !t.netns.Load().IsRoot()
}
// NetworkContext returns the network stack used by the task. NetworkContext
@ -31,14 +29,10 @@ func (t *Task) IsNetworkNamespaced() bool {
// TODO(gvisor.dev/issue/1833): Migrate callers of this method to
// NetworkNamespace().
func (t *Task) NetworkContext() inet.Stack {
t.mu.Lock()
defer t.mu.Unlock()
return t.netns.Stack()
return t.netns.Load().Stack()
}
// NetworkNamespace returns the network namespace observed by the task.
func (t *Task) NetworkNamespace() *inet.Namespace {
t.mu.Lock()
defer t.mu.Unlock()
return t.netns
return t.netns.Load()
}

View File

@ -140,7 +140,6 @@ func (ts *TaskSet) newTask(cfg *TaskConfig) (*Task, error) {
allowedCPUMask: cfg.AllowedCPUMask.Copy(),
ioUsage: &usage.IO{},
niceness: cfg.Niceness,
netns: cfg.NetworkNamespace,
utsns: cfg.UTSNamespace,
ipcns: cfg.IPCNamespace,
abstractSockets: cfg.AbstractSocketNamespace,
@ -152,6 +151,7 @@ func (ts *TaskSet) newTask(cfg *TaskConfig) (*Task, error) {
containerID: cfg.ContainerID,
cgroups: make(map[Cgroup]struct{}),
}
t.netns.Store(cfg.NetworkNamespace)
t.creds.Store(cfg.Credentials)
t.endStopCond.L = &t.tg.signalHandlers.mu
t.ptraceTracer.Store((*Task)(nil))