Maintain all VM_BIND bindings in an list. Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Jon Bloomfield <jon.bloomfield@xxxxxxxxx> Cc: Daniel Vetter <daniel.vetter@xxxxxxxxx> Cc: Chris P Wilson <chris.p.wilson@xxxxxxxxx> Cc: Sudeep Dutt <sudeep.dutt@xxxxxxxxx> Cc: Stuart Summers <stuart.summers@xxxxxxxxx> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@xxxxxxxxx> --- 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 Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx