]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
Merge tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_object.c
index 969de54b62da8efc2bf9c6bdc6e8c7e6824a3a8a..fac4b6067efd6377f3a2681b9fd050878db21c13 100644 (file)
@@ -36,6 +36,7 @@
 #include <drm/drm_cache.h>
 #include "amdgpu.h"
 #include "amdgpu_trace.h"
+#include "amdgpu_amdkfd.h"
 
 static bool amdgpu_need_backup(struct amdgpu_device *adev)
 {
@@ -54,8 +55,13 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
        struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
        struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo);
 
+       if (bo->kfd_bo)
+               amdgpu_amdkfd_unreserve_system_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);
        amdgpu_bo_unref(&bo->parent);
        if (!list_empty(&bo->shadow_list)) {
@@ -169,13 +175,15 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
  * @size: size for the new BO
  * @align: alignment for the new BO
  * @domain: where to place it
- * @bo_ptr: resulting BO
+ * @bo_ptr: used to initialize BOs in structures
  * @gpu_addr: GPU addr of the pinned BO
  * @cpu_addr: optional CPU address mapping
  *
  * Allocates and pins a BO for kernel internal use, and returns it still
  * reserved.
  *
+ * Note: For bo_ptr new BO is only created if bo_ptr points to NULL.
+ *
  * Returns 0 on success, negative error code otherwise.
  */
 int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
@@ -187,10 +195,10 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
        int r;
 
        if (!*bo_ptr) {
-               r = amdgpu_bo_create(adev, size, align, true, domain,
+               r = amdgpu_bo_create(adev, size, align, domain,
                                     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
                                     AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
-                                    NULL, NULL, bo_ptr);
+                                    ttm_bo_type_kernel, NULL, bo_ptr);
                if (r) {
                        dev_err(adev->dev, "(%d) failed to allocate kernel bo\n",
                                r);
@@ -238,12 +246,14 @@ error_free:
  * @size: size for the new BO
  * @align: alignment for the new BO
  * @domain: where to place it
- * @bo_ptr: resulting BO
+ * @bo_ptr:  used to initialize BOs in structures
  * @gpu_addr: GPU addr of the pinned BO
  * @cpu_addr: optional CPU address mapping
  *
  * Allocates and pins a BO for kernel internal use.
  *
+ * Note: For bo_ptr new BO is only created if bo_ptr points to NULL.
+ *
  * Returns 0 on success, negative error code otherwise.
  */
 int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
@@ -331,23 +341,22 @@ fail:
        return false;
 }
 
-static int amdgpu_bo_do_create(struct amdgpu_device *adev,
-                              unsigned long size, int byte_align,
-                              bool kernel, u32 domain, u64 flags,
-                              struct sg_table *sg,
+static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
+                              int byte_align, u32 domain,
+                              u64 flags, enum ttm_bo_type type,
                               struct reservation_object *resv,
                               struct amdgpu_bo **bo_ptr)
 {
        struct ttm_operation_ctx ctx = {
-               .interruptible = !kernel,
+               .interruptible = (type != ttm_bo_type_kernel),
                .no_wait_gpu = false,
-               .allow_reserved_eviction = true,
-               .resv = resv
+               .resv = resv,
+               .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
        };
        struct amdgpu_bo *bo;
-       enum ttm_bo_type type;
        unsigned long page_align;
        size_t acc_size;
+       u32 domains;
        int r;
 
        page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
@@ -356,13 +365,6 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        if (!amdgpu_bo_validate_size(adev, size, domain))
                return -ENOMEM;
 
-       if (kernel) {
-               type = ttm_bo_type_kernel;
-       } else if (sg) {
-               type = ttm_bo_type_sg;
-       } else {
-               type = ttm_bo_type_device;
-       }
        *bo_ptr = NULL;
 
        acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size,
@@ -381,7 +383,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
                                         AMDGPU_GEM_DOMAIN_GWS |
                                         AMDGPU_GEM_DOMAIN_OA);
        bo->allowed_domains = bo->preferred_domains;
-       if (!kernel && bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
+       if (type != ttm_bo_type_kernel &&
+           bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
                bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
 
        bo->flags = flags;
@@ -415,12 +418,23 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
 #endif
 
        bo->tbo.bdev = &adev->mman.bdev;
-       amdgpu_ttm_placement_from_domain(bo, domain);
-
+       domains = bo->preferred_domains;
+retry:
+       amdgpu_ttm_placement_from_domain(bo, domains);
        r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
-                                &bo->placement, page_align, &ctx, NULL,
-                                acc_size, sg, resv, &amdgpu_ttm_bo_destroy);
-       if (unlikely(r != 0))
+                                &bo->placement, page_align, &ctx, acc_size,
+                                NULL, resv, &amdgpu_ttm_bo_destroy);
+
+       if (unlikely(r && r != -ERESTARTSYS)) {
+               if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
+                       bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+                       goto retry;
+               } else if (domains != bo->preferred_domains) {
+                       domains = bo->allowed_domains;
+                       goto retry;
+               }
+       }
+       if (unlikely(r))
                return r;
 
        if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
@@ -431,7 +445,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        else
                amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 0);
 
-       if (kernel)
+       if (type == ttm_bo_type_kernel)
                bo->tbo.priority = 1;
 
        if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
@@ -475,12 +489,11 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
        if (bo->shadow)
                return 0;
 
-       r = amdgpu_bo_do_create(adev, size, byte_align, true,
-                               AMDGPU_GEM_DOMAIN_GTT,
+       r = amdgpu_bo_do_create(adev, size, byte_align, AMDGPU_GEM_DOMAIN_GTT,
                                AMDGPU_GEM_CREATE_CPU_GTT_USWC |
                                AMDGPU_GEM_CREATE_SHADOW,
-                               NULL, bo->tbo.resv,
-                               &bo->shadow);
+                               ttm_bo_type_kernel,
+                               bo->tbo.resv, &bo->shadow);
        if (!r) {
                bo->shadow->parent = amdgpu_bo_ref(bo);
                mutex_lock(&adev->shadow_list_lock);
@@ -491,18 +504,17 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
        return r;
 }
 
-int amdgpu_bo_create(struct amdgpu_device *adev,
-                    unsigned long size, int byte_align,
-                    bool kernel, u32 domain, u64 flags,
-                    struct sg_table *sg,
+int amdgpu_bo_create(struct amdgpu_device *adev, unsigned long size,
+                    int byte_align, u32 domain,
+                    u64 flags, enum ttm_bo_type type,
                     struct reservation_object *resv,
                     struct amdgpu_bo **bo_ptr)
 {
        uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW;
        int r;
 
-       r = amdgpu_bo_do_create(adev, size, byte_align, kernel, domain,
-                               parent_flags, sg, resv, bo_ptr);
+       r = amdgpu_bo_do_create(adev, size, byte_align, domain,
+                               parent_flags, type, resv, bo_ptr);
        if (r)
                return r;
 
@@ -817,7 +829,8 @@ static const char *amdgpu_vram_names[] = {
        "GDDR4",
        "GDDR5",
        "HBM",
-       "DDR3"
+       "DDR3",
+       "DDR4",
 };
 
 int amdgpu_bo_init(struct amdgpu_device *adev)
This page took 0.041557 seconds and 4 git commands to generate.