Skip to content

Commit 906fb31

Browse files
ayushr2gvisor-bot
authored andcommitted
nvproxy: Add option to use the device gofer optionally.
We always use the device gofer in runsc, because the sandbox's filesystem does not have the GPU devices mounted in it. PiperOrigin-RevId: 736316547
1 parent 63f6dd7 commit 906fb31

File tree

4 files changed

+58
-34
lines changed

4 files changed

+58
-34
lines changed

pkg/sentry/devices/nvproxy/frontend.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package nvproxy
1616

1717
import (
1818
"fmt"
19+
"path/filepath"
1920

2021
"golang.org/x/sys/unix"
2122
"gvisor.dev/gvisor/pkg/abi/linux"
@@ -55,32 +56,43 @@ func (dev *frontendDevice) basename() string {
5556

5657
// Open implements vfs.Device.Open.
5758
func (dev *frontendDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
58-
devClient := devutil.GoferClientFromContext(ctx)
59-
if devClient == nil {
60-
log.Warningf("devutil.CtxDevGoferClient is not set")
61-
return nil, linuxerr.ENOENT
59+
fd := &frontendFD{
60+
dev: dev,
6261
}
6362
basename := dev.basename()
64-
hostFD, err := devClient.OpenAt(ctx, basename, opts.Flags)
65-
if err != nil {
66-
ctx.Warningf("nvproxy: failed to open host %s: %v", basename, err)
67-
return nil, err
68-
}
69-
fd := &frontendFD{
70-
dev: dev,
71-
containerName: devClient.ContainerName(),
72-
hostFD: int32(hostFD),
63+
if dev.nvp.useDevGofer {
64+
devClient := devutil.GoferClientFromContext(ctx)
65+
if devClient == nil {
66+
log.Warningf("devutil.CtxDevGoferClient is not set")
67+
return nil, linuxerr.ENOENT
68+
}
69+
fd.containerName = devClient.ContainerName()
70+
hostFD, err := devClient.OpenAt(ctx, basename, opts.Flags)
71+
if err != nil {
72+
ctx.Warningf("nvproxy: failed to open %s: %v", basename, err)
73+
return nil, err
74+
}
75+
fd.hostFD = int32(hostFD)
76+
} else {
77+
devPath := filepath.Join("/dev", basename)
78+
flags := int(opts.Flags&unix.O_ACCMODE | unix.O_NOFOLLOW)
79+
hostFD, err := unix.Openat(-1, devPath, flags, 0)
80+
if err != nil {
81+
ctx.Warningf("nvproxy: failed to open host %s: %v", devPath, err)
82+
return nil, err
83+
}
84+
fd.hostFD = int32(hostFD)
7385
}
7486
if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
7587
UseDentryMetadata: true,
7688
}); err != nil {
77-
unix.Close(hostFD)
89+
unix.Close(int(fd.hostFD))
7890
return nil, err
7991
}
8092
fd.internalEntry.Init(fd, waiter.AllEvents)
8193
fd.internalQueue.EventRegister(&fd.internalEntry)
82-
if err := fdnotifier.AddFD(int32(hostFD), &fd.internalQueue); err != nil {
83-
unix.Close(hostFD)
94+
if err := fdnotifier.AddFD(fd.hostFD, &fd.internalQueue); err != nil {
95+
unix.Close(int(fd.hostFD))
8496
return nil, err
8597
}
8698
fd.memmapFile.fd = fd

pkg/sentry/devices/nvproxy/nvproxy.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030
)
3131

3232
// Register registers all devices implemented by this package in vfsObj.
33-
func Register(vfsObj *vfs.VirtualFilesystem, version nvconf.DriverVersion, driverCaps nvconf.DriverCaps, uvmDevMajor uint32) error {
33+
func Register(vfsObj *vfs.VirtualFilesystem, version nvconf.DriverVersion, driverCaps nvconf.DriverCaps, uvmDevMajor uint32, useDevGofer bool) error {
3434
// The kernel driver's interface is unstable, so only allow versions of the
3535
// driver that are known to be supported.
3636
log.Infof("NVIDIA driver version: %s", version)
@@ -45,6 +45,7 @@ func Register(vfsObj *vfs.VirtualFilesystem, version nvconf.DriverVersion, drive
4545
abi: abiCons.cons(),
4646
version: version,
4747
capsEnabled: driverCaps,
48+
useDevGofer: useDevGofer,
4849
frontendFDs: make(map[*frontendFD]struct{}),
4950
clients: make(map[nvgpu.Handle]*rootClient),
5051
objsFreeSet: make(map[*object]struct{}),
@@ -74,6 +75,7 @@ type nvproxy struct {
7475
abi *driverABI `state:"nosave"`
7576
version nvconf.DriverVersion
7677
capsEnabled nvconf.DriverCaps
78+
useDevGofer bool
7779

7880
fdsMu fdsMutex `state:"nosave"`
7981
frontendFDs map[*frontendFD]struct{}

pkg/sentry/devices/nvproxy/uvm.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,39 @@ type uvmDevice struct {
4141

4242
// Open implements vfs.Device.Open.
4343
func (dev *uvmDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
44-
devClient := devutil.GoferClientFromContext(ctx)
45-
if devClient == nil {
46-
log.Warningf("devutil.CtxDevGoferClient is not set")
47-
return nil, linuxerr.ENOENT
48-
}
49-
hostFD, err := devClient.OpenAt(ctx, "nvidia-uvm", opts.Flags)
50-
if err != nil {
51-
ctx.Warningf("nvproxy: failed to open host /dev/nvidia-uvm: %v", err)
52-
return nil, err
53-
}
5444
fd := &uvmFD{
55-
dev: dev,
56-
containerName: devClient.ContainerName(),
57-
hostFD: int32(hostFD),
45+
dev: dev,
46+
}
47+
if dev.nvp.useDevGofer {
48+
devClient := devutil.GoferClientFromContext(ctx)
49+
if devClient == nil {
50+
log.Warningf("devutil.CtxDevGoferClient is not set")
51+
return nil, linuxerr.ENOENT
52+
}
53+
fd.containerName = devClient.ContainerName()
54+
hostFD, err := devClient.OpenAt(ctx, "nvidia-uvm", opts.Flags)
55+
if err != nil {
56+
ctx.Warningf("nvproxy: failed to open nvidia-uvm: %v", err)
57+
return nil, err
58+
}
59+
fd.hostFD = int32(hostFD)
60+
} else {
61+
flags := int(opts.Flags&unix.O_ACCMODE | unix.O_NOFOLLOW)
62+
hostFD, err := unix.Openat(-1, "/dev/nvidia-uvm", flags, 0)
63+
if err != nil {
64+
ctx.Warningf("nvproxy: failed to open host /dev/nvidia-uvm: %v", err)
65+
return nil, err
66+
}
67+
fd.hostFD = int32(hostFD)
5868
}
5969
if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
6070
UseDentryMetadata: true,
6171
}); err != nil {
62-
unix.Close(hostFD)
72+
unix.Close(int(fd.hostFD))
6373
return nil, err
6474
}
65-
if err := fdnotifier.AddFD(int32(hostFD), &fd.queue); err != nil {
66-
unix.Close(hostFD)
75+
if err := fdnotifier.AddFD(fd.hostFD, &fd.queue); err != nil {
76+
unix.Close(int(fd.hostFD))
6777
return nil, err
6878
}
6979
fd.memmapFile.fd = fd

runsc/boot/vfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ func nvproxyRegisterDevices(info *containerInfo, vfsObj *vfs.VirtualFilesystem)
14011401
if err != nil {
14021402
return fmt.Errorf("reserving device major number for nvidia-uvm: %w", err)
14031403
}
1404-
if err := nvproxy.Register(vfsObj, info.nvidiaDriverVersion, driverCaps, uvmDevMajor); err != nil {
1404+
if err := nvproxy.Register(vfsObj, info.nvidiaDriverVersion, driverCaps, uvmDevMajor, true /* useDevGofer */); err != nil {
14051405
return fmt.Errorf("registering nvproxy driver: %w", err)
14061406
}
14071407
info.nvidiaUVMDevMajor = uvmDevMajor

0 commit comments

Comments
 (0)