Maintain all VM_BIND bindings in an list.

Cc: Joonas Lahtinen <[email protected]>
Cc: Jon Bloomfield <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: Chris P Wilson <[email protected]>
Cc: Sudeep Dutt <[email protected]>
Cc: Stuart Summers <[email protected]>
Signed-off-by: Niranjana Vishwanathapura <[email protected]>
---
 drivers/gpu/drm/i915/Kconfig            | 11 ++++
 drivers/gpu/drm/i915/Makefile           |  3 +
 drivers/gpu/drm/i915/gem/i915_gem_svm.c | 82 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_svm.h | 22 +++++++
 drivers/gpu/drm/i915/gt/intel_gtt.c     |  1 +
 drivers/gpu/drm/i915/gt/intel_gtt.h     |  4 ++
 drivers/gpu/drm/i915/i915_drv.c         |  4 ++
 drivers/gpu/drm/i915/i915_vma.c         |  5 ++
 drivers/gpu/drm/i915/i915_vma_types.h   |  3 +
 9 files changed, 135 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_svm.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_svm.h

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index ba9595960bbe..c2e48710eec8 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -137,6 +137,17 @@ config DRM_I915_GVT_KVMGT
          Choose this option if you want to enable KVMGT support for
          Intel GVT-g.
 
+config DRM_I915_SVM
+       bool "Enable Shared Virtual Memory support in i915"
+       depends on STAGING
+       depends on DRM_I915
+       default n
+       help
+         Choose this option if you want Shared Virtual Memory (SVM)
+         support in i915. With SVM support, one can share the virtual
+         address space between a process and the GPU. SVM is supported
+         on both integrated and discrete Intel GPUs.
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index b8c5f8934dbd..dbdbe85790f6 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -156,6 +156,9 @@ i915-y += \
          intel_region_lmem.o \
          intel_wopcm.o
 
+# SVM code
+i915-$(CONFIG_DRM_I915_SVM) += gem/i915_gem_svm.o
+
 # general-purpose microcontroller (GuC) support
 i915-y += gt/uc/intel_uc.o \
          gt/uc/intel_uc_fw.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_svm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_svm.c
