For Shared Virtual Memory (SVM) system (SYS) allocator, there is no
backing buffer object (BO). Add support to bind a VA to PA mapping
in the device page table.

Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfi...@intel.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Sudeep Dutt <sudeep.d...@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathap...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 60 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_gtt.h | 10 +++++
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 44ff4074db12..d9e95229ba1d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -183,6 +183,50 @@ static void ppgtt_unbind_vma(struct i915_vma *vma)
                vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
 }
 
+int svm_bind_addr_prepare(struct i915_address_space *vm, u64 start, u64 size)
+{
+       return vm->allocate_va_range(vm, start, size);
+}
+
+int svm_bind_addr_commit(struct i915_address_space *vm, u64 start, u64 size,
+                        u64 flags, struct sg_table *st, u32 sg_page_sizes)
+{
+       struct i915_vma vma = {0};
+       u32 pte_flags = 0;
+
+       /* use a vma wrapper */
+       vma.page_sizes.sg = sg_page_sizes;
+       vma.node.start = start;
+       vma.node.size = size;
+       vma.pages = st;
+       vma.vm = vm;
+
+       /* Applicable to VLV, and gen8+ */
+       if (flags & I915_GTT_SVM_READONLY)
+               pte_flags |= PTE_READ_ONLY;
+
+       vm->insert_entries(vm, &vma, 0, pte_flags);
+       return 0;
+}
+
+int svm_bind_addr(struct i915_address_space *vm, u64 start, u64 size,
+                 u64 flags, struct sg_table *st, u32 sg_page_sizes)
+{
+       int ret;
+
+       ret = svm_bind_addr_prepare(vm, start, size);
+       if (ret)
+               return ret;
+
+       return svm_bind_addr_commit(vm, start, size, flags, st, sg_page_sizes);
+}
+
+void svm_unbind_addr(struct i915_address_space *vm,
+                    u64 start, u64 size)
+{
+       vm->clear_range(vm, start, size);
+}
+
 static int ppgtt_set_pages(struct i915_vma *vma)
 {
        GEM_BUG_ON(vma->pages);
@@ -973,11 +1017,21 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space 
* const vm,
        DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d 
}\n",
            __func__, vm, lvl + 1, start, end,
            idx, len, atomic_read(px_used(pd)));
-       GEM_BUG_ON(!len || len >= atomic_read(px_used(pd)));
+       /*
+        * FIXME: In SVM case, during mmu invalidation, we need to clear ppgtt,
+        * but we don't know if the entry exist or not. So, we can't assume
+        * that it is called only when the entry exist. revisit.
+        * Also need to add the ebility to properly handle partial invalidations
+        * by downgrading the large mappings.
+        */
+       GEM_BUG_ON(!len);
 
        do {
                struct i915_page_table *pt = pd->entry[idx];
 
+               if (!pt)
+                       continue;
+
                if (atomic_fetch_inc(&pt->used) >> gen8_pd_shift(1) &&
                    gen8_pd_contains(start, end, lvl)) {
                        DBG("%s(%p):{ lvl:%d, idx:%d, start:%llx, end:%llx } 
removing pd\n",
@@ -1000,7 +1054,9 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * 
const vm,
                            __func__, vm, lvl, start, end,
                            gen8_pd_index(start, 0), count,
                            atomic_read(&pt->used));
-                       GEM_BUG_ON(!count || count >= atomic_read(&pt->used));
+                       GEM_BUG_ON(!count);
+                       if (count > atomic_read(&pt->used))
+                               count = atomic_read(&pt->used);
 
                        vaddr = kmap_atomic_px(pt);
                        memset64(vaddr + gen8_pd_index(start, 0),
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index d618a5787c61..6a8d55490e39 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -39,6 +39,7 @@
 #include <linux/mm.h>
 #include <linux/pagevec.h>
 #include <linux/workqueue.h>
+#include <linux/scatterlist.h>
 
 #include <drm/drm_mm.h>
 
@@ -678,4 +679,13 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 
 #define PIN_OFFSET_MASK                (-I915_GTT_PAGE_SIZE)
 
+/* SVM API */
+#define I915_GTT_SVM_READONLY  BIT(0)
+
+int svm_bind_addr_prepare(struct i915_address_space *vm, u64 start, u64 size);
+int svm_bind_addr_commit(struct i915_address_space *vm, u64 start, u64 size,
+                        u64 flags, struct sg_table *st, u32 sg_page_sizes);
+int svm_bind_addr(struct i915_address_space *vm, u64 start, u64 size,
+                 u64 flags, struct sg_table *st, u32 sg_page_sizes);
+void svm_unbind_addr(struct i915_address_space *vm, u64 start, u64 size);
 #endif
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to