From: Christian König <[email protected]>

"AMDGPU_GEM_DOMAIN_MMIO_REMAP" - Never activated as UAPI and it turned
out that this was to inflexible.

Allocate the MMIO_REMAP buffer object as a regular GEM BO and explicitly
move it into the fixed AMDGPU_PL_MMIO_REMAP placement at the TTM level.

This avoids relying on GEM domain bits for MMIO_REMAP, keeps the
placement purely internal, and makes the lifetime and pinning of the
global MMIO_REMAP BO explicit. The BO is pinned in TTM so it cannot be
migrated or evicted.

The corresponding free path relies on normal DRM teardown ordering,
where no further user ioctls can access the global BO once TTM teardown
begins.

v2 (Srini):
- Updated patch title.
- Drop use of AMDGPU_GEM_DOMAIN_MMIO_REMAP in amdgpu_ttm.c. The
  MMIO_REMAP domain bit is removed from UAPI, so keep the MMIO_REMAP BO
  allocation domain-less (bp.domain = 0) and rely on the TTM placement
  (AMDGPU_PL_MMIO_REMAP) for backing/pinning.
- Keep fdinfo/mem-stats visibility for MMIO_REMAP by classifying BOs
  based on bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP, since the
  domain bit is removed.

v3: Squash patches #1 & #3

Fixes: dd2bf86d1383 ("drm/amdgpu/uapi: Introduce AMDGPU_GEM_DOMAIN_MMIO_REMAP")
Fixes: 2f711aebfa64 ("drm/amdgpu/ttm: Allocate/Free 4K MMIO_REMAP Singleton")
Cc: Alex Deucher <[email protected]>
Cc: Christian König <[email protected]>
Cc: Leo Liu <[email protected]>
Cc: Ruijing Dong <[email protected]>
Cc: David (Ming Qiang) Wu <[email protected]>
Signed-off-by: Srinivasan Shanmugam <[email protected]>
Signed-off-by: Christian König <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c    |  3 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 21 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 77 ++++++++++++++--------
 include/uapi/drm/amdgpu_drm.h              |  6 +-
 5 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 9b81a6677f90..b46b61297f68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -458,9 +458,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void 
*data,
        /* always clear VRAM */
        flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
 
-       if (args->in.domains & AMDGPU_GEM_DOMAIN_MMIO_REMAP)
-               return -EINVAL;
-
        /* create a gem object to contain this object in */
        if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
            AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index b676310ce9ac..1fb956400696 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -153,14 +153,6 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo 
*abo, u32 domain)
                c++;
        }
 
-       if (domain & AMDGPU_GEM_DOMAIN_MMIO_REMAP) {
-               places[c].fpfn = 0;
-               places[c].lpfn = 0;
-               places[c].mem_type = AMDGPU_PL_MMIO_REMAP;
-               places[c].flags = 0;
-               c++;
-       }
-
        if (domain & AMDGPU_GEM_DOMAIN_GTT) {
                places[c].fpfn = 0;
                places[c].lpfn = 0;
@@ -1546,8 +1538,17 @@ u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)
  */
 uint32_t amdgpu_bo_mem_stats_placement(struct amdgpu_bo *bo)
 {
-       uint32_t domain = bo->preferred_domains & AMDGPU_GEM_DOMAIN_MASK;
+       u32 domain;
 
+       /*
+        * MMIO_REMAP is internal now, so it no longer maps from a userspace
+        * domain bit. Keep fdinfo/mem-stats visibility by checking the actual
+        * TTM placement.
+        */
+       if (bo->tbo.resource && bo->tbo.resource->mem_type == 
AMDGPU_PL_MMIO_REMAP)
+               return AMDGPU_PL_MMIO_REMAP;
+
+       domain = bo->preferred_domains & AMDGPU_GEM_DOMAIN_MASK;
        if (!domain)
                return TTM_PL_SYSTEM;
 
@@ -1566,8 +1567,6 @@ uint32_t amdgpu_bo_mem_stats_placement(struct amdgpu_bo 
*bo)
                return AMDGPU_PL_OA;
        case AMDGPU_GEM_DOMAIN_DOORBELL:
                return AMDGPU_PL_DOORBELL;
-       case AMDGPU_GEM_DOMAIN_MMIO_REMAP:
-               return AMDGPU_PL_MMIO_REMAP;
        default:
                return TTM_PL_SYSTEM;
        }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 52c2d1731aab..912c9afaf9e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -168,8 +168,6 @@ static inline unsigned amdgpu_mem_type_to_domain(u32 
mem_type)
                return AMDGPU_GEM_DOMAIN_OA;
        case AMDGPU_PL_DOORBELL:
                return AMDGPU_GEM_DOMAIN_DOORBELL;
-       case AMDGPU_PL_MMIO_REMAP:
-               return AMDGPU_GEM_DOMAIN_MMIO_REMAP;
        default:
                break;
        }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index f27ffe64aafa..6d7a5bf2d0c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1909,42 +1909,45 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device 
*adev)
 }
 
 /**
- * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton 4K MMIO_REMAP BO
+ * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton MMIO_REMAP BO
  * @adev: amdgpu device
  *
- * Allocates a one-page (4K) GEM BO in AMDGPU_GEM_DOMAIN_MMIO_REMAP when the
+ * Allocates a global BO with backing AMDGPU_PL_MMIO_REMAP when the
  * hardware exposes a remap base (adev->rmmio_remap.bus_addr) and the host
  * PAGE_SIZE is <= AMDGPU_GPU_PAGE_SIZE (4K). The BO is created as a regular
  * GEM object (amdgpu_bo_create).
  *
- * The BO is created as a normal GEM object via amdgpu_bo_create(), then
- * reserved and pinned at the TTM level (ttm_bo_pin()) so it can never be
- * migrated or evicted. No CPU mapping is established here.
- *
  * Return:
  *  * 0 on success or intentional skip (feature not present/unsupported)
  *  * negative errno on allocation failure
  */
-static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
+static int amdgpu_ttm_alloc_mmio_remap_bo(struct amdgpu_device *adev)
 {
+       struct ttm_operation_ctx ctx = { false, false };
+       struct ttm_placement placement;
+       struct ttm_buffer_object *tbo;
+       struct ttm_place placements;
        struct amdgpu_bo_param bp;
+       struct ttm_resource *tmp;
        int r;
 
        /* Skip if HW doesn't expose remap, or if PAGE_SIZE > 
AMDGPU_GPU_PAGE_SIZE (4K). */
        if (!adev->rmmio_remap.bus_addr || PAGE_SIZE > AMDGPU_GPU_PAGE_SIZE)
                return 0;
 
+       /*
+        * Allocate a BO first and then move it to AMDGPU_PL_MMIO_REMAP.
+        * The initial TTM resource assigned by amdgpu_bo_create() is
+        * replaced below with a fixed MMIO_REMAP placement.
+        */
        memset(&bp, 0, sizeof(bp));
-
-       /* Create exactly one GEM BO in the MMIO_REMAP domain. */
-       bp.type        = ttm_bo_type_device;          /* userspace-mappable GEM 
*/
-       bp.size        = AMDGPU_GPU_PAGE_SIZE;        /* 4K */
+       bp.type        = ttm_bo_type_device;
+       bp.size        = AMDGPU_GPU_PAGE_SIZE;
        bp.byte_align  = AMDGPU_GPU_PAGE_SIZE;
-       bp.domain      = AMDGPU_GEM_DOMAIN_MMIO_REMAP;
+       bp.domain      = 0;
        bp.flags       = 0;
        bp.resv        = NULL;
        bp.bo_ptr_size = sizeof(struct amdgpu_bo);
-
        r = amdgpu_bo_create(adev, &bp, &adev->rmmio_remap.bo);
        if (r)
                return r;
@@ -1953,42 +1956,60 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct 
amdgpu_device *adev)
        if (r)
                goto err_unref;
 
+       tbo = &adev->rmmio_remap.bo->tbo;
+
        /*
         * MMIO_REMAP is a fixed I/O placement (AMDGPU_PL_MMIO_REMAP).
-        * Use TTM-level pin so the BO cannot be evicted/migrated,
-        * independent of GEM domains. This
-        * enforces the “fixed I/O window”
         */
-       ttm_bo_pin(&adev->rmmio_remap.bo->tbo);
+       placement.num_placement = 1;
+       placement.placement = &placements;
+       placements.fpfn = 0;
+       placements.lpfn = 0;
+       placements.mem_type = AMDGPU_PL_MMIO_REMAP;
+       placements.flags = 0;
+       /* Force the BO into the fixed MMIO_REMAP placement */
+       r = ttm_bo_mem_space(tbo, &placement, &tmp, &ctx);
+       if (unlikely(r))
+               goto err_unlock;
+
+       ttm_resource_free(tbo, &tbo->resource);
+       ttm_bo_assign_mem(tbo, tmp);
+       ttm_bo_pin(tbo);
 
        amdgpu_bo_unreserve(adev->rmmio_remap.bo);
        return 0;
 
+err_unlock:
+       amdgpu_bo_unreserve(adev->rmmio_remap.bo);
+
 err_unref:
-       if (adev->rmmio_remap.bo)
-               amdgpu_bo_unref(&adev->rmmio_remap.bo);
+       amdgpu_bo_unref(&adev->rmmio_remap.bo);
        adev->rmmio_remap.bo = NULL;
        return r;
 }
 
 /**
- * amdgpu_ttm_mmio_remap_bo_fini - Free the singleton MMIO_REMAP BO
+ * amdgpu_ttm_free_mmio_remap_bo - Free the singleton MMIO_REMAP BO
  * @adev: amdgpu device
  *
  * Frees the kernel-owned MMIO_REMAP BO if it was allocated by
  * amdgpu_ttm_mmio_remap_bo_init().
  */
-static void amdgpu_ttm_mmio_remap_bo_fini(struct amdgpu_device *adev)
+static void amdgpu_ttm_free_mmio_remap_bo(struct amdgpu_device *adev)
 {
-       struct amdgpu_bo *bo = adev->rmmio_remap.bo;
-
-       if (!bo)
-               return;   /* <-- safest early exit */
+       if (!adev->rmmio_remap.bo)
+               return;
 
        if (!amdgpu_bo_reserve(adev->rmmio_remap.bo, true)) {
                ttm_bo_unpin(&adev->rmmio_remap.bo->tbo);
                amdgpu_bo_unreserve(adev->rmmio_remap.bo);
        }
+
+    /*
+     * At this point we rely on normal DRM teardown ordering:
+     * no new user ioctls can access the global MMIO_REMAP BO
+     * once TTM teardown begins.
+     */
        amdgpu_bo_unref(&adev->rmmio_remap.bo);
        adev->rmmio_remap.bo = NULL;
 }
@@ -2169,8 +2190,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
                return r;
        }
 
-       /* Allocate the singleton MMIO_REMAP BO (4K) if supported */
-       r = amdgpu_ttm_mmio_remap_bo_init(adev);
+       /* Allocate the singleton MMIO_REMAP BO if supported */
+       r = amdgpu_ttm_alloc_mmio_remap_bo(adev);
        if (r)
                return r;
 
@@ -2238,7 +2259,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
        amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
                                        &adev->mman.sdma_access_ptr);
 
-       amdgpu_ttm_mmio_remap_bo_fini(adev);
+       amdgpu_ttm_free_mmio_remap_bo(adev);
        amdgpu_ttm_fw_reserve_vram_fini(adev);
        amdgpu_ttm_drv_reserve_vram_fini(adev);
 
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 9680548ee41b..ab2bf47553e1 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -105,8 +105,6 @@ extern "C" {
  *
  * %AMDGPU_GEM_DOMAIN_DOORBELL Doorbell. It is an MMIO region for
  * signalling user mode queues.
- *
- * %AMDGPU_GEM_DOMAIN_MMIO_REMAP       MMIO remap page (special mapping for 
HDP flushing).
  */
 #define AMDGPU_GEM_DOMAIN_CPU          0x1
 #define AMDGPU_GEM_DOMAIN_GTT          0x2
@@ -115,15 +113,13 @@ extern "C" {
 #define AMDGPU_GEM_DOMAIN_GWS          0x10
 #define AMDGPU_GEM_DOMAIN_OA           0x20
 #define AMDGPU_GEM_DOMAIN_DOORBELL     0x40
-#define AMDGPU_GEM_DOMAIN_MMIO_REMAP   0x80
 #define AMDGPU_GEM_DOMAIN_MASK         (AMDGPU_GEM_DOMAIN_CPU | \
                                         AMDGPU_GEM_DOMAIN_GTT | \
                                         AMDGPU_GEM_DOMAIN_VRAM | \
                                         AMDGPU_GEM_DOMAIN_GDS | \
                                         AMDGPU_GEM_DOMAIN_GWS | \
                                         AMDGPU_GEM_DOMAIN_OA | \
-                                        AMDGPU_GEM_DOMAIN_DOORBELL | \
-                                        AMDGPU_GEM_DOMAIN_MMIO_REMAP)
+                                        AMDGPU_GEM_DOMAIN_DOORBELL)
 
 /* Flag that CPU access will be required for the case of VRAM domain */
 #define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED  (1 << 0)
-- 
2.34.1

Reply via email to