aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/include
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-11-01 03:56:19 +1000
committerBen Skeggs <bskeggs@redhat.com>2017-11-02 13:32:30 +1000
commitf9463a4bc8ea2df5ea25c4d6e0be72011e559b95 (patch)
tree35868b7e31f1f496ae2f18e446b34b350c18343c /drivers/gpu/drm/nouveau/include
parentdrm/nouveau/mmu: remove support for old backends (diff)
downloadlinux-dev-f9463a4bc8ea2df5ea25c4d6e0be72011e559b95.tar.xz
linux-dev-f9463a4bc8ea2df5ea25c4d6e0be72011e559b95.zip
drm/nouveau/mmu: implement new vmm frontend
These are the new priviledged interfaces to the VMM backends, and expose some functionality that wasn't previously available. It's now possible to allocate a chunk of address-space (even all of it), without causing page tables to be allocated up-front, and then map into it at arbitrary locations. This is the basic primitive used to support features such as sparse mapping, or to allow userspace control over its own address-space, or HMM (where the GPU driver isn't in control of the address-space layout). Rather than being tied to a subtle combination of memory object and VMA properties, arguments that control map flags (ro, kind, etc) are passed explicitly at map time. The compatibility hacks to implement the old frontend on top of the new driver backends have been replaced with something similar to implement the old frontend's interfaces on top of the new frontend. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/include')
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h48
2 files changed, 36 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
index 5b5ff5a9a127..4af663d4d3c7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
@@ -1,9 +1,7 @@
#ifndef __NVKM_FB_H__
#define __NVKM_FB_H__
#include <core/subdev.h>
-#include <core/memory.h>
-
-#include <subdev/mmu.h>
+#include <core/mm.h>
/* memory type/access flags, do not match hardware values */
#define NV_MEM_ACCESS_RO 1
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
index 630c3cbaf2b9..7fa60d79ec4c 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -1,9 +1,6 @@
#ifndef __NVKM_MMU_H__
#define __NVKM_MMU_H__
#include <core/subdev.h>
-#include <core/memory.h>
-#include <core/mm.h>
-struct nvkm_gpuobj;
struct nvkm_mem;
struct nvkm_vm_pgt {
@@ -12,14 +9,25 @@ struct nvkm_vm_pgt {
};
struct nvkm_vma {
- struct nvkm_memory *memory;
- struct nvkm_tags *tags;
+ struct list_head head;
+ struct rb_node tree;
+ u64 addr;
+ u64 size:50;
+ bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */
+ bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */
+#define NVKM_VMA_PAGE_NONE 7
+ u8 page:3; /* Requested page type (index, or NONE for automatic). */
+ u8 refd:3; /* Current page type (index, or NONE for unreferenced). */
+ bool used:1; /* Region allocated. */
+ bool part:1; /* Region was split from an allocated region by map(). */
+ bool user:1; /* Region user-allocated. */
+ bool busy:1; /* Region busy (for temporarily preventing user access). */
+ struct nvkm_memory *memory; /* Memory currently mapped into VMA. */
+ struct nvkm_tags *tags; /* Compression tag reference. */
+
+ struct nvkm_vma *node;
struct nvkm_vm *vm;
- struct nvkm_mm_node *node;
- union {
- u64 offset;
- u64 addr;
- };
+ u64 offset;
u32 access;
};
@@ -37,8 +45,9 @@ struct nvkm_vm {
struct nvkm_vmm_pt *pd;
struct list_head join;
- struct nvkm_mm mm;
- struct kref refcount;
+ struct list_head list;
+ struct rb_root free;
+ struct rb_root root;
bool bootstrapped;
atomic_t engref[NVKM_SUBDEV_NR];
@@ -57,9 +66,16 @@ void nvkm_vm_put(struct nvkm_vma *);
void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *);
void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *);
void nvkm_vm_unmap(struct nvkm_vma *);
-void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length);
+int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc,
+ struct lock_class_key *, const char *name, struct nvkm_vmm **);
+struct nvkm_vmm *nvkm_vmm_ref(struct nvkm_vmm *);
+void nvkm_vmm_unref(struct nvkm_vmm **);
int nvkm_vmm_boot(struct nvkm_vmm *);
+int nvkm_vmm_join(struct nvkm_vmm *, struct nvkm_memory *inst);
+void nvkm_vmm_part(struct nvkm_vmm *, struct nvkm_memory *inst);
+int nvkm_vmm_get(struct nvkm_vmm *, u8 page, u64 size, struct nvkm_vma **);
+void nvkm_vmm_put(struct nvkm_vmm *, struct nvkm_vma **);
struct nvkm_vmm_map {
struct nvkm_memory *memory;
@@ -78,6 +94,12 @@ struct nvkm_vmm_map {
u64 ctag;
};
+int nvkm_vmm_map(struct nvkm_vmm *, struct nvkm_vma *, void *argv, u32 argc,
+ struct nvkm_vmm_map *);
+void nvkm_vmm_unmap(struct nvkm_vmm *, struct nvkm_vma *);
+
+struct nvkm_vmm *nvkm_uvmm_search(struct nvkm_client *, u64 handle);
+
struct nvkm_mmu {
const struct nvkm_mmu_func *func;
struct nvkm_subdev subdev;