new file mode 100644
index 000000000000..f26567ea0e3a
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_svm.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "i915_gem_gtt.h"
+#include "i915_gem_lmem.h"
+
+static struct i915_vma *
+i915_gem_vm_lookup_svm_vma(struct i915_address_space *vm,
+                          struct drm_i915_gem_object *obj,
+                          struct drm_i915_gem_vm_bind_va *va)
+{
+       struct i915_vma *vma, *tmp;
+
+       /* FIXME: Optimize lookup (use hashtable or tree) */
+       mutex_lock(&vm->svm_mutex);
+       list_for_each_entry_safe(vma, tmp, &vm->svm_list, svm_link) {
+               if (vma->obj != obj ||
+                   vma->node.start != va->start ||
+                   vma->node.size != va->length)
+                       continue;
+
+               list_del_init(&vma->svm_link);
+               mutex_unlock(&vm->svm_mutex);
+               return vma;
+       }
+       mutex_unlock(&vm->svm_mutex);
+       return NULL;
+}
+
+int i915_gem_vm_bind_svm_obj(struct i915_address_space *vm,
+                            struct drm_i915_gem_vm_bind_va *va,
+                            struct drm_file *file)
+{
+       struct drm_i915_gem_object *obj;
+       struct i915_vma *vma;
+       int ret = 0;
+
+       obj = i915_gem_object_lookup(file, va->handle);
+       if (!obj)
+               return -ENOENT;
+
+       /* For dgfx, ensure the obj is in device local memory only */
+       if (IS_DGFX(vm->i915) && !i915_gem_object_is_lmem(obj))
+               return -EINVAL;
+
+       if (!(va->flags & I915_GEM_VM_BIND_UNBIND)) {
+               struct i915_ggtt_view view;
+
+               view.type = I915_GGTT_VIEW_PARTIAL;
+               view.partial.offset = va->offset >> PAGE_SHIFT;
+               view.partial.size = va->length >> PAGE_SHIFT;
+               vma = i915_vma_instance(obj, vm, &view);
+               if (IS_ERR(vma)) {
+                       ret = PTR_ERR(vma);
+                       goto put_obj;
+               }
+               vma->va_start = va->start;
+               /* Disable eviction for now */
+               __i915_vma_pin(vma);
+
+               /*
+                * FIXME: Reserve VA here and bind only if the vm is active.
+                * This ensures any overlapping binding is rejected here itself.
+                * and we don't need to store va_start.
+                */
+               mutex_lock(&vm->svm_mutex);
+               list_add(&vma->svm_link, &vm->svm_list);
+               mutex_unlock(&vm->svm_mutex);
+       } else {
+               vma = i915_gem_vm_lookup_svm_vma(vm, obj, va);
+               if (vma) {
+                       __i915_vma_unpin(vma);
+                       __i915_vma_put(vma);
+               }
+       }
+put_obj:
+       i915_gem_object_put(obj);
+       return ret;
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_svm.h 
b/drivers/gpu/drm/i915/gem/i915_gem_svm.h
new file mode 100644
index 000000000000..e1ad125e86cc
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_svm.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef __I915_GEM_SVM_H
+#define __I915_GEM_SVM_H
+
+#include "i915_drv.h"
+
+#if defined(CONFIG_DRM_I915_SVM)
+int i915_gem_vm_bind_svm_obj(struct i915_address_space *vm,
+                            struct drm_i915_gem_vm_bind_va *va,
+                            struct drm_file *file);
+#else
+static inline int i915_gem_vm_bind_svm_obj(struct i915_address_space *vm,
+                                          struct drm_i915_gem_vm_bind_va *va,
+                                          struct drm_file *file)
+{ return -ENOTSUPP; }
+#endif
+
+#endif /* __I915_GEM_SVM_H */
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index ad5bf7fc851a..897aad1f7c08 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -276,6 +276,7 @@ void i915_address_space_init(struct i915_address_space *vm, 
int subclass)
 
        INIT_LIST_HEAD(&vm->bound_list);
 
+       INIT_LIST_HEAD(&vm->svm_list);
        mutex_init(&vm->svm_mutex);
        i915_active_init(&vm->active, __i915_vm_active, __i915_vm_retire);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h 
b/drivers/gpu/drm/i915/gt/intel_gtt.h
index f3e5469c4dc6..800c062a4b0e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -263,6 +263,10 @@ struct i915_address_space {
         */
        struct list_head bound_list;
 
+       /**
+        * List of SVM bind objects.
+        */
+       struct list_head svm_list;
        struct mutex svm_mutex; /* protects svm operations */
 
        struct pagestash free_pages;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 64ba02c55282..5631fa82bfed 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -62,6 +62,7 @@
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_mman.h"
+#include "gem/i915_gem_svm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_rc6.h"
@@ -2718,6 +2719,9 @@ static int i915_gem_vm_bind_ioctl(struct drm_device *dev, 
void *data,
                }
 
                switch (va.type) {
+               case I915_GEM_VM_BIND_SVM_OBJ:
+                       ret = i915_gem_vm_bind_svm_obj(vm, &va, file);
+                       break;
                default:
                        ret = -EINVAL;
                }
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 48af37355371..3e16b291f806 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -223,6 +223,7 @@ vma_create(struct drm_i915_gem_object *obj,
 
        spin_unlock(&obj->vma.lock);
 
+       INIT_LIST_HEAD(&vma->svm_link);
        return vma;
 
 err_vma:
@@ -1047,6 +1048,10 @@ void i915_vma_release(struct kref *ref)
                list_del(&vma->obj_link);
                rb_erase(&vma->obj_node, &obj->vma.tree);
                spin_unlock(&obj->vma.lock);
+
+               mutex_lock(&vma->vm->svm_mutex);
+               list_del_init(&vma->svm_link);
+               mutex_unlock(&vma->vm->svm_mutex);
        }
 
        __i915_vma_remove_closed(vma);
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h 
b/drivers/gpu/drm/i915/i915_vma_types.h
index e0942efd5236..d5a4fb4e43a4 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -269,6 +269,9 @@ struct i915_vma {
        /** This object's place on the active/inactive lists */
        struct list_head vm_link;
 
+       u64 va_start;
+       struct list_head svm_link; /* Link in persistent VMA list */
+
        struct list_head obj_link; /* Link in the object's VMA list */
        struct rb_node obj_node;
        struct hlist_node obj_hash;
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to