Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nvproxy: Add option to use the device gofer optionally. #11464

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 28 additions & 16 deletions pkg/sentry/devices/nvproxy/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package nvproxy

import (
"fmt"
"path/filepath"

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

// Open implements vfs.Device.Open.
func (dev *frontendDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
devClient := devutil.GoferClientFromContext(ctx)
if devClient == nil {
log.Warningf("devutil.CtxDevGoferClient is not set")
return nil, linuxerr.ENOENT
fd := &frontendFD{
dev: dev,
}
basename := dev.basename()
hostFD, err := devClient.OpenAt(ctx, basename, opts.Flags)
if err != nil {
ctx.Warningf("nvproxy: failed to open host %s: %v", basename, err)
return nil, err
}
fd := &frontendFD{
dev: dev,
containerName: devClient.ContainerName(),
hostFD: int32(hostFD),
if dev.nvp.useDevGofer {
devClient := devutil.GoferClientFromContext(ctx)
if devClient == nil {
log.Warningf("devutil.CtxDevGoferClient is not set")
return nil, linuxerr.ENOENT
}
fd.containerName = devClient.ContainerName()
hostFD, err := devClient.OpenAt(ctx, basename, opts.Flags)
if err != nil {
ctx.Warningf("nvproxy: failed to open %s: %v", basename, err)
return nil, err
}
fd.hostFD = int32(hostFD)
} else {
devPath := filepath.Join("/dev", basename)
flags := int(opts.Flags&unix.O_ACCMODE | unix.O_NOFOLLOW)
hostFD, err := unix.Openat(-1, devPath, flags, 0)
if err != nil {
ctx.Warningf("nvproxy: failed to open host %s: %v", devPath, err)
return nil, err
}
fd.hostFD = int32(hostFD)
}
if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
UseDentryMetadata: true,
}); err != nil {
unix.Close(hostFD)
unix.Close(int(fd.hostFD))
return nil, err
}
fd.internalEntry.Init(fd, waiter.AllEvents)
fd.internalQueue.EventRegister(&fd.internalEntry)
if err := fdnotifier.AddFD(int32(hostFD), &fd.internalQueue); err != nil {
unix.Close(hostFD)
if err := fdnotifier.AddFD(fd.hostFD, &fd.internalQueue); err != nil {
unix.Close(int(fd.hostFD))
return nil, err
}
fd.memmapFile.fd = fd
Expand Down
4 changes: 3 additions & 1 deletion pkg/sentry/devices/nvproxy/nvproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

// Register registers all devices implemented by this package in vfsObj.
func Register(vfsObj *vfs.VirtualFilesystem, versionStr string, driverCaps nvconf.DriverCaps, uvmDevMajor uint32) error {
func Register(vfsObj *vfs.VirtualFilesystem, versionStr string, driverCaps nvconf.DriverCaps, uvmDevMajor uint32, useDevGofer bool) error {
// The kernel driver's interface is unstable, so only allow versions of the
// driver that are known to be supported.
log.Infof("NVIDIA driver version: %s", versionStr)
Expand All @@ -49,6 +49,7 @@ func Register(vfsObj *vfs.VirtualFilesystem, versionStr string, driverCaps nvcon
abi: abiCons.cons(),
version: version,
capsEnabled: driverCaps,
useDevGofer: useDevGofer,
frontendFDs: make(map[*frontendFD]struct{}),
clients: make(map[nvgpu.Handle]*rootClient),
objsFreeSet: make(map[*object]struct{}),
Expand Down Expand Up @@ -78,6 +79,7 @@ type nvproxy struct {
abi *driverABI `state:"nosave"`
version DriverVersion
capsEnabled nvconf.DriverCaps
useDevGofer bool

fdsMu fdsMutex `state:"nosave"`
frontendFDs map[*frontendFD]struct{}
Expand Down
42 changes: 26 additions & 16 deletions pkg/sentry/devices/nvproxy/uvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,39 @@ type uvmDevice struct {

// Open implements vfs.Device.Open.
func (dev *uvmDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
devClient := devutil.GoferClientFromContext(ctx)
if devClient == nil {
log.Warningf("devutil.CtxDevGoferClient is not set")
return nil, linuxerr.ENOENT
}
hostFD, err := devClient.OpenAt(ctx, "nvidia-uvm", opts.Flags)
if err != nil {
ctx.Warningf("nvproxy: failed to open host /dev/nvidia-uvm: %v", err)
return nil, err
}
fd := &uvmFD{
dev: dev,
containerName: devClient.ContainerName(),
hostFD: int32(hostFD),
dev: dev,
}
if dev.nvp.useDevGofer {
devClient := devutil.GoferClientFromContext(ctx)
if devClient == nil {
log.Warningf("devutil.CtxDevGoferClient is not set")
return nil, linuxerr.ENOENT
}
fd.containerName = devClient.ContainerName()
hostFD, err := devClient.OpenAt(ctx, "nvidia-uvm", opts.Flags)
if err != nil {
ctx.Warningf("nvproxy: failed to open nvidia-uvm: %v", err)
return nil, err
}
fd.hostFD = int32(hostFD)
} else {
flags := int(opts.Flags&unix.O_ACCMODE | unix.O_NOFOLLOW)
hostFD, err := unix.Openat(-1, "/dev/nvidia-uvm", flags, 0)
if err != nil {
ctx.Warningf("nvproxy: failed to open host /dev/nvidia-uvm: %v", err)
return nil, err
}
fd.hostFD = int32(hostFD)
}
if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
UseDentryMetadata: true,
}); err != nil {
unix.Close(hostFD)
unix.Close(int(fd.hostFD))
return nil, err
}
if err := fdnotifier.AddFD(int32(hostFD), &fd.queue); err != nil {
unix.Close(hostFD)
if err := fdnotifier.AddFD(fd.hostFD, &fd.queue); err != nil {
unix.Close(int(fd.hostFD))
return nil, err
}
fd.memmapFile.fd = fd
Expand Down
2 changes: 1 addition & 1 deletion runsc/boot/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1401,7 +1401,7 @@ func nvproxyRegisterDevices(info *containerInfo, vfsObj *vfs.VirtualFilesystem)
if err != nil {
return fmt.Errorf("reserving device major number for nvidia-uvm: %w", err)
}
if err := nvproxy.Register(vfsObj, info.nvidiaDriverVersion, driverCaps, uvmDevMajor); err != nil {
if err := nvproxy.Register(vfsObj, info.nvidiaDriverVersion, driverCaps, uvmDevMajor, true /* useDevGofer */); err != nil {
return fmt.Errorf("registering nvproxy driver: %w", err)
}
info.nvidiaUVMDevMajor = uvmDevMajor
Expand Down