From: Venkata Sandeep Dhanalakota <venkata.s.dhanalak...@intel.com>

As PCIe is non-coherent link, do not allow direct access to buffer
objects across the PCIe link for SVM case. Upon CPU accesses (mmap, pread),
migrate buffer object to host memory.

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>
Cc: Niranjana Vishwanathapura <niranjana.vishwanathap...@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalak...@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   | 10 ++++++++
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 29 +++++++++++++++++-----
 drivers/gpu/drm/i915/gem/i915_gem_object.h |  3 +++
 drivers/gpu/drm/i915/intel_memory_region.c |  4 ---
 drivers/gpu/drm/i915/intel_memory_region.h |  4 +++
 5 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d60973603cc1..0b41e2f3098c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -13,6 +13,7 @@
 #include "i915_drv.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
+#include "i915_gem_lmem.h"
 #include "i915_gem_object.h"
 #include "i915_trace.h"
 #include "i915_vma.h"
@@ -235,6 +236,15 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
        if (i915_gem_object_is_readonly(obj) && write)
                return VM_FAULT_SIGBUS;
 
+       /* Implicitly migrate BO to SMEM if it is SVM mapped */
+       if (i915_gem_object_svm_mapped(obj) && i915_gem_object_is_lmem(obj)) {
+               u32 regions[] = { REGION_MAP(INTEL_MEMORY_SYSTEM, 0) };
+
+               ret = i915_gem_object_migrate_region(obj, regions, 1);
+               if (ret)
+                       goto err;
+       }
+
        /* We don't use vmf->pgoff since that has the fake offset */
        page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 10defa723bc9..a7dee1b749cb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -493,12 +493,17 @@ __region_id(u32 region)
        return INTEL_REGION_UNKNOWN;
 }
 
+bool
+i915_gem_object_svm_mapped(struct drm_i915_gem_object *obj)
+{
+       return false;
+}
+
 static int i915_gem_object_region_select(struct drm_i915_private *dev_priv,
                                         struct drm_i915_gem_object_param *args,
                                         struct drm_file *file,
                                         struct drm_i915_gem_object *obj)
 {
-       struct intel_context *ce = dev_priv->engine[BCS0]->kernel_context;
        u32 __user *uregions = u64_to_user_ptr(args->data);
        u32 uregions_copy[INTEL_REGION_UNKNOWN];
        int i, ret;
@@ -518,16 +523,28 @@ static int i915_gem_object_region_select(struct 
drm_i915_private *dev_priv,
                ++uregions;
        }
 
+       ret = i915_gem_object_migrate_region(obj, uregions_copy,
+                                            args->size);
+
+       return ret;
+}
+
+int i915_gem_object_migrate_region(struct drm_i915_gem_object *obj,
+                                  u32 *regions, int size)
+{
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+       struct intel_context *ce = dev_priv->engine[BCS0]->kernel_context;
+       int i, ret;
+
        mutex_lock(&dev_priv->drm.struct_mutex);
        ret = i915_gem_object_prepare_move(obj);
        if (ret) {
                DRM_ERROR("Cannot set memory region, object in use\n");
-               goto err;
+               goto err;
        }
 
-       for (i = 0; i < args->size; i++) {
-               u32 region = uregions_copy[i];
-               enum intel_region_id id = __region_id(region);
+       for (i = 0; i < size; i++) {
+               enum intel_region_id id = __region_id(regions[i]);
 
                if (id == INTEL_REGION_UNKNOWN) {
                        ret = -EINVAL;
@@ -537,7 +554,7 @@ static int i915_gem_object_region_select(struct 
drm_i915_private *dev_priv,
                ret = i915_gem_object_migrate(obj, ce, id);
                if (!ret) {
                        if (!i915_gem_object_has_pages(obj) &&
-                           MEMORY_TYPE_FROM_REGION(region) ==
+                           MEMORY_TYPE_FROM_REGION(regions[i]) ==
                            INTEL_MEMORY_LOCAL) {
                                /*
                                 * TODO: this should be part of get_pages(),
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 4d6da91beaff..eec31d9a4fa2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -47,6 +47,9 @@ int i915_gem_object_prepare_move(struct drm_i915_gem_object 
*obj);
 int i915_gem_object_migrate(struct drm_i915_gem_object *obj,
                            struct intel_context *ce,
                            enum intel_region_id id);
+bool i915_gem_object_svm_mapped(struct drm_i915_gem_object *obj);
+int i915_gem_object_migrate_region(struct drm_i915_gem_object *obj,
+                                  u32 *uregions, int size);
 
 void i915_gem_flush_free_objects(struct drm_i915_private *i915);
 
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
b/drivers/gpu/drm/i915/intel_memory_region.c
index baaeaecc64af..049a1b482d9d 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -6,10 +6,6 @@
 #include "intel_memory_region.h"
 #include "i915_drv.h"
 
-/* XXX: Hysterical raisins. BIT(inst) needs to just be (inst) at some point. */
-#define REGION_MAP(type, inst) \
-       BIT((type) + INTEL_MEMORY_TYPE_SHIFT) | BIT(inst)
-
 const u32 intel_region_map[] = {
        [INTEL_REGION_SMEM] = REGION_MAP(INTEL_MEMORY_SYSTEM, 0),
        [INTEL_REGION_LMEM] = REGION_MAP(INTEL_MEMORY_LOCAL, 0),
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h 
b/drivers/gpu/drm/i915/intel_memory_region.h
index 238722009677..4622c086c06d 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -41,6 +41,10 @@ enum intel_region_id {
 
 #define INTEL_MEMORY_TYPE_SHIFT 16
 
+/* XXX: Hysterical raisins. BIT(inst) needs to just be (inst) at some point. */
+#define REGION_MAP(type, inst) \
+       (BIT((type) + INTEL_MEMORY_TYPE_SHIFT) | BIT(inst))
+
 #define MEMORY_TYPE_FROM_REGION(r) (ilog2((r) >> INTEL_MEMORY_TYPE_SHIFT))
 #define MEMORY_INSTANCE_FROM_REGION(r) (ilog2((r) & 0xffff))
 
-- 
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