+       if (((domain & AMDGPU_GEM_DOMAIN_VRAM) ||
+           (domain & AMDGPU_GEM_DOMAIN_GTT)) && offset != ~0) {

Why not make it simple? Like:

if ((domain & (AMDGPU_GEM_DOMAIN_VRAM|AMDGPU_GEM_DOMAIN_GTT)) && offset !=~0)

-----Original Message-----
From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of 
Horace Chen
Sent: 2017年11月1日 16:58
To: amd-gfx@lists.freedesktop.org
Cc: Chen, Horace <horace.c...@amd.com>
Subject: [PATCH 1/3] drm/amdgpu: Add interface to protect VRAM at exact position

The existing method to reserve specified VRAM is to create a bo on system 
domain then pin it to VRAM. But in this process the existing data on the VRAM 
will be broken, because ttm will allocate a zero buffer on system domain then 
copy the zeroes to VRAM.

Actually SRIOV need to reserve VRAM to protect data at exact position.

So here add a new interface to create bo at the exact position directly and 
then pin it immediately to avoid eviction and avoid breaking the existing data 
on the VRAM.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index e44b880..7108dc5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -281,7 +281,7 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 
*gpu_addr,
                *cpu_addr = NULL;
 }
 
-static int amdgpu_bo_do_create(struct amdgpu_device *adev,
+static int amdgpu_bo_do_create(struct amdgpu_device *adev, u64 offset,
                               unsigned long size, int byte_align,
                               bool kernel, u32 domain, u64 flags,
                               struct sg_table *sg,
@@ -295,6 +295,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        u64 initial_bytes_moved, bytes_moved;
        size_t acc_size;
        int r;
+       int i;
 
        page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
        size = ALIGN(size, PAGE_SIZE);
@@ -364,6 +365,21 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
        bo->tbo.bdev = &adev->mman.bdev;
        amdgpu_ttm_placement_from_domain(bo, domain);
 
+       /*
+        * if offset is not ~0, it means the offset of this bo is restricted.
+        * modify the placement to create bo at the exact place.
+        */
+       if (((domain & AMDGPU_GEM_DOMAIN_VRAM) ||
+           (domain & AMDGPU_GEM_DOMAIN_GTT)) && offset != ~0) {
+               offset = ALIGN(offset, PAGE_SIZE);
+               for (i = 0; i < bo->placement.num_placement; ++i) {
+                       bo->placements[i].fpfn =
+                           offset >> PAGE_SHIFT;
+                       bo->placements[i].lpfn =
+                           (offset + 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, @@ 
-416,6 +432,68 @@ 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;
+       /* specified memory must be in contiguous*/
+       flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
+
+       r = amdgpu_bo_do_create(adev, offset, 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;
+}
+
 static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
                                   unsigned long size, int byte_align,
                                   struct amdgpu_bo *bo)
@@ -425,7 +503,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,
@@ -455,7 +533,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 33615e2..71f4f82 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -216,6 +216,10 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
                            unsigned long size, int align,
                            u32 domain, struct amdgpu_bo **bo_ptr,
                            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_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
                           void **cpu_addr);
 int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);
--
2.7.4

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

Reply via email to