History

drm/msm: Split out map/unmap ops

With async VM_BIND, the actual pgtable updates are deferred. Synchronously, a list of map/unmap ops will be generated, but the actual pgtable changes are deferred. To support that, split out op handlers and change the existing non-VM_BIND paths to use them. Note in particular, the vma itself may already be destroyed/freed by the time an UNMAP op runs (or even a MAP op if there is a later queued UNMAP). For this reason, the op handlers cannot reference the vma pointer.

Rob Clark committed 1 year ago

Commit ecfd9fa1 parent e601ea31 file · +56 −7Browse files

Unified · Split

drivers/gpu/drm/msm/msm_gem_vma.c+56−7
@@ -8,6 +8,34 @@ · 7 unmodified lines
8#include "msm_gem.h"8#include "msm_gem.h"
9#include "msm_mmu.h"9#include "msm_mmu.h"
10 10
11#define vm_dbg(fmt, ...) pr_debug("%s:%d: "fmt"\n", __func__, __LINE__, ##__VA_ARGS__)
12
13/**
14 * struct msm_vm_map_op - create new pgtable mapping
15 */
16struct msm_vm_map_op {
17 /** @iova: start address for mapping */
18 uint64_t iova;
19 /** @range: size of the region to map */
20 uint64_t range;
21 /** @offset: offset into @sgt to map */
22 uint64_t offset;
23 /** @sgt: pages to map, or NULL for a PRR mapping */
24 struct sg_table *sgt;
25 /** @prot: the mapping protection flags */
26 int prot;
27};
28
29/**
30 * struct msm_vm_unmap_op - unmap a range of pages from pgtable
31 */
32struct msm_vm_unmap_op {
33 /** @iova: start address for unmap */
34 uint64_t iova;
35 /** @range: size of region to unmap */
36 uint64_t range;
37};
38
11static void39static void
12msm_gem_vm_free(struct drm_gpuvm *gpuvm)40msm_gem_vm_free(struct drm_gpuvm *gpuvm)
13{41{
@@ -21,18 +49,36 @@ msm_gem_vm_free(struct drm_gpuvm *gpuvm) · 7 unmodified lines
21 kfree(vm);49 kfree(vm);
22}50}
23 51
52static void
53vm_unmap_op(struct msm_gem_vm *vm, const struct msm_vm_unmap_op *op)
54{
55 vm_dbg("%p: %016llx %016llx", vm, op->iova, op->iova + op->range);
56
57 vm->mmu->funcs->unmap(vm->mmu, op->iova, op->range);
58}
59
60static int
61vm_map_op(struct msm_gem_vm *vm, const struct msm_vm_map_op *op)
62{
63 vm_dbg("%p: %016llx %016llx", vm, op->iova, op->iova + op->range);
64
65 return vm->mmu->funcs->map(vm->mmu, op->iova, op->sgt, op->offset,
66 op->range, op->prot);
67}
68
24/* Actually unmap memory for the vma */69/* Actually unmap memory for the vma */
25void msm_gem_vma_unmap(struct drm_gpuva *vma)70void msm_gem_vma_unmap(struct drm_gpuva *vma)
26{71{
27 struct msm_gem_vma *msm_vma = to_msm_vma(vma);72 struct msm_gem_vma *msm_vma = to_msm_vma(vma);
28 struct msm_gem_vm *vm = to_msm_vm(vma->vm);
29 unsigned size = vma->va.range;
30 73
31 /* Don't do anything if the memory isn't mapped */74 /* Don't do anything if the memory isn't mapped */
32 if (!msm_vma->mapped)75 if (!msm_vma->mapped)
33 return;76 return;
34 77
35 vm->mmu->funcs->unmap(vm->mmu, vma->va.addr, size);78 vm_unmap_op(to_msm_vm(vma->vm), &(struct msm_vm_unmap_op){
79 .iova = vma->va.addr,
80 .range = vma->va.range,
81 });
36 82
37 msm_vma->mapped = false;83 msm_vma->mapped = false;
38}84}
@@ -42,7 +88,6 @@ int · 3 unmodified lines
42msm_gem_vma_map(struct drm_gpuva *vma, int prot, struct sg_table *sgt)88msm_gem_vma_map(struct drm_gpuva *vma, int prot, struct sg_table *sgt)
43{89{
44 struct msm_gem_vma *msm_vma = to_msm_vma(vma);90 struct msm_gem_vma *msm_vma = to_msm_vma(vma);
45 struct msm_gem_vm *vm = to_msm_vm(vma->vm);
46 int ret;91 int ret;
47 92
48 if (GEM_WARN_ON(!vma->va.addr))93 if (GEM_WARN_ON(!vma->va.addr))
@@ -62,9 +107,13 @@ msm_gem_vma_map(struct drm_gpuva *vma, int prot, struct sg_table *sgt) · 13 unmodified lines
62 * Revisit this if we can come up with a scheme to pre-alloc pages107 * Revisit this if we can come up with a scheme to pre-alloc pages
63 * for the pgtable in map/unmap ops.108 * for the pgtable in map/unmap ops.
64 */109 */
65 ret = vm->mmu->funcs->map(vm->mmu, vma->va.addr, sgt,110 ret = vm_map_op(to_msm_vm(vma->vm), &(struct msm_vm_map_op){
66 vma->gem.offset, vma->va.range,111 .iova = vma->va.addr,
67 prot);112 .range = vma->va.range,
113 .offset = vma->gem.offset,
114 .sgt = sgt,
115 .prot = prot,
116 });
68 if (ret) {117 if (ret) {
69 msm_vma->mapped = false;118 msm_vma->mapped = false;
70 }119 }