Skip to content

Commit

Permalink
drm/nouveau/svm: initial support for shared virtual memory
Browse files Browse the repository at this point in the history
This uses HMM to mirror a process' CPU page tables into a channel's page
tables, and keep them synchronised so that both the CPU and GPU are able
to access the same memory at the same virtual address.

While this code also supports Volta/Turing, it's only enabled for Pascal
GPUs currently due to channel recovery being unreliable right now on the
later GPUs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Feb 19, 2019
1 parent bfe91af commit eeaf06a
Show file tree
Hide file tree
Showing 10 changed files with 818 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/Kbuild
Expand Up @@ -30,6 +30,7 @@ nouveau-y += nouveau_vga.o
# DRM - memory management
nouveau-y += nouveau_bo.o
nouveau-y += nouveau_gem.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_svm.o
nouveau-y += nouveau_mem.o
nouveau-y += nouveau_prime.o
nouveau-y += nouveau_sgdma.o
Expand Down
11 changes: 11 additions & 0 deletions drivers/gpu/drm/nouveau/Kconfig
Expand Up @@ -71,3 +71,14 @@ config DRM_NOUVEAU_BACKLIGHT
help
Say Y here if you want to control the backlight of your display
(e.g. a laptop panel).

config DRM_NOUVEAU_SVM
bool "(EXPERIMENTAL) Enable SVM (Shared Virtual Memory) support"
depends on ARCH_HAS_HMM
depends on DRM_NOUVEAU
depends on STAGING
select HMM_MIRROR
default n
help
Say Y here if you want to enable experimental support for
Shared Virtual Memory (SVM).
9 changes: 9 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_chan.c
Expand Up @@ -42,6 +42,7 @@
#include "nouveau_fence.h"
#include "nouveau_abi16.h"
#include "nouveau_vmm.h"
#include "nouveau_svm.h"

MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM");
int nouveau_vram_pushbuf;
Expand Down Expand Up @@ -95,6 +96,10 @@ nouveau_channel_del(struct nouveau_channel **pchan)

if (chan->fence)
nouveau_fence(chan->drm)->context_del(chan);

if (cli)
nouveau_svmm_part(chan->vmm->svmm, chan->inst);

nvif_object_fini(&chan->nvsw);
nvif_object_fini(&chan->gart);
nvif_object_fini(&chan->vram);
Expand Down Expand Up @@ -494,6 +499,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
nouveau_channel_del(pchan);
}

ret = nouveau_svmm_join((*pchan)->vmm->svmm, (*pchan)->inst);
if (ret)
nouveau_channel_del(pchan);

done:
cli->base.super = super;
return ret;
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_drm.c
Expand Up @@ -62,6 +62,7 @@
#include "nouveau_usif.h"
#include "nouveau_connector.h"
#include "nouveau_platform.h"
#include "nouveau_svm.h"

MODULE_PARM_DESC(config, "option string to pass to driver core");
static char *nouveau_config;
Expand Down Expand Up @@ -549,6 +550,7 @@ nouveau_drm_device_init(struct drm_device *dev)

nouveau_debugfs_init(drm);
nouveau_hwmon_init(dev);
nouveau_svm_init(drm);
nouveau_fbcon_init(dev);
nouveau_led_init(dev);

Expand Down Expand Up @@ -592,6 +594,7 @@ nouveau_drm_device_fini(struct drm_device *dev)

nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_svm_fini(drm);
nouveau_hwmon_fini(dev);
nouveau_debugfs_fini(drm);

Expand Down Expand Up @@ -737,6 +740,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
struct nouveau_drm *drm = nouveau_drm(dev);
int ret;

nouveau_svm_suspend(drm);
nouveau_led_suspend(dev);

if (dev->mode_config.num_crtc) {
Expand Down Expand Up @@ -813,7 +817,7 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
}

nouveau_led_resume(dev);

nouveau_svm_resume(drm);
return 0;
}

Expand Down Expand Up @@ -1033,6 +1037,7 @@ nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_SVM_INIT, nouveau_svmm_init, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Expand Up @@ -210,6 +210,8 @@ struct nouveau_drm {
bool have_disp_power_ref;

struct dev_pm_domain vga_pm_domain;

struct nouveau_svm *svm;
};

static inline struct nouveau_drm *
Expand Down

0 comments on commit eeaf06a

Please sign in to comment.