NAK, please use the existing functionality for that.

Using amdgpu_bo_do_create() with domain=0 will just create the amdgpu_bo structure without allocating any backing memory.

This BO can then pinned to the desired VRAM location using amdgpu_bo_pin().

Regards,
Christian.

Am 28.09.2017 um 10:36 schrieb Horace Chen:
Add two function to create and free bo at the specified position
on the VRAM.

Add a new parameter to amdgpu_bo_do_create to tell the start
address of the special bo. If the start address is located in
the GPU MC address space, the placement will be set to the exact
place according to the size and start address. Otherwise the start
address will be ingored.

Signed-off-by: Horace Chen <horace.c...@amd.com>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 129 ++++++++++++++++++++++++++++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |   6 ++
  2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 6982bae..0695160 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -284,6 +284,7 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 
*gpu_addr,
  }
static int amdgpu_bo_do_create(struct amdgpu_device *adev,
+                              u64 start_addr,
                               unsigned long size, int byte_align,
                               bool kernel, u32 domain, u64 flags,
                               struct sg_table *sg,
@@ -297,9 +298,12 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        u64 initial_bytes_moved, bytes_moved;
        size_t acc_size;
        int r;
+       int i;
+       bool vram_restricted = false;
page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
        size = ALIGN(size, PAGE_SIZE);
+       start_addr = ALIGN(start_addr, PAGE_SIZE);
if (kernel) {
                type = ttm_bo_type_kernel;
@@ -366,6 +370,32 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        bo->tbo.bdev = &adev->mman.bdev;
        amdgpu_ttm_placement_from_domain(bo, domain);
+ /*
+        * if domain is VRAM && start_addr in vram address space,
+        * set the place to the specified place
+        */
+       if ((domain == AMDGPU_GEM_DOMAIN_VRAM) &&
+           start_addr >= adev->mc.vram_start &&
+           (start_addr + size) < adev->mc.vram_end) {
+               start_addr -= adev->mc.vram_start;
+               vram_restricted = true;
+       } else if ((domain == AMDGPU_GEM_DOMAIN_GTT) &&
+           start_addr >= adev->mc.gart_start &&
+           (start_addr + size) < adev->mc.gart_end) {
+               /* if in gart address space */
+               start_addr -= adev->mc.gart_start;
+               vram_restricted = true;
+       }
+
+       if (vram_restricted) {
+               for (i = 0; i < bo->placement.num_placement; ++i) {
+                       bo->placements[i].fpfn =
+                               start_addr >> PAGE_SHIFT;
+                       bo->placements[i].lpfn =
+                               (start_addr + size) >> PAGE_SHIFT;
+               }
+       }
+
        initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
        /* Kernel allocation are uninterruptible */
        r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
@@ -418,6 +448,101 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        return r;
  }
+/**
+ * amdgpu_bo_create_vram_restricted_kernel -
+ *    create BO at the specified place on the VRAM.
+ *
+ * @adev: amdgpu device object
+ * @offset: start offset of the new BO
+ * @size: size for the new BO
+ * @byte_align: alignment for the new BO
+ * @flags: addition flags for the BO
+ * @bo_ptr: resulting BO
+ * @gpu_addr: GPU addr of the pinned BO
+ * @cpu_addr: optional CPU address mapping
+ *
+ * Allocates and pins a BO at the specified place on the VRAM.
+ *
+ * Returns 0 on success, negative error code otherwise.
+ */
+int amdgpu_bo_create_vram_restricted_kernel(struct amdgpu_device *adev,
+                    u64 offset, unsigned long size, int byte_align,
+                    u64 flags, struct amdgpu_bo **bo_ptr,
+                    u64 *gpu_addr, void **cpu_addr)
+{
+       int r;
+       u64 start_addr = offset + adev->mc.vram_start;
+       /* specified memory must be in contiguous*/
+       flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
+
+       r = amdgpu_bo_do_create(adev, start_addr, size, byte_align, true,
+               AMDGPU_GEM_DOMAIN_VRAM, flags, NULL, NULL, 0, bo_ptr);
+       if (r)
+               return r;
+
+       r = amdgpu_bo_reserve(*bo_ptr, false);
+       if (r)
+               goto error_reserve;
+       r = amdgpu_bo_pin_restricted(*bo_ptr,
+               AMDGPU_GEM_DOMAIN_VRAM, offset, (offset + size),
+               gpu_addr);
+       if (r)
+               goto error_pin;
+       if (cpu_addr) {
+               r = amdgpu_bo_kmap(*bo_ptr,
+                                       cpu_addr);
+               if (r)
+                       goto error_kmap;
+       }
+
+       amdgpu_bo_unreserve(*bo_ptr);
+
+       return r;
+error_kmap:
+       amdgpu_bo_unpin(*bo_ptr);
+error_pin:
+       amdgpu_bo_unreserve(*bo_ptr);
+error_reserve:
+       amdgpu_bo_unref(bo_ptr);
+       if (cpu_addr)
+               *cpu_addr = NULL;
+       if (gpu_addr)
+               *gpu_addr = 0;
+       return r;
+}
+
+/**
+ * amdgpu_bo_free_vram_restricted_kernel - free BO for restricted vram
+ *
+ * @bo: amdgpu BO to free
+ * @gpu_addr : gpu address
+ * @cpu_addr : cpu address if mapped
+ *
+ * unmaps and unpin a BO which created by
+ * amdgpu_bo_create_vram_restricted_kernel.
+ */
+void amdgpu_bo_free_vram_restricted_kernel(struct amdgpu_bo **bo, u64 
*gpu_addr,
+                          void **cpu_addr)
+{
+       if (*bo == NULL)
+               return;
+
+       if (likely(amdgpu_bo_reserve(*bo, true) == 0)) {
+               if (cpu_addr)
+                       amdgpu_bo_kunmap(*bo);
+               amdgpu_bo_unpin(*bo);
+               amdgpu_bo_unreserve(*bo);
+       }
+       amdgpu_bo_unref(bo);
+
+       if (gpu_addr)
+               *gpu_addr = 0;
+
+       if (cpu_addr)
+               *cpu_addr = NULL;
+}
+
+
  static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
                                   unsigned long size, int byte_align,
                                   struct amdgpu_bo *bo)
@@ -427,7 +552,7 @@ 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,
+       r = amdgpu_bo_do_create(adev, 0, size, byte_align, true,
                                AMDGPU_GEM_DOMAIN_GTT,
                                AMDGPU_GEM_CREATE_CPU_GTT_USWC |
                                AMDGPU_GEM_CREATE_SHADOW,
@@ -457,7 +582,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
        uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW;
        int r;
- r = amdgpu_bo_do_create(adev, size, byte_align, kernel, domain,
+       r = amdgpu_bo_do_create(adev, 0, size, byte_align, kernel, domain,
                                parent_flags, sg, resv, init_value, bo_ptr);
        if (r)
                return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 39b6bf6..0f34ba77 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -205,6 +205,12 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
                            u64 *gpu_addr, void **cpu_addr);
  void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
                           void **cpu_addr);
+int amdgpu_bo_create_vram_restricted_kernel(struct amdgpu_device *adev,
+                    u64 offset, unsigned long size, int byte_align,
+                    u64 flags, struct amdgpu_bo **bo_ptr,
+                    u64 *gpu_addr, void **cpu_addr);
+void amdgpu_bo_free_vram_restricted_kernel(struct amdgpu_bo **bo, u64 
*gpu_addr,
+                          void **cpu_addr);
  int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);
  void *amdgpu_bo_kptr(struct amdgpu_bo *bo);
  void amdgpu_bo_kunmap(struct amdgpu_bo *bo);


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to