mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
kernel: don't use atomic pointers for task.netns
task.netns is always changed from a task goroutine under task.mu. It means that we can access it without any locks from a task goroutine we don't need to increment a reference counter in such cases. In all other cases, we need to take task.mu. PiperOrigin-RevId: 552913323
This commit is contained in:
@@ -18,21 +18,9 @@ go_template_instance(
|
||||
},
|
||||
)
|
||||
|
||||
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",
|
||||
|
||||
@@ -508,8 +508,8 @@ type Task struct {
|
||||
|
||||
// netns is the task's network namespace. It has to be changed under mu
|
||||
// so that GetNetworkNamespace can take a reference before it is
|
||||
// released.
|
||||
netns inet.NamespaceAtomicPtr
|
||||
// released. It is changed only from the task goroutine.
|
||||
netns *inet.Namespace
|
||||
|
||||
// If rseqPreempted is true, before the next call to p.Switch(),
|
||||
// interrupt rseq critical regions as defined by rseqAddr and
|
||||
|
||||
@@ -126,7 +126,7 @@ func (t *Task) Clone(args *linux.CloneArgs) (ThreadID, *SyscallControl, error) {
|
||||
ipcns.DecRef(t)
|
||||
})
|
||||
|
||||
netns := t.netns.Load()
|
||||
netns := t.netns
|
||||
if args.Flags&linux.CLONE_NEWNET != 0 {
|
||||
netns = inet.NewNamespace(netns, userns)
|
||||
inode := nsfs.NewInode(t, t.k.nsfsMount, netns)
|
||||
@@ -444,7 +444,7 @@ func (t *Task) Setns(fd *vfs.FileDescription, flags int32) error {
|
||||
oldNS := t.NetworkNamespace()
|
||||
ns.IncRef()
|
||||
t.mu.Lock()
|
||||
t.netns.Store(ns)
|
||||
t.netns = ns
|
||||
t.mu.Unlock()
|
||||
oldNS.DecRef(t)
|
||||
return nil
|
||||
@@ -570,9 +570,10 @@ func (t *Task) Unshare(flags int32) error {
|
||||
netnsInode := nsfs.NewInode(t, t.k.nsfsMount, netns)
|
||||
netns.SetInode(netnsInode)
|
||||
t.mu.Lock()
|
||||
netns = t.netns.Swap(netns)
|
||||
oldNetns := t.netns
|
||||
t.netns = netns
|
||||
t.mu.Unlock()
|
||||
netns.DecRef(t)
|
||||
oldNetns.DecRef(t)
|
||||
}
|
||||
|
||||
cu := cleanup.Cleanup{}
|
||||
|
||||
@@ -288,7 +288,8 @@ func (*runExitMain) execute(t *Task) taskRunState {
|
||||
mntns := t.mountNamespace
|
||||
t.mountNamespace = nil
|
||||
ipcns := t.ipcns
|
||||
netns := t.netns.Swap(nil)
|
||||
netns := t.netns
|
||||
t.netns = nil
|
||||
t.mu.Unlock()
|
||||
if mntns != nil {
|
||||
mntns.DecRef(t)
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
// IsNetworkNamespaced returns true if t is in a non-root network namespace.
|
||||
func (t *Task) IsNetworkNamespaced() bool {
|
||||
return !t.netns.Load().IsRoot()
|
||||
return !t.netns.IsRoot()
|
||||
}
|
||||
|
||||
// NetworkContext returns the network stack used by the task. NetworkContext
|
||||
@@ -29,12 +29,12 @@ func (t *Task) IsNetworkNamespaced() bool {
|
||||
// TODO(gvisor.dev/issue/1833): Migrate callers of this method to
|
||||
// NetworkNamespace().
|
||||
func (t *Task) NetworkContext() inet.Stack {
|
||||
return t.netns.Load().Stack()
|
||||
return t.netns.Stack()
|
||||
}
|
||||
|
||||
// NetworkNamespace returns the network namespace observed by the task.
|
||||
func (t *Task) NetworkNamespace() *inet.Namespace {
|
||||
return t.netns.Load()
|
||||
return t.netns
|
||||
}
|
||||
|
||||
// GetNetworkNamespace takes a reference on the task network namespace and
|
||||
@@ -43,7 +43,7 @@ func (t *Task) GetNetworkNamespace() *inet.Namespace {
|
||||
// t.mu is required to be sure that the network namespace will not be
|
||||
// released.
|
||||
t.mu.Lock()
|
||||
netns := t.netns.Load()
|
||||
netns := t.netns
|
||||
if netns != nil {
|
||||
netns.IncRef()
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func (ts *TaskSet) newTask(ctx context.Context, cfg *TaskConfig) (*Task, error)
|
||||
cgroups: make(map[Cgroup]struct{}),
|
||||
userCounters: cfg.UserCounters,
|
||||
}
|
||||
t.netns.Store(cfg.NetworkNamespace)
|
||||
t.netns = cfg.NetworkNamespace
|
||||
t.creds.Store(cfg.Credentials)
|
||||
t.endStopCond.L = &t.tg.signalHandlers.mu
|
||||
t.ptraceTracer.Store((*Task)(nil))
|
||||
|
||||
Reference in New Issue
Block a user