Skip to content

Commit 6b252cf

Browse files
committed
drm/nouveau: nvkm/vmm: implement raw ops to manage uvmm
The new VM_BIND UAPI uses the DRM GPU VA manager to manage the VA space. Hence, we a need a way to manipulate the MMUs page tables without going through the internal range allocator implemented by nvkm/vmm. This patch adds a raw interface for nvkm/vmm to pass the resposibility for managing the address space and the corresponding map/unmap/sparse operations to the upper layers. Reviewed-by: Dave Airlie <[email protected]> Signed-off-by: Danilo Krummrich <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 7576c4c commit 6b252cf

File tree

12 files changed

+566
-99
lines changed

12 files changed

+566
-99
lines changed

drivers/gpu/drm/nouveau/include/nvif/if000c.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
struct nvif_vmm_v0 {
44
__u8 version;
55
__u8 page_nr;
6-
__u8 managed;
6+
#define NVIF_VMM_V0_TYPE_UNMANAGED 0x00
7+
#define NVIF_VMM_V0_TYPE_MANAGED 0x01
8+
#define NVIF_VMM_V0_TYPE_RAW 0x02
9+
__u8 type;
710
__u8 pad03[5];
811
__u64 addr;
912
__u64 size;
@@ -17,6 +20,7 @@ struct nvif_vmm_v0 {
1720
#define NVIF_VMM_V0_UNMAP 0x04
1821
#define NVIF_VMM_V0_PFNMAP 0x05
1922
#define NVIF_VMM_V0_PFNCLR 0x06
23+
#define NVIF_VMM_V0_RAW 0x07
2024
#define NVIF_VMM_V0_MTHD(i) ((i) + 0x80)
2125

2226
struct nvif_vmm_page_v0 {
@@ -66,6 +70,26 @@ struct nvif_vmm_unmap_v0 {
6670
__u64 addr;
6771
};
6872

73+
struct nvif_vmm_raw_v0 {
74+
__u8 version;
75+
#define NVIF_VMM_RAW_V0_GET 0x0
76+
#define NVIF_VMM_RAW_V0_PUT 0x1
77+
#define NVIF_VMM_RAW_V0_MAP 0x2
78+
#define NVIF_VMM_RAW_V0_UNMAP 0x3
79+
#define NVIF_VMM_RAW_V0_SPARSE 0x4
80+
__u8 op;
81+
__u8 sparse;
82+
__u8 ref;
83+
__u8 shift;
84+
__u32 argc;
85+
__u8 pad01[7];
86+
__u64 addr;
87+
__u64 size;
88+
__u64 offset;
89+
__u64 memory;
90+
__u64 argv;
91+
};
92+
6993
struct nvif_vmm_pfnmap_v0 {
7094
__u8 version;
7195
__u8 page;

drivers/gpu/drm/nouveau/include/nvif/vmm.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
struct nvif_mem;
55
struct nvif_mmu;
66

7+
enum nvif_vmm_type {
8+
UNMANAGED,
9+
MANAGED,
10+
RAW,
11+
};
12+
713
enum nvif_vmm_get {
814
ADDR,
915
PTES,
@@ -30,13 +36,22 @@ struct nvif_vmm {
3036
int page_nr;
3137
};
3238

33-
int nvif_vmm_ctor(struct nvif_mmu *, const char *name, s32 oclass, bool managed,
34-
u64 addr, u64 size, void *argv, u32 argc, struct nvif_vmm *);
39+
int nvif_vmm_ctor(struct nvif_mmu *, const char *name, s32 oclass,
40+
enum nvif_vmm_type, u64 addr, u64 size, void *argv, u32 argc,
41+
struct nvif_vmm *);
3542
void nvif_vmm_dtor(struct nvif_vmm *);
3643
int nvif_vmm_get(struct nvif_vmm *, enum nvif_vmm_get, bool sparse,
3744
u8 page, u8 align, u64 size, struct nvif_vma *);
3845
void nvif_vmm_put(struct nvif_vmm *, struct nvif_vma *);
3946
int nvif_vmm_map(struct nvif_vmm *, u64 addr, u64 size, void *argv, u32 argc,
4047
struct nvif_mem *, u64 offset);
4148
int nvif_vmm_unmap(struct nvif_vmm *, u64);
49+
50+
int nvif_vmm_raw_get(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift);
51+
int nvif_vmm_raw_put(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift);
52+
int nvif_vmm_raw_map(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift,
53+
void *argv, u32 argc, struct nvif_mem *mem, u64 offset);
54+
int nvif_vmm_raw_unmap(struct nvif_vmm *vmm, u64 addr, u64 size,
55+
u8 shift, bool sparse);
56+
int nvif_vmm_raw_sparse(struct nvif_vmm *vmm, u64 addr, u64 size, bool ref);
4257
#endif

drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct nvkm_vma {
1717
bool part:1; /* Region was split from an allocated region by map(). */
1818
bool busy:1; /* Region busy (for temporarily preventing user access). */
1919
bool mapped:1; /* Region contains valid pages. */
20+
bool no_comp:1; /* Force no memory compression. */
2021
struct nvkm_memory *memory; /* Memory currently mapped into VMA. */
2122
struct nvkm_tags *tags; /* Compression tag reference. */
2223
};
@@ -27,10 +28,26 @@ struct nvkm_vmm {
2728
const char *name;
2829
u32 debug;
2930
struct kref kref;
30-
struct mutex mutex;
31+
32+
struct {
33+
struct mutex vmm;
34+
struct mutex ref;
35+
struct mutex map;
36+
} mutex;
3137

3238
u64 start;
3339
u64 limit;
40+
struct {
41+
struct {
42+
u64 addr;
43+
u64 size;
44+
} p;
45+
struct {
46+
u64 addr;
47+
u64 size;
48+
} n;
49+
bool raw;
50+
} managed;
3451

3552
struct nvkm_vmm_pt *pd;
3653
struct list_head join;
@@ -70,6 +87,7 @@ struct nvkm_vmm_map {
7087

7188
const struct nvkm_vmm_page *page;
7289

90+
bool no_comp;
7391
struct nvkm_tags *tags;
7492
u64 next;
7593
u64 type;

drivers/gpu/drm/nouveau/nouveau_svm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ nouveau_svmm_init(struct drm_device *dev, void *data,
350350
* VMM instead of the standard one.
351351
*/
352352
ret = nvif_vmm_ctor(&cli->mmu, "svmVmm",
353-
cli->vmm.vmm.object.oclass, true,
353+
cli->vmm.vmm.object.oclass, MANAGED,
354354
args->unmanaged_addr, args->unmanaged_size,
355355
&(struct gp100_vmm_v0) {
356356
.fault_replay = true,

drivers/gpu/drm/nouveau/nouveau_vmm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ nouveau_vmm_fini(struct nouveau_vmm *vmm)
128128
int
129129
nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm)
130130
{
131-
int ret = nvif_vmm_ctor(&cli->mmu, "drmVmm", oclass, false, PAGE_SIZE,
132-
0, NULL, 0, &vmm->vmm);
131+
int ret = nvif_vmm_ctor(&cli->mmu, "drmVmm", oclass, UNMANAGED,
132+
PAGE_SIZE, 0, NULL, 0, &vmm->vmm);
133133
if (ret)
134134
return ret;
135135

drivers/gpu/drm/nouveau/nvif/vmm.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,90 @@ nvif_vmm_get(struct nvif_vmm *vmm, enum nvif_vmm_get type, bool sparse,
104104
return ret;
105105
}
106106

107+
int
108+
nvif_vmm_raw_get(struct nvif_vmm *vmm, u64 addr, u64 size,
109+
u8 shift)
110+
{
111+
struct nvif_vmm_raw_v0 args = {
112+
.version = 0,
113+
.op = NVIF_VMM_RAW_V0_GET,
114+
.addr = addr,
115+
.size = size,
116+
.shift = shift,
117+
};
118+
119+
return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_RAW,
120+
&args, sizeof(args));
121+
}
122+
123+
int
124+
nvif_vmm_raw_put(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift)
125+
{
126+
struct nvif_vmm_raw_v0 args = {
127+
.version = 0,
128+
.op = NVIF_VMM_RAW_V0_PUT,
129+
.addr = addr,
130+
.size = size,
131+
.shift = shift,
132+
};
133+
134+
return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_RAW,
135+
&args, sizeof(args));
136+
}
137+
138+
int
139+
nvif_vmm_raw_map(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift,
140+
void *argv, u32 argc, struct nvif_mem *mem, u64 offset)
141+
{
142+
struct nvif_vmm_raw_v0 args = {
143+
.version = 0,
144+
.op = NVIF_VMM_RAW_V0_MAP,
145+
.addr = addr,
146+
.size = size,
147+
.shift = shift,
148+
.memory = nvif_handle(&mem->object),
149+
.offset = offset,
150+
.argv = (u64)(uintptr_t)argv,
151+
.argc = argc,
152+
};
153+
154+
155+
return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_RAW,
156+
&args, sizeof(args));
157+
}
158+
159+
int
160+
nvif_vmm_raw_unmap(struct nvif_vmm *vmm, u64 addr, u64 size,
161+
u8 shift, bool sparse)
162+
{
163+
struct nvif_vmm_raw_v0 args = {
164+
.version = 0,
165+
.op = NVIF_VMM_RAW_V0_UNMAP,
166+
.addr = addr,
167+
.size = size,
168+
.shift = shift,
169+
.sparse = sparse,
170+
};
171+
172+
return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_RAW,
173+
&args, sizeof(args));
174+
}
175+
176+
int
177+
nvif_vmm_raw_sparse(struct nvif_vmm *vmm, u64 addr, u64 size, bool ref)
178+
{
179+
struct nvif_vmm_raw_v0 args = {
180+
.version = 0,
181+
.op = NVIF_VMM_RAW_V0_SPARSE,
182+
.addr = addr,
183+
.size = size,
184+
.ref = ref,
185+
};
186+
187+
return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_RAW,
188+
&args, sizeof(args));
189+
}
190+
107191
void
108192
nvif_vmm_dtor(struct nvif_vmm *vmm)
109193
{
@@ -112,8 +196,9 @@ nvif_vmm_dtor(struct nvif_vmm *vmm)
112196
}
113197

114198
int
115-
nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass, bool managed,
116-
u64 addr, u64 size, void *argv, u32 argc, struct nvif_vmm *vmm)
199+
nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass,
200+
enum nvif_vmm_type type, u64 addr, u64 size, void *argv, u32 argc,
201+
struct nvif_vmm *vmm)
117202
{
118203
struct nvif_vmm_v0 *args;
119204
u32 argn = sizeof(*args) + argc;
@@ -125,9 +210,18 @@ nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass, bool managed,
125210
if (!(args = kmalloc(argn, GFP_KERNEL)))
126211
return -ENOMEM;
127212
args->version = 0;
128-
args->managed = managed;
129213
args->addr = addr;
130214
args->size = size;
215+
216+
switch (type) {
217+
case UNMANAGED: args->type = NVIF_VMM_V0_TYPE_UNMANAGED; break;
218+
case MANAGED: args->type = NVIF_VMM_V0_TYPE_MANAGED; break;
219+
case RAW: args->type = NVIF_VMM_V0_TYPE_RAW; break;
220+
default:
221+
WARN_ON(1);
222+
return -EINVAL;
223+
}
224+
131225
memcpy(args->data, argv, argc);
132226

133227
ret = nvif_object_ctor(&mmu->object, name ? name : "nvifVmm", 0,

0 commit comments

Comments
 (0)