[Intel-gfx] [RFC 4/8] drm/i915/svm: Manage SVM bindings added using VM_BIND
Niranjana Vishwanathapura
niranjana.vishwanathapura at intel.com
Fri Jan 24 08:53:58 UTC 2020
Maintain all VM_BIND bindings in an list.
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield at intel.com>
Cc: Daniel Vetter <daniel.vetter at intel.com>
Cc: Chris P Wilson <chris.p.wilson at intel.com>
Cc: Sudeep Dutt <sudeep.dutt at intel.com>
Cc: Stuart Summers <stuart.summers at intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
---
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
More information about the Intel-gfx
mailing list