Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eeaf06ac authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/svm: initial support for shared virtual memory



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: default avatarBen Skeggs <bskeggs@redhat.com>
parent bfe91afa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+11 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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;
+6 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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);

@@ -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);

@@ -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) {
@@ -813,7 +817,7 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
	}

	nouveau_led_resume(dev);

	nouveau_svm_resume(drm);
	return 0;
}

@@ -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),
+2 −0
Original line number Diff line number Diff line
@@ -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 *
Loading