diff options
author | Jérôme Glisse <jglisse@redhat.com> | 2018-08-07 16:13:16 -0400 |
---|---|---|
committer | Jérôme Glisse <jglisse@redhat.com> | 2018-08-08 18:11:14 -0400 |
commit | 9e58bccae6a66b0d37bf3b7e82767ecacddcd1ba (patch) | |
tree | f03370e17ee4bed6ca4d64af2f895bd5ad04f4d0 | |
parent | 382b31fbec733cb998a2aff68ae503b2194d0ce4 (diff) |
gpu/nouveau: new ioctl to migrate process memory to GPU memoryscratch
[WIP we need to make sure we get the ioctl API right, i think we want
some more flags so that kernel can keep overall view and make final
decission on wether or not some range should be migrated. Only the
kernel can have global overview accross multiple processed and decide
on how to share the device memory resource]
This add an ioctl to migrate a range of process address space to the
device memory. On platform without cache coherent bus (x86, ARM, ...)
this means that CPU can not access that range directly, instead CPU
will fault which will migrate the memory back to system memory.
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_svm.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_svm.h | 2 | ||||
-rw-r--r-- | include/uapi/drm/nouveau_drm.h | 7 |
4 files changed, 46 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index b5e68914c406..50425b14e385 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -982,6 +982,7 @@ nouveau_ioctls[] = { 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_SVM_MIGRATE, nouveau_svmm_migrate, 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), diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 60a9856e774d..345e4935575a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -22,6 +22,7 @@ #include "nouveau_svm.h" #include "nouveau_drv.h" #include "nouveau_chan.h" +#include "nouveau_dmem.h" #include <nvif/notify.h> #include <nvif/object.h> @@ -810,3 +811,38 @@ nvkm_svm_mmap_reserved(struct vm_area_struct *vma) return 0; } + +int +nouveau_svmm_migrate(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct nouveau_cli *cli = nouveau_cli(file_priv); + struct drm_nouveau_svm_migrate *args = data; + unsigned long addr, end; + struct mm_struct *mm; + + mm = get_task_mm(current); + down_read(&mm->mmap_sem); + + for (addr = args->addr, end = (args->addr + args->size); addr < end;) { + struct vm_area_struct *vma; + unsigned long next; + int ret; + + vma = find_vma_intersection(mm, addr, end); + if (!vma) + break; + + next = min(vma->vm_end, end); + ret = nouveau_dmem_migrate_vma(cli->drm, vma, addr, next); + if (ret) { + // FIXME ponder more on what to do + } + addr = next; + } + + up_read(&mm->mmap_sem); + mmput(mm); + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.h b/drivers/gpu/drm/nouveau/nouveau_svm.h index 06504dd993bd..13f0bbc7fe1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.h +++ b/drivers/gpu/drm/nouveau/nouveau_svm.h @@ -20,4 +20,6 @@ void nouveau_svmm_part(struct nouveau_svmm *, u64 inst); struct vm_area_struct; int nvkm_svm_mmap_reserved(struct vm_area_struct *vma); + +int nouveau_svmm_migrate(struct drm_device *, void *, struct drm_file *); #endif diff --git a/include/uapi/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h index afac182c80d8..e2e7b35dcbc0 100644 --- a/include/uapi/drm/nouveau_drm.h +++ b/include/uapi/drm/nouveau_drm.h @@ -134,6 +134,7 @@ struct drm_nouveau_gem_cpu_fini { #define DRM_NOUVEAU_GPUOBJ_FREE 0x06 /* deprecated */ #define DRM_NOUVEAU_NVIF 0x07 #define DRM_NOUVEAU_SVM_INIT 0x08 +#define DRM_NOUVEAU_SVM_MIGRATE 0x09 #define DRM_NOUVEAU_GEM_NEW 0x40 #define DRM_NOUVEAU_GEM_PUSHBUF 0x41 #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 @@ -145,7 +146,13 @@ struct drm_nouveau_svm_init { __u64 unmanaged_size; }; +struct drm_nouveau_svm_migrate { + __u64 addr; + __u64 size; +}; + #define DRM_IOCTL_NOUVEAU_SVM_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SVM_INIT, struct drm_nouveau_svm_init) +#define DRM_IOCTL_NOUVEAU_SVM_MIGRATE DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SVM_MIGRATE, struct drm_nouveau_svm_migrate) #define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new) #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf) |