drm/amdgpu: allocate PDs/PTs with no_gpu_wait in a page fault
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_object.c
index bea6f298dfdc5b47132abdba12a2b4999f693ac0..162e3849ff88a2d54437ca4de9d4f4dcb0f0311a 100644 (file)
@@ -80,14 +80,11 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo)
        if (bo->pin_count > 0)
                amdgpu_bo_subtract_pin_size(bo);
 
-       if (bo->kfd_bo)
-               amdgpu_amdkfd_unreserve_memory_limit(bo);
-
        amdgpu_bo_kunmap(bo);
 
-       if (bo->gem_base.import_attach)
-               drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg);
-       drm_gem_object_release(&bo->gem_base);
+       if (bo->tbo.base.import_attach)
+               drm_prime_gem_destroy(&bo->tbo.base, bo->tbo.sg);
+       drm_gem_object_release(&bo->tbo.base);
        /* in case amdgpu_device_recover_vram got NULL of bo->parent */
        if (!list_empty(&bo->shadow_list)) {
                mutex_lock(&adev->shadow_list_lock);
@@ -249,8 +246,9 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
        bp.size = size;
        bp.byte_align = align;
        bp.domain = domain;
-       bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
-               AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
+       bp.flags = cpu_addr ? AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
+               : AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+       bp.flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
        bp.type = ttm_bo_type_kernel;
        bp.resv = NULL;
 
@@ -413,13 +411,47 @@ fail:
        return false;
 }
 
+bool amdgpu_bo_support_uswc(u64 bo_flags)
+{
+
+#ifdef CONFIG_X86_32
+       /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit
+        * See https://bugs.freedesktop.org/show_bug.cgi?id=84627
+        */
+       return false;
+#elif defined(CONFIG_X86) && !defined(CONFIG_X86_PAT)
+       /* Don't try to enable write-combining when it can't work, or things
+        * may be slow
+        * See https://bugs.freedesktop.org/show_bug.cgi?id=88758
+        */
+
+#ifndef CONFIG_COMPILE_TEST
+#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
+        thanks to write-combining
+#endif
+
+       if (bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
+               DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
+                             "better performance thanks to write-combining\n");
+       return false;
+#else
+       /* For architectures that don't support WC memory,
+        * mask out the WC flag from the BO
+        */
+       if (!drm_arch_can_wc_memory())
+               return false;
+
+       return true;
+#endif
+}
+
 static int amdgpu_bo_do_create(struct amdgpu_device *adev,
                               struct amdgpu_bo_param *bp,
                               struct amdgpu_bo **bo_ptr)
 {
        struct ttm_operation_ctx ctx = {
                .interruptible = (bp->type != ttm_bo_type_kernel),
-               .no_wait_gpu = false,
+               .no_wait_gpu = bp->no_wait_gpu,
                .resv = bp->resv,
                .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
        };
@@ -454,7 +486,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        bo = kzalloc(sizeof(struct amdgpu_bo), GFP_KERNEL);
        if (bo == NULL)
                return -ENOMEM;
-       drm_gem_private_object_init(adev->ddev, &bo->gem_base, size);
+       drm_gem_private_object_init(adev->ddev, &bo->tbo.base, size);
        INIT_LIST_HEAD(&bo->shadow_list);
        bo->vm_bo = NULL;
        bo->preferred_domains = bp->preferred_domain ? bp->preferred_domain :
@@ -466,33 +498,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
 
        bo->flags = bp->flags;
 
-#ifdef CONFIG_X86_32
-       /* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit
-        * See https://bugs.freedesktop.org/show_bug.cgi?id=84627
-        */
-       bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
-#elif defined(CONFIG_X86) && !defined(CONFIG_X86_PAT)
-       /* Don't try to enable write-combining when it can't work, or things
-        * may be slow
-        * See https://bugs.freedesktop.org/show_bug.cgi?id=88758
-        */
-
-#ifndef CONFIG_COMPILE_TEST
-#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
-        thanks to write-combining
-#endif
-
-       if (bo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
-               DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
-                             "better performance thanks to write-combining\n");
-       bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
-#else
-       /* For architectures that don't support WC memory,
-        * mask out the WC flag from the BO
-        */
-       if (!drm_arch_can_wc_memory())
+       if (!amdgpu_bo_support_uswc(bo->flags))
                bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
-#endif
 
        bo->tbo.bdev = &adev->mman.bdev;
        if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA |
@@ -521,7 +528,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
            bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
                struct dma_fence *fence;
 
-               r = amdgpu_fill_buffer(bo, 0, bo->tbo.resv, &fence);
+               r = amdgpu_fill_buffer(bo, 0, bo->tbo.base.resv, &fence);
                if (unlikely(r))
                        goto fail_unreserve;
 
@@ -544,7 +551,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
 
 fail_unreserve:
        if (!bp->resv)
-               ww_mutex_unlock(&bo->tbo.resv->lock);
+               dma_resv_unlock(bo->tbo.base.resv);
        amdgpu_bo_unref(&bo);
        return r;
 }
@@ -565,7 +572,7 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
        bp.flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC |
                AMDGPU_GEM_CREATE_SHADOW;
        bp.type = ttm_bo_type_kernel;
-       bp.resv = bo->tbo.resv;
+       bp.resv = bo->tbo.base.resv;
 
        r = amdgpu_bo_do_create(adev, &bp, &bo->shadow);
        if (!r) {
@@ -606,13 +613,13 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
 
        if ((flags & AMDGPU_GEM_CREATE_SHADOW) && !(adev->flags & AMD_IS_APU)) {
                if (!bp->resv)
-                       WARN_ON(reservation_object_lock((*bo_ptr)->tbo.resv,
+                       WARN_ON(dma_resv_lock((*bo_ptr)->tbo.base.resv,
                                                        NULL));
 
                r = amdgpu_bo_create_shadow(adev, bp->size, *bo_ptr);
 
                if (!bp->resv)
-                       reservation_object_unlock((*bo_ptr)->tbo.resv);
+                       dma_resv_unlock((*bo_ptr)->tbo.base.resv);
 
                if (r)
                        amdgpu_bo_unref(bo_ptr);
@@ -709,7 +716,7 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
                return 0;
        }
 
-       r = reservation_object_wait_timeout_rcu(bo->tbo.resv, false, false,
+       r = dma_resv_wait_timeout_rcu(bo->tbo.base.resv, false, false,
                                                MAX_SCHEDULE_TIMEOUT);
        if (r < 0)
                return r;
@@ -1087,7 +1094,7 @@ int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags)
  */
 void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 *tiling_flags)
 {
-       lockdep_assert_held(&bo->tbo.resv->lock.base);
+       dma_resv_assert_held(bo->tbo.base.resv);
 
        if (tiling_flags)
                *tiling_flags = bo->tiling_flags;
@@ -1211,6 +1218,42 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
        trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
 }
 
+/**
+ * amdgpu_bo_move_notify - notification about a BO being released
+ * @bo: pointer to a buffer object
+ *
+ * Wipes VRAM buffers whose contents should not be leaked before the
+ * memory is released.
+ */
+void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
+{
+       struct dma_fence *fence = NULL;
+       struct amdgpu_bo *abo;
+       int r;
+
+       if (!amdgpu_bo_is_amdgpu_bo(bo))
+               return;
+
+       abo = ttm_to_amdgpu_bo(bo);
+
+       if (abo->kfd_bo)
+               amdgpu_amdkfd_unreserve_memory_limit(abo);
+
+       if (bo->mem.mem_type != TTM_PL_VRAM || !bo->mem.mm_node ||
+           !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE))
+               return;
+
+       dma_resv_lock(bo->base.resv, NULL);
+
+       r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence);
+       if (!WARN_ON(r)) {
+               amdgpu_bo_fence(abo, fence, false);
+               dma_fence_put(fence);
+       }
+
+       dma_resv_unlock(bo->base.resv);
+}
+
 /**
  * amdgpu_bo_fault_reserve_notify - notification about a memory fault
  * @bo: pointer to a buffer object
@@ -1283,12 +1326,12 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
 void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
                     bool shared)
 {
-       struct reservation_object *resv = bo->tbo.resv;
+       struct dma_resv *resv = bo->tbo.base.resv;
 
        if (shared)
-               reservation_object_add_shared_fence(resv, fence);
+               dma_resv_add_shared_fence(resv, fence);
        else
-               reservation_object_add_excl_fence(resv, fence);
+               dma_resv_add_excl_fence(resv, fence);
 }
 
 /**
@@ -1308,7 +1351,7 @@ int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr)
        int r;
 
        amdgpu_sync_create(&sync);
-       amdgpu_sync_resv(adev, &sync, bo->tbo.resv, owner, false);
+       amdgpu_sync_resv(adev, &sync, bo->tbo.base.resv, owner, false);
        r = amdgpu_sync_wait(&sync, intr);
        amdgpu_sync_free(&sync);
 
@@ -1328,7 +1371,7 @@ int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr)
 u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
 {
        WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
-       WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
+       WARN_ON_ONCE(!dma_resv_is_locked(bo->tbo.base.resv) &&
                     !bo->pin_count && bo->tbo.type != ttm_bo_type_kernel);
        WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
        WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM &&