From 4fdbe3a623b264d0f361a81a41baff16b4aa6bb1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 16 Apr 2025 17:27:41 -0400 Subject: [PATCH 01/16] drm/amdgpu/userq: rename eviction helpers suspend/resume -> evict/restore Rename to avoid confusion with the system suspend and resume helpers. v2: update error messages Reviewed-by: Prike Liang Signed-off-by: Alex Deucher --- .../drm/amd/amdgpu/amdgpu_eviction_fence.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 20 +++++++++---------- drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c index 0075469550b0..02164bca51a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c @@ -112,7 +112,7 @@ amdgpu_eviction_fence_suspend_worker(struct work_struct *work) if (!ev_fence) goto unlock; - amdgpu_userqueue_suspend(uq_mgr, ev_fence); + amdgpu_userqueue_evict(uq_mgr, ev_fence); unlock: mutex_unlock(&uq_mgr->userq_mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c index b75b93e69c09..82741dcb2a45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c @@ -528,7 +528,7 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, #endif static int -amdgpu_userqueue_resume_all(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userqueue_restore_all(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_device *adev = uq_mgr->adev; struct amdgpu_usermode_queue *queue; @@ -659,7 +659,7 @@ unlock_all: return ret; } -static void amdgpu_userqueue_resume_worker(struct work_struct *work) +static void amdgpu_userqueue_restore_worker(struct work_struct *work) { struct amdgpu_userq_mgr *uq_mgr = work_to_uq_mgr(work, resume_work.work); struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); @@ -675,9 +675,9 @@ static void amdgpu_userqueue_resume_worker(struct work_struct *work) goto unlock; } - ret = amdgpu_userqueue_resume_all(uq_mgr); + ret = amdgpu_userqueue_restore_all(uq_mgr); if (ret) { - DRM_ERROR("Failed to resume all queues\n"); + DRM_ERROR("Failed to restore all queues\n"); goto unlock; } @@ -686,7 +686,7 @@ unlock: } static int -amdgpu_userqueue_suspend_all(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userqueue_evict_all(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_device *adev = uq_mgr->adev; struct amdgpu_usermode_queue *queue; @@ -728,8 +728,8 @@ amdgpu_userqueue_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) } void -amdgpu_userqueue_suspend(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_eviction_fence *ev_fence) +amdgpu_userqueue_evict(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_eviction_fence *ev_fence) { int ret; struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); @@ -738,11 +738,11 @@ amdgpu_userqueue_suspend(struct amdgpu_userq_mgr *uq_mgr, /* Wait for any pending userqueue fence work to finish */ ret = amdgpu_userqueue_wait_for_signal(uq_mgr); if (ret) { - DRM_ERROR("Not suspending userqueue, timeout waiting for work\n"); + DRM_ERROR("Not evicting userqueue, timeout waiting for work\n"); return; } - ret = amdgpu_userqueue_suspend_all(uq_mgr); + ret = amdgpu_userqueue_evict_all(uq_mgr); if (ret) { DRM_ERROR("Failed to evict userqueue\n"); return; @@ -770,7 +770,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi list_add(&userq_mgr->list, &adev->userq_mgr_list); mutex_unlock(&adev->userq_mutex); - INIT_DELAYED_WORK(&userq_mgr->resume_work, amdgpu_userqueue_resume_worker); + INIT_DELAYED_WORK(&userq_mgr->resume_work, amdgpu_userqueue_restore_worker); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h index 8f392a0947a2..a9f0e46bcec0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h @@ -108,8 +108,8 @@ int amdgpu_userqueue_create_object(struct amdgpu_userq_mgr *uq_mgr, void amdgpu_userqueue_destroy_object(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_userq_obj *userq_obj); -void amdgpu_userqueue_suspend(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_eviction_fence *ev_fence); +void amdgpu_userqueue_evict(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_eviction_fence *ev_fence); int amdgpu_userqueue_active(struct amdgpu_userq_mgr *uq_mgr); -- 2.51.0 From 42a66677805d03df9e2600fab82d0cbe855500e1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 16 Apr 2025 17:49:45 -0400 Subject: [PATCH 02/16] drm/amdgpu/userq: use consistent function naming s/userqueue/userq/ 1. remove the mix of amdgpu_userqueue and amdgpu_userq 2. to be consistent with other amdgpu_userq_fence.c 3. it's shorter Reviewed-by: Prike Liang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- .../drm/amd/amdgpu/amdgpu_eviction_fence.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 +- .../{amdgpu_userqueue.c => amdgpu_userq.c} | 122 +++++++++--------- .../{amdgpu_userqueue.h => amdgpu_userq.h} | 34 ++--- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 4 +- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.h | 2 +- drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 12 +- drivers/gpu/drm/amd/amdgpu/mes_userqueue.h | 2 +- 11 files changed, 94 insertions(+), 94 deletions(-) rename drivers/gpu/drm/amd/amdgpu/{amdgpu_userqueue.c => amdgpu_userq.c} (86%) rename drivers/gpu/drm/amd/amdgpu/{amdgpu_userqueue.h => amdgpu_userq.h} (80%) diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 513c4d64f554..8595e05c691b 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -257,7 +257,7 @@ amdgpu-y += \ amdgpu-y += amdgpu_amdkfd.o # add gfx usermode queue -amdgpu-y += amdgpu_userqueue.o +amdgpu-y += amdgpu_userq.o ifneq ($(CONFIG_HSA_AMD),) AMDKFD_PATH := ../amdkfd diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index decf66c2a718..cc26cf1bd843 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -113,7 +113,7 @@ #include "amdgpu_xcp.h" #include "amdgpu_seq64.h" #include "amdgpu_reg_state.h" -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" #include "amdgpu_eviction_fence.h" #if defined(CONFIG_DRM_AMD_ISP) #include "amdgpu_isp.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index e24b0c730baf..b9a1ef343c79 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -51,7 +51,7 @@ #include "amdgpu_reset.h" #include "amdgpu_sched.h" #include "amdgpu_xgmi.h" -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" #include "amdgpu_userq_fence.h" #include "../amdxcp/amdgpu_xcp_drv.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c index 02164bca51a7..faa3f59b20c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c @@ -112,7 +112,7 @@ amdgpu_eviction_fence_suspend_worker(struct work_struct *work) if (!ev_fence) goto unlock; - amdgpu_userqueue_evict(uq_mgr, ev_fence); + amdgpu_userq_evict(uq_mgr, ev_fence); unlock: mutex_unlock(&uq_mgr->userq_mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 151366ecc0af..8f992314c5a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -45,7 +45,7 @@ #include "amdgpu_ras.h" #include "amdgpu_reset.h" #include "amd_pcie.h" -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev) { @@ -1009,7 +1009,7 @@ out: } } - dev_info->userq_ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev); + dev_info->userq_ip_mask = amdgpu_userq_get_supported_ip_mask(adev); ret = copy_to_user(out, dev_info, min((size_t)size, sizeof(*dev_info))) ? -EFAULT : 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c similarity index 86% rename from drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c rename to drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 82741dcb2a45..4be72bebcf34 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -28,10 +28,10 @@ #include "amdgpu.h" #include "amdgpu_vm.h" -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" #include "amdgpu_userq_fence.h" -u32 amdgpu_userqueue_get_supported_ip_mask(struct amdgpu_device *adev) +u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) { int i; u32 userq_ip_mask = 0; @@ -45,8 +45,8 @@ u32 amdgpu_userqueue_get_supported_ip_mask(struct amdgpu_device *adev) } static int -amdgpu_userqueue_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_usermode_queue *queue) +amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) { struct amdgpu_device *adev = uq_mgr->adev; const struct amdgpu_userq_funcs *userq_funcs = @@ -64,8 +64,8 @@ amdgpu_userqueue_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, } static int -amdgpu_userqueue_map_helper(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_usermode_queue *queue) +amdgpu_userq_map_helper(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) { struct amdgpu_device *adev = uq_mgr->adev; const struct amdgpu_userq_funcs *userq_funcs = @@ -84,8 +84,8 @@ amdgpu_userqueue_map_helper(struct amdgpu_userq_mgr *uq_mgr, } static void -amdgpu_userqueue_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_usermode_queue *queue) +amdgpu_userq_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) { struct amdgpu_device *adev = uq_mgr->adev; struct dma_fence *f = queue->last_fence; @@ -99,9 +99,9 @@ amdgpu_userqueue_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr, } static void -amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_usermode_queue *queue, - int queue_id) +amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue, + int queue_id) { struct amdgpu_device *adev = uq_mgr->adev; const struct amdgpu_userq_funcs *uq_funcs = adev->userq_funcs[queue->queue_type]; @@ -113,7 +113,7 @@ amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr, } int -amdgpu_userqueue_active(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userq_active(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_usermode_queue *queue; int queue_id; @@ -130,14 +130,14 @@ amdgpu_userqueue_active(struct amdgpu_userq_mgr *uq_mgr) #ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ static struct amdgpu_usermode_queue * -amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid) +amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid) { return idr_find(&uq_mgr->userq_idr, qid); } void -amdgpu_userqueue_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_eviction_fence_mgr *evf_mgr) +amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_eviction_fence_mgr *evf_mgr) { struct amdgpu_eviction_fence *ev_fence; @@ -160,9 +160,9 @@ retry: } } -int amdgpu_userqueue_create_object(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_userq_obj *userq_obj, - int size) +int amdgpu_userq_create_object(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_userq_obj *userq_obj, + int size) { struct amdgpu_device *adev = uq_mgr->adev; struct amdgpu_bo_param bp; @@ -215,17 +215,17 @@ free_obj: return r; } -void amdgpu_userqueue_destroy_object(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_userq_obj *userq_obj) +void amdgpu_userq_destroy_object(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_userq_obj *userq_obj) { amdgpu_bo_kunmap(userq_obj->obj); amdgpu_bo_unref(&userq_obj->obj); } uint64_t -amdgpu_userqueue_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_db_info *db_info, - struct drm_file *filp) +amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_db_info *db_info, + struct drm_file *filp) { uint64_t index; struct drm_gem_object *gobj; @@ -292,7 +292,7 @@ unref_bo: } static int -amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id) +amdgpu_userq_destroy(struct drm_file *filp, int queue_id) { struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr; @@ -303,17 +303,17 @@ amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id) cancel_delayed_work(&uq_mgr->resume_work); mutex_lock(&uq_mgr->userq_mutex); - queue = amdgpu_userqueue_find(uq_mgr, queue_id); + queue = amdgpu_userq_find(uq_mgr, queue_id); if (!queue) { DRM_DEBUG_DRIVER("Invalid queue id to destroy\n"); mutex_unlock(&uq_mgr->userq_mutex); return -EINVAL; } - amdgpu_userqueue_wait_for_last_fence(uq_mgr, queue); - r = amdgpu_userqueue_unmap_helper(uq_mgr, queue); + amdgpu_userq_wait_for_last_fence(uq_mgr, queue); + r = amdgpu_userq_unmap_helper(uq_mgr, queue); amdgpu_bo_unpin(queue->db_obj.obj); amdgpu_bo_unref(&queue->db_obj.obj); - amdgpu_userqueue_cleanup(uq_mgr, queue, queue_id); + amdgpu_userq_cleanup(uq_mgr, queue, queue_id); mutex_unlock(&uq_mgr->userq_mutex); pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); @@ -338,7 +338,7 @@ static int amdgpu_userq_priority_permit(struct drm_file *filp, } static int -amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args) +amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) { struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr; @@ -387,7 +387,7 @@ amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args) * * This will also make sure we have a valid eviction fence ready to be used. */ - amdgpu_userqueue_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); + amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); uq_funcs = adev->userq_funcs[args->in.ip_type]; if (!uq_funcs) { @@ -413,7 +413,7 @@ amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args) db_info.doorbell_offset = args->in.doorbell_offset; /* Convert relative doorbell offset into absolute doorbell index */ - index = amdgpu_userqueue_get_doorbell_index(uq_mgr, &db_info, filp); + index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp); if (index == (uint64_t)-EINVAL) { DRM_ERROR("Failed to get doorbell for queue\n"); kfree(queue); @@ -456,7 +456,7 @@ amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args) else skip_map_queue = false; if (!skip_map_queue) { - r = amdgpu_userqueue_map_helper(uq_mgr, queue); + r = amdgpu_userq_map_helper(uq_mgr, queue); if (r) { mutex_unlock(&adev->userq_mutex); DRM_ERROR("Failed to map Queue\n"); @@ -489,7 +489,7 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, if (args->in.flags & ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK | AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE)) return -EINVAL; - r = amdgpu_userqueue_create(filp, args); + r = amdgpu_userq_create(filp, args); if (r) DRM_ERROR("Failed to create usermode queue\n"); break; @@ -507,7 +507,7 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, args->in.mqd || args->in.mqd_size) return -EINVAL; - r = amdgpu_userqueue_destroy(filp, args->in.queue_id); + r = amdgpu_userq_destroy(filp, args->in.queue_id); if (r) DRM_ERROR("Failed to destroy usermode queue\n"); break; @@ -528,7 +528,7 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, #endif static int -amdgpu_userqueue_restore_all(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_device *adev = uq_mgr->adev; struct amdgpu_usermode_queue *queue; @@ -537,7 +537,7 @@ amdgpu_userqueue_restore_all(struct amdgpu_userq_mgr *uq_mgr) /* Resume all the queues for this process */ idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) { - r = amdgpu_userqueue_map_helper(uq_mgr, queue); + r = amdgpu_userq_map_helper(uq_mgr, queue); if (r) ret = r; } @@ -548,7 +548,7 @@ amdgpu_userqueue_restore_all(struct amdgpu_userq_mgr *uq_mgr) } static int -amdgpu_userqueue_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) +amdgpu_userq_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) { struct ttm_operation_ctx ctx = { false, false }; int ret; @@ -563,7 +563,7 @@ amdgpu_userqueue_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) } static int -amdgpu_userqueue_validate_bos(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userq_validate_bos(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); struct amdgpu_vm *vm = &fpriv->vm; @@ -619,7 +619,7 @@ amdgpu_userqueue_validate_bos(struct amdgpu_userq_mgr *uq_mgr) spin_unlock(&vm->status_lock); bo = bo_va->base.bo; - ret = amdgpu_userqueue_validate_vm_bo(NULL, bo); + ret = amdgpu_userq_validate_vm_bo(NULL, bo); if (ret) { DRM_ERROR("Failed to validate BO\n"); goto unlock_all; @@ -659,7 +659,7 @@ unlock_all: return ret; } -static void amdgpu_userqueue_restore_worker(struct work_struct *work) +static void amdgpu_userq_restore_worker(struct work_struct *work) { struct amdgpu_userq_mgr *uq_mgr = work_to_uq_mgr(work, resume_work.work); struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); @@ -669,13 +669,13 @@ static void amdgpu_userqueue_restore_worker(struct work_struct *work) mutex_lock(&uq_mgr->userq_mutex); - ret = amdgpu_userqueue_validate_bos(uq_mgr); + ret = amdgpu_userq_validate_bos(uq_mgr); if (ret) { DRM_ERROR("Failed to validate BOs to restore\n"); goto unlock; } - ret = amdgpu_userqueue_restore_all(uq_mgr); + ret = amdgpu_userq_restore_all(uq_mgr); if (ret) { DRM_ERROR("Failed to restore all queues\n"); goto unlock; @@ -686,7 +686,7 @@ unlock: } static int -amdgpu_userqueue_evict_all(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_device *adev = uq_mgr->adev; struct amdgpu_usermode_queue *queue; @@ -695,7 +695,7 @@ amdgpu_userqueue_evict_all(struct amdgpu_userq_mgr *uq_mgr) /* Try to unmap all the queues in this process ctx */ idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) { - r = amdgpu_userqueue_unmap_helper(uq_mgr, queue); + r = amdgpu_userq_unmap_helper(uq_mgr, queue); if (r) ret = r; } @@ -706,7 +706,7 @@ amdgpu_userqueue_evict_all(struct amdgpu_userq_mgr *uq_mgr) } static int -amdgpu_userqueue_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) +amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) { struct amdgpu_usermode_queue *queue; int queue_id, ret; @@ -728,21 +728,21 @@ amdgpu_userqueue_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) } void -amdgpu_userqueue_evict(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_eviction_fence *ev_fence) +amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_eviction_fence *ev_fence) { int ret; struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); struct amdgpu_eviction_fence_mgr *evf_mgr = &fpriv->evf_mgr; /* Wait for any pending userqueue fence work to finish */ - ret = amdgpu_userqueue_wait_for_signal(uq_mgr); + ret = amdgpu_userq_wait_for_signal(uq_mgr); if (ret) { DRM_ERROR("Not evicting userqueue, timeout waiting for work\n"); return; } - ret = amdgpu_userqueue_evict_all(uq_mgr); + ret = amdgpu_userq_evict_all(uq_mgr); if (ret) { DRM_ERROR("Failed to evict userqueue\n"); return; @@ -770,7 +770,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi list_add(&userq_mgr->list, &adev->userq_mgr_list); mutex_unlock(&adev->userq_mutex); - INIT_DELAYED_WORK(&userq_mgr->resume_work, amdgpu_userqueue_restore_worker); + INIT_DELAYED_WORK(&userq_mgr->resume_work, amdgpu_userq_restore_worker); return 0; } @@ -785,9 +785,9 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr) mutex_lock(&userq_mgr->userq_mutex); idr_for_each_entry(&userq_mgr->userq_idr, queue, queue_id) { - amdgpu_userqueue_wait_for_last_fence(userq_mgr, queue); - amdgpu_userqueue_unmap_helper(userq_mgr, queue); - amdgpu_userqueue_cleanup(userq_mgr, queue, queue_id); + amdgpu_userq_wait_for_last_fence(userq_mgr, queue); + amdgpu_userq_unmap_helper(userq_mgr, queue); + amdgpu_userq_cleanup(userq_mgr, queue, queue_id); } mutex_lock(&adev->userq_mutex); list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) { @@ -804,7 +804,7 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr) int amdgpu_userq_suspend(struct amdgpu_device *adev) { - u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev); + u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev); struct amdgpu_usermode_queue *queue; struct amdgpu_userq_mgr *uqm, *tmp; int queue_id; @@ -817,7 +817,7 @@ int amdgpu_userq_suspend(struct amdgpu_device *adev) list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) { cancel_delayed_work_sync(&uqm->resume_work); idr_for_each_entry(&uqm->userq_idr, queue, queue_id) { - r = amdgpu_userqueue_unmap_helper(uqm, queue); + r = amdgpu_userq_unmap_helper(uqm, queue); if (r) ret = r; } @@ -828,7 +828,7 @@ int amdgpu_userq_suspend(struct amdgpu_device *adev) int amdgpu_userq_resume(struct amdgpu_device *adev) { - u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev); + u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev); struct amdgpu_usermode_queue *queue; struct amdgpu_userq_mgr *uqm, *tmp; int queue_id; @@ -840,7 +840,7 @@ int amdgpu_userq_resume(struct amdgpu_device *adev) mutex_lock(&adev->userq_mutex); list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) { idr_for_each_entry(&uqm->userq_idr, queue, queue_id) { - r = amdgpu_userqueue_map_helper(uqm, queue); + r = amdgpu_userq_map_helper(uqm, queue); if (r) ret = r; } @@ -852,7 +852,7 @@ int amdgpu_userq_resume(struct amdgpu_device *adev) int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev, u32 idx) { - u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev); + u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev); struct amdgpu_usermode_queue *queue; struct amdgpu_userq_mgr *uqm, *tmp; int queue_id; @@ -872,7 +872,7 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev, if (((queue->queue_type == AMDGPU_HW_IP_GFX) || (queue->queue_type == AMDGPU_HW_IP_COMPUTE)) && (queue->xcp_id == idx)) { - r = amdgpu_userqueue_unmap_helper(uqm, queue); + r = amdgpu_userq_unmap_helper(uqm, queue); if (r) ret = r; } @@ -885,7 +885,7 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev, int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, u32 idx) { - u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev); + u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev); struct amdgpu_usermode_queue *queue; struct amdgpu_userq_mgr *uqm, *tmp; int queue_id; @@ -904,7 +904,7 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, if (((queue->queue_type == AMDGPU_HW_IP_GFX) || (queue->queue_type == AMDGPU_HW_IP_COMPUTE)) && (queue->xcp_id == idx)) { - r = amdgpu_userqueue_map_helper(uqm, queue); + r = amdgpu_userq_map_helper(uqm, queue); if (r) ret = r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h similarity index 80% rename from drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h rename to drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h index a9f0e46bcec0..4d3eb651acf1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h @@ -22,8 +22,8 @@ * */ -#ifndef AMDGPU_USERQUEUE_H_ -#define AMDGPU_USERQUEUE_H_ +#ifndef AMDGPU_USERQ_H_ +#define AMDGPU_USERQ_H_ #include "amdgpu_eviction_fence.h" #define AMDGPU_MAX_USERQ_COUNT 512 @@ -32,7 +32,7 @@ #define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr) #define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr, name) -enum amdgpu_userqueue_state { +enum amdgpu_userq_state { AMDGPU_USERQ_STATE_UNMAPPED = 0, AMDGPU_USERQ_STATE_MAPPED, AMDGPU_USERQ_STATE_PREEMPTED, @@ -49,7 +49,7 @@ struct amdgpu_userq_obj { struct amdgpu_usermode_queue { int queue_type; - enum amdgpu_userqueue_state state; + enum amdgpu_userq_state state; uint64_t doorbell_handle; uint64_t doorbell_index; uint64_t flags; @@ -101,26 +101,26 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr); -int amdgpu_userqueue_create_object(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_userq_obj *userq_obj, - int size); +int amdgpu_userq_create_object(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_userq_obj *userq_obj, + int size); -void amdgpu_userqueue_destroy_object(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_userq_obj *userq_obj); +void amdgpu_userq_destroy_object(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_userq_obj *userq_obj); -void amdgpu_userqueue_evict(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_eviction_fence *ev_fence); +void amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_eviction_fence *ev_fence); -int amdgpu_userqueue_active(struct amdgpu_userq_mgr *uq_mgr); +int amdgpu_userq_active(struct amdgpu_userq_mgr *uq_mgr); -void amdgpu_userqueue_ensure_ev_fence(struct amdgpu_userq_mgr *userq_mgr, - struct amdgpu_eviction_fence_mgr *evf_mgr); +void amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *userq_mgr, + struct amdgpu_eviction_fence_mgr *evf_mgr); -uint64_t amdgpu_userqueue_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, - struct amdgpu_db_info *db_info, +uint64_t amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_db_info *db_info, struct drm_file *filp); -u32 amdgpu_userqueue_get_supported_ip_mask(struct amdgpu_device *adev); +u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev); int amdgpu_userq_suspend(struct amdgpu_device *adev); int amdgpu_userq_resume(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index ca198360cfda..be068e8e37d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -292,7 +292,7 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq, static const char *amdgpu_userq_fence_get_driver_name(struct dma_fence *f) { - return "amdgpu_userqueue_fence"; + return "amdgpu_userq_fence"; } static const char *amdgpu_userq_fence_get_timeline_name(struct dma_fence *f) @@ -513,7 +513,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, goto put_gobj_write; /* We are here means UQ is active, make sure the eviction fence is valid */ - amdgpu_userqueue_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); + amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); /* Create a new fence */ r = amdgpu_userq_fence_create(queue, userq_fence, wptr, &fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h index 2af4e0c15773..97a125ab8a78 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h @@ -27,7 +27,7 @@ #include -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" struct amdgpu_userq_fence { struct dma_fence base; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index 4c01c3a03095..d6f50b13e2ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -189,7 +189,7 @@ static int mes_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr, * for the same. */ size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_GANG_CTX_SZ; - r = amdgpu_userqueue_create_object(uq_mgr, ctx, size); + r = amdgpu_userq_create_object(uq_mgr, ctx, size); if (r) { DRM_ERROR("Failed to allocate ctx space bo for userqueue, err:%d\n", r); return r; @@ -222,7 +222,7 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, goto free_props; } - r = amdgpu_userqueue_create_object(uq_mgr, &queue->mqd, mqd_hw_default->mqd_size); + r = amdgpu_userq_create_object(uq_mgr, &queue->mqd, mqd_hw_default->mqd_size); if (r) { DRM_ERROR("Failed to create MQD object for userqueue\n"); goto free_props; @@ -327,10 +327,10 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, return 0; free_ctx: - amdgpu_userqueue_destroy_object(uq_mgr, &queue->fw_obj); + amdgpu_userq_destroy_object(uq_mgr, &queue->fw_obj); free_mqd: - amdgpu_userqueue_destroy_object(uq_mgr, &queue->mqd); + amdgpu_userq_destroy_object(uq_mgr, &queue->mqd); free_props: kfree(userq_props); @@ -342,9 +342,9 @@ static void mes_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) { - amdgpu_userqueue_destroy_object(uq_mgr, &queue->fw_obj); + amdgpu_userq_destroy_object(uq_mgr, &queue->fw_obj); kfree(queue->userq_prop); - amdgpu_userqueue_destroy_object(uq_mgr, &queue->mqd); + amdgpu_userq_destroy_object(uq_mgr, &queue->mqd); } const struct amdgpu_userq_funcs userq_mes_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.h b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.h index d0a521312ad4..090ae8897770 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.h +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.h @@ -24,7 +24,7 @@ #ifndef MES_USERQ_H #define MES_USERQ_H -#include "amdgpu_userqueue.h" +#include "amdgpu_userq.h" extern const struct amdgpu_userq_funcs userq_mes_funcs; #endif -- 2.51.0 From 3f397cd203f247879c2f1a061e90d4c8d23655de Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Fri, 18 Apr 2025 00:57:19 +0530 Subject: [PATCH 03/16] drm/amd/display: Add NULL pointer checks in dm_force_atomic_commit() This commit updates the dm_force_atomic_commit function to replace the usage of PTR_ERR_OR_ZERO with IS_ERR for checking error states after retrieving the Connector (drm_atomic_get_connector_state), CRTC (drm_atomic_get_crtc_state), and Plane (drm_atomic_get_plane_state) states. The function utilized PTR_ERR_OR_ZERO for error checking. However, this approach is inappropriate in this context because the respective functions do not return NULL; they return pointers that encode errors. This change ensures that error pointers are properly checked using IS_ERR before attempting to dereference. Cc: Harry Wentland Cc: Nicholas Kazlauskas Cc: Tom Chung Cc: Roman Li Cc: Alex Hung Cc: Aurabindo Pillai Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 31a5b8fc4dc4..e7da058b4aaf 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10602,16 +10602,20 @@ static int dm_force_atomic_commit(struct drm_connector *connector) */ conn_state = drm_atomic_get_connector_state(state, connector); - ret = PTR_ERR_OR_ZERO(conn_state); - if (ret) + /* Check for error in getting connector state */ + if (IS_ERR(conn_state)) { + ret = PTR_ERR(conn_state); goto out; + } /* Attach crtc to drm_atomic_state*/ crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base); - ret = PTR_ERR_OR_ZERO(crtc_state); - if (ret) + /* Check for error in getting crtc state */ + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); goto out; + } /* force a restore */ crtc_state->mode_changed = true; @@ -10619,9 +10623,11 @@ static int dm_force_atomic_commit(struct drm_connector *connector) /* Attach plane to drm_atomic_state */ plane_state = drm_atomic_get_plane_state(state, plane); - ret = PTR_ERR_OR_ZERO(plane_state); - if (ret) + /* Check for error in getting plane state */ + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); goto out; + } /* Call commit internally with the state we just constructed */ ret = drm_atomic_commit(state); -- 2.51.0 From 61ca97e9590ceac8c96a40b8526332c1c36409dc Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 9 Apr 2025 15:41:59 +0530 Subject: [PATCH 04/16] drm/amdgpu/gfx11: Add fw minimum version check for usermode queue This patch is load usermode queue based on FW support for gfx11. CP Ucode FW version: [PFP = 2530, ME = 2390, MEC = 2600, MES = 120] v2: Addressed review comments from Alex. - Just check the firmware versions directly. v3: Firmware version checks only for Navi3x(by Alex). Cc: Alex Deucher Cc: Christian Koenig Cc: Shashank Sharma Cc: Sunil Khatri Acked-by: Alex Deucher Reviewed-by: Sunil Khatri Signed-off-by: Arvind Yadav Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 496e83cb8917..ac7ac58e25a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1631,8 +1631,11 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block) case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 3): #ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ - /* add firmware version checks here */ - if (0 && !adev->gfx.disable_uq) { + if (!adev->gfx.disable_uq && + adev->gfx.me_fw_version >= 2390 && + adev->gfx.pfp_fw_version >= 2530 && + adev->gfx.mec_fw_version >= 2600 && + adev->mes.fw_version[0] >= 120) { adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs; adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs; } -- 2.51.0 From cade59abaa0586100a95c72725d9bde0fadc3845 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 9 Apr 2025 15:45:34 +0530 Subject: [PATCH 05/16] drm/amdgpu/gfx12: Add fw minimum version check for usermode queue This patch is load usermode queue based on FW support for gfx12. CP Ucode FW Vesion: [PFP = 2840, ME = 2780, MEC = 3050, MES = 123] v2: Addressed review comments from Alex - Just check the firmware versions directly. Cc: Alex Deucher Cc: Christian Koenig Cc: Shashank Sharma Cc: Sunil Khatri Acked-by: Alex Deucher Reviewed-by: Sunil Khatri Signed-off-by: Arvind Yadav Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index 9cfe50016dab..dfa0830a4eb1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -1417,8 +1417,11 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block) case IP_VERSION(12, 0, 0): case IP_VERSION(12, 0, 1): #ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ - /* add firmware version checks here */ - if (0 && !adev->gfx.disable_uq) { + if (!adev->gfx.disable_uq && + adev->gfx.me_fw_version >= 2780 && + adev->gfx.pfp_fw_version >= 2840 && + adev->gfx.mec_fw_version >= 3050 && + adev->mes.fw_version[0] >= 123) { adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs; adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs; } -- 2.51.0 From 127e612bf16726620e431b6e0f771424916492be Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Mon, 21 Apr 2025 17:45:49 +0530 Subject: [PATCH 06/16] drm/amdgpu: update fence ptr with context:seqno log context:seqno of the fence during timeout rather than logging fence pointer. Reviewed-by: Arvind Yadav Cc: Tvrtko Ursulin Signed-off-by: Sunil Khatri Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 4be72bebcf34..b0e8098a3988 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -94,7 +94,8 @@ amdgpu_userq_wait_for_last_fence(struct amdgpu_userq_mgr *uq_mgr, if (f && !dma_fence_is_signaled(f)) { ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100)); if (ret <= 0) - dev_err(adev->dev, "Timed out waiting for fence f=%p\n", f); + dev_err(adev->dev, "Timed out waiting for fence=%llu:%llu\n", + f->context, f->seqno); } } -- 2.51.0 From af0819755c8cf746930627b7f88b34566240815a Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Mon, 21 Apr 2025 08:38:33 +0530 Subject: [PATCH 07/16] drm/amd/display: Fix NULL pointer dereferences in dm_update_crtc_state() v2 Added checks for NULL values after retrieving drm_new_conn_state to prevent dereferencing NULL pointers. Fixes the below: drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:10751 dm_update_crtc_state() warn: 'drm_new_conn_state' can also be NULL drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c 10672 static int dm_update_crtc_state(struct amdgpu_display_manager *dm, 10673 struct drm_atomic_state *state, 10674 struct drm_crtc *crtc, 10675 struct drm_crtc_state *old_crtc_state, 10676 struct drm_crtc_state *new_crtc_state, 10677 bool enable, 10678 bool *lock_and_validation_needed) 10679 { 10680 struct dm_atomic_state *dm_state = NULL; 10681 struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; 10682 struct dc_stream_state *new_stream; 10683 int ret = 0; 10684 ... 10703 10704 /* TODO This hack should go away */ 10705 if (connector && enable) { 10706 /* Make sure fake sink is created in plug-in scenario */ 10707 drm_new_conn_state = drm_atomic_get_new_connector_state(state, 10708 connector); drm_atomic_get_new_connector_state() can't return error pointers, only NULL. 10709 drm_old_conn_state = drm_atomic_get_old_connector_state(state, 10710 connector); 10711 10712 if (IS_ERR(drm_new_conn_state)) { ^^^^^^^^^^^^^^^^^^ 10713 ret = PTR_ERR_OR_ZERO(drm_new_conn_state); Calling PTR_ERR_OR_ZERO() doesn't make sense. It can't be success. 10714 goto fail; 10715 } 10716 ... 10748 10749 dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level; 10750 --> 10751 ret = fill_hdr_info_packet(drm_new_conn_state, ^^^^^^^^^^^^^^^^^^ Unchecked dereference 10752 &new_stream->hdr_static_metadata); 10753 if (ret) 10754 goto fail; 10755 v2: Modified the NULL pointer check for drm_new_conn_state in the dm_update_crtc_state function to include a warning via WARN_ON and return -EINVAL to indicate an invalid state when the pointer is NULL. Cc: Harry Wentland Cc: Nicholas Kazlauskas Cc: Tom Chung Cc: Rodrigo Siqueira Cc: Roman Li Cc: Alex Hung Cc: Aurabindo Pillai Reported-by: Dan Carpenter Signed-off-by: Srinivasan Shanmugam Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e7da058b4aaf..89a43f33e8a1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10864,8 +10864,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, drm_old_conn_state = drm_atomic_get_old_connector_state(state, connector); - if (IS_ERR(drm_new_conn_state)) { - ret = PTR_ERR_OR_ZERO(drm_new_conn_state); + if (WARN_ON(!drm_new_conn_state)) { + ret = -EINVAL; goto fail; } -- 2.51.0 From 75f138db48c5c493f0ac198c2579d52fc6a4c4a0 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Wed, 16 Apr 2025 12:23:44 +0530 Subject: [PATCH 08/16] drm/amdgpu: Disallow partition query during reset Reject queries to get current partition modes during reset. Also, don't accept sysfs interface requests to switch compute partition mode while in reset. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Reviewed-by: Asad Kamal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 10 ++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index e1dca45a152b..cb9ffb17ab98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1353,6 +1353,10 @@ static ssize_t amdgpu_gfx_get_current_compute_partition(struct device *dev, struct amdgpu_device *adev = drm_to_adev(ddev); int mode; + /* Only minimal precaution taken to reject requests while in reset.*/ + if (amdgpu_in_reset(adev)) + return -EPERM; + mode = amdgpu_xcp_query_partition_mode(adev->xcp_mgr, AMDGPU_XCP_FL_NONE); @@ -1396,8 +1400,14 @@ static ssize_t amdgpu_gfx_set_compute_partition(struct device *dev, return -EINVAL; } + /* Don't allow a switch while under reset */ + if (!down_read_trylock(&adev->reset_domain->sem)) + return -EPERM; + ret = amdgpu_xcp_switch_partition_mode(adev->xcp_mgr, mode); + up_read(&adev->reset_domain->sem); + if (ret) return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index ecb74ccf1d90..6b0fbbb91e57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -1230,6 +1230,10 @@ static ssize_t current_memory_partition_show( struct amdgpu_device *adev = drm_to_adev(ddev); enum amdgpu_memory_partition mode; + /* Only minimal precaution taken to reject requests while in reset */ + if (amdgpu_in_reset(adev)) + return -EPERM; + mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); if ((mode >= ARRAY_SIZE(nps_desc)) || (BIT(mode) & AMDGPU_ALL_NPS_MASK) != BIT(mode)) -- 2.51.0 From d4673f3c3b3dcb74e36e53cdfc880baa7a87b330 Mon Sep 17 00:00:00 2001 From: Chris Bainbridge Date: Thu, 17 Apr 2025 16:50:05 -0500 Subject: [PATCH 09/16] drm/amd/display: Fix slab-use-after-free in hdcp The HDCP code in amdgpu_dm_hdcp.c copies pointers to amdgpu_dm_connector objects without incrementing the kref reference counts. When using a USB-C dock, and the dock is unplugged, the corresponding amdgpu_dm_connector objects are freed, creating dangling pointers in the HDCP code. When the dock is plugged back, the dangling pointers are dereferenced, resulting in a slab-use-after-free: [ 66.775837] BUG: KASAN: slab-use-after-free in event_property_validate+0x42f/0x6c0 [amdgpu] [ 66.776171] Read of size 4 at addr ffff888127804120 by task kworker/0:1/10 [ 66.776179] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Not tainted 6.14.0-rc7-00180-g54505f727a38-dirty #233 [ 66.776183] Hardware name: HP HP Pavilion Aero Laptop 13-be0xxx/8916, BIOS F.17 12/18/2024 [ 66.776186] Workqueue: events event_property_validate [amdgpu] [ 66.776494] Call Trace: [ 66.776496] [ 66.776497] dump_stack_lvl+0x70/0xa0 [ 66.776504] print_report+0x175/0x555 [ 66.776507] ? __virt_addr_valid+0x243/0x450 [ 66.776510] ? kasan_complete_mode_report_info+0x66/0x1c0 [ 66.776515] kasan_report+0xeb/0x1c0 [ 66.776518] ? event_property_validate+0x42f/0x6c0 [amdgpu] [ 66.776819] ? event_property_validate+0x42f/0x6c0 [amdgpu] [ 66.777121] __asan_report_load4_noabort+0x14/0x20 [ 66.777124] event_property_validate+0x42f/0x6c0 [amdgpu] [ 66.777342] ? __lock_acquire+0x6b40/0x6b40 [ 66.777347] ? enable_assr+0x250/0x250 [amdgpu] [ 66.777571] process_one_work+0x86b/0x1510 [ 66.777575] ? pwq_dec_nr_in_flight+0xcf0/0xcf0 [ 66.777578] ? assign_work+0x16b/0x280 [ 66.777580] ? lock_is_held_type+0xa3/0x130 [ 66.777583] worker_thread+0x5c0/0xfa0 [ 66.777587] ? process_one_work+0x1510/0x1510 [ 66.777588] kthread+0x3a2/0x840 [ 66.777591] ? kthread_is_per_cpu+0xd0/0xd0 [ 66.777594] ? trace_hardirqs_on+0x4f/0x60 [ 66.777597] ? _raw_spin_unlock_irq+0x27/0x60 [ 66.777599] ? calculate_sigpending+0x77/0xa0 [ 66.777602] ? kthread_is_per_cpu+0xd0/0xd0 [ 66.777605] ret_from_fork+0x40/0x90 [ 66.777607] ? kthread_is_per_cpu+0xd0/0xd0 [ 66.777609] ret_from_fork_asm+0x11/0x20 [ 66.777614] [ 66.777643] Allocated by task 10: [ 66.777646] kasan_save_stack+0x39/0x60 [ 66.777649] kasan_save_track+0x14/0x40 [ 66.777652] kasan_save_alloc_info+0x37/0x50 [ 66.777655] __kasan_kmalloc+0xbb/0xc0 [ 66.777658] __kmalloc_cache_noprof+0x1c8/0x4b0 [ 66.777661] dm_dp_add_mst_connector+0xdd/0x5c0 [amdgpu] [ 66.777880] drm_dp_mst_port_add_connector+0x47e/0x770 [drm_display_helper] [ 66.777892] drm_dp_send_link_address+0x1554/0x2bf0 [drm_display_helper] [ 66.777901] drm_dp_check_and_send_link_address+0x187/0x1f0 [drm_display_helper] [ 66.777909] drm_dp_mst_link_probe_work+0x2b8/0x410 [drm_display_helper] [ 66.777917] process_one_work+0x86b/0x1510 [ 66.777919] worker_thread+0x5c0/0xfa0 [ 66.777922] kthread+0x3a2/0x840 [ 66.777925] ret_from_fork+0x40/0x90 [ 66.777927] ret_from_fork_asm+0x11/0x20 [ 66.777932] Freed by task 1713: [ 66.777935] kasan_save_stack+0x39/0x60 [ 66.777938] kasan_save_track+0x14/0x40 [ 66.777940] kasan_save_free_info+0x3b/0x60 [ 66.777944] __kasan_slab_free+0x52/0x70 [ 66.777946] kfree+0x13f/0x4b0 [ 66.777949] dm_dp_mst_connector_destroy+0xfa/0x150 [amdgpu] [ 66.778179] drm_connector_free+0x7d/0xb0 [ 66.778184] drm_mode_object_put.part.0+0xee/0x160 [ 66.778188] drm_mode_object_put+0x37/0x50 [ 66.778191] drm_atomic_state_default_clear+0x220/0xd60 [ 66.778194] __drm_atomic_state_free+0x16e/0x2a0 [ 66.778197] drm_mode_atomic_ioctl+0x15ed/0x2ba0 [ 66.778200] drm_ioctl_kernel+0x17a/0x310 [ 66.778203] drm_ioctl+0x584/0xd10 [ 66.778206] amdgpu_drm_ioctl+0xd2/0x1c0 [amdgpu] [ 66.778375] __x64_sys_ioctl+0x139/0x1a0 [ 66.778378] x64_sys_call+0xee7/0xfb0 [ 66.778381] do_syscall_64+0x87/0x140 [ 66.778385] entry_SYSCALL_64_after_hwframe+0x4b/0x53 Fix this by properly incrementing and decrementing the reference counts when making and deleting copies of the amdgpu_dm_connector pointers. (Mario: rebase on current code and update fixes tag) Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4006 Signed-off-by: Chris Bainbridge Fixes: da3fd7ac0bcf3 ("drm/amd/display: Update CP property based on HW query") Reviewed-by: Alex Hung Link: https://lore.kernel.org/r/20250417215005.37964-1-mario.limonciello@amd.com Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 2bd8dee1b7c2..26922d870b89 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -202,6 +202,9 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, unsigned int conn_index = aconnector->base.index; guard(mutex)(&hdcp_w->mutex); + drm_connector_get(&aconnector->base); + if (hdcp_w->aconnector[conn_index]) + drm_connector_put(&hdcp_w->aconnector[conn_index]->base); hdcp_w->aconnector[conn_index] = aconnector; memset(&link_adjust, 0, sizeof(link_adjust)); @@ -249,7 +252,6 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int conn_index = aconnector->base.index; guard(mutex)(&hdcp_w->mutex); - hdcp_w->aconnector[conn_index] = aconnector; /* the removal of display will invoke auth reset -> hdcp destroy and * we'd expect the Content Protection (CP) property changed back to @@ -265,7 +267,10 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, } mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output); - + if (hdcp_w->aconnector[conn_index]) { + drm_connector_put(&hdcp_w->aconnector[conn_index]->base); + hdcp_w->aconnector[conn_index] = NULL; + } process_output(hdcp_w); } @@ -283,6 +288,10 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { hdcp_w->encryption_status[conn_index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; + if (hdcp_w->aconnector[conn_index]) { + drm_connector_put(&hdcp_w->aconnector[conn_index]->base); + hdcp_w->aconnector[conn_index] = NULL; + } } process_output(hdcp_w); @@ -517,6 +526,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) struct hdcp_workqueue *hdcp_work = handle; struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx; int link_index = aconnector->dc_link->link_index; + unsigned int conn_index = aconnector->base.index; struct mod_hdcp_display *display = &hdcp_work[link_index].display; struct mod_hdcp_link *link = &hdcp_work[link_index].link; struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; @@ -573,7 +583,10 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) guard(mutex)(&hdcp_w->mutex); mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output); - + drm_connector_get(&aconnector->base); + if (hdcp_w->aconnector[conn_index]) + drm_connector_put(&hdcp_w->aconnector[conn_index]->base); + hdcp_w->aconnector[conn_index] = aconnector; process_output(hdcp_w); } -- 2.51.0 From e5f7e4e0a445f1b9b81ddc9b968e52b44f9d4242 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 21 Apr 2025 14:58:34 -0700 Subject: [PATCH 10/16] drm/amdgpu/atom: Work around vbios NULL offset false positive GCC really does not want to consider NULL (or near-NULL) addresses as valid, so calculations based off of NULL end up getting range-tracked into being an offset wthin a 0 byte array. It gets especially mad about this: if (vbios_str == NULL) vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1; ... if (vbios_str != NULL && *vbios_str == 0) vbios_str++; It sees this as being "sizeof(BIOS_ATOM_PREFIX) - 1" byte offset from NULL, when building with -Warray-bounds (and the coming -fdiagnostic-details flag): In function 'atom_get_vbios_pn', inlined from 'amdgpu_atom_parse' at drivers/gpu/drm/amd/amdgpu/atom.c:1553:2: drivers/gpu/drm/amd/amdgpu/atom.c:1447:34: error: array subscript 0 is outside array bounds of 'unsigned char[0]' [-Werror=array-bounds=] 1447 | if (vbios_str != NULL && *vbios_str == 0) | ^~~~~~~~~~ 'amdgpu_atom_parse': events 1-2 1444 | if (vbios_str == NULL) | ^ | | | (1) when the condition is evaluated to true ...... 1447 | if (vbios_str != NULL && *vbios_str == 0) | ~~~~~~~~~~ | | | (2) out of array bounds here In function 'amdgpu_atom_parse': cc1: note: source object is likely at address zero As there isn't a sane way to convince it otherwise, hide vbios_str from GCC's optimizer to avoid the warning so we can get closer to enabling -Warray-bounds globally. Acked-by: Alex Deucher Signed-off-by: Kees Cook Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/atom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 81d195d366ce..427b073de2fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1444,6 +1444,7 @@ static void atom_get_vbios_pn(struct atom_context *ctx) if (vbios_str == NULL) vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1; } + OPTIMIZER_HIDE_VAR(vbios_str); if (vbios_str != NULL && *vbios_str == 0) vbios_str++; -- 2.51.0 From 5a2658fda44f67003e7587547da6ac5decc97072 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 22 Apr 2025 11:26:26 +0100 Subject: [PATCH 11/16] drm/amdgpu: Fix spelling mistake "rounter" -> "router" There is a spelling mistake with the array utcl2_rounter_str, it appears it should be utcl2_router_str. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c index d81449f9d822..c48cd47b531f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c @@ -1547,7 +1547,7 @@ static void gfx_v9_4_2_log_utc_edc_count(struct amdgpu_device *adev, { uint32_t bank, way, mem; static const char * const vml2_way_str[] = { "BIGK", "4K" }; - static const char * const utcl2_rounter_str[] = { "VMC", "APT" }; + static const char * const utcl2_router_str[] = { "VMC", "APT" }; mem = instance % blk->num_mem_blocks; way = (instance / blk->num_mem_blocks) % blk->num_ways; @@ -1568,7 +1568,7 @@ static void gfx_v9_4_2_log_utc_edc_count(struct amdgpu_device *adev, dev_info( adev->dev, "GFX SubBlock UTCL2_ROUTER_IFIF%d_GROUP0_%s, SED %d, DED %d\n", - bank, utcl2_rounter_str[mem], sec_cnt, ded_cnt); + bank, utcl2_router_str[mem], sec_cnt, ded_cnt); break; case ATC_L2_CACHE_2M: dev_info( -- 2.51.0 From 9718f7457dba2e98dab256217814296b5ad47ee4 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 21 Apr 2025 16:12:18 -0600 Subject: [PATCH 12/16] drm/amdgpu/gfx: Introduce helpers handling CSB manipulation From GFX6 to GFX11, there is a function for getting the CSB buffer to be put into the hardware. Three common parts are duplicated in all of these GFX functions: 1. Prepare the CSB preamble. 2. Parser the CS data. 3. End the CSB preamble. This commit creates helpers to be used from GFX6 to GFX11. Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 69 +++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 3 ++ 2 files changed, 72 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index cb9ffb17ab98..e0cc2bb083cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -33,6 +33,7 @@ #include "amdgpu_reset.h" #include "amdgpu_xcp.h" #include "amdgpu_xgmi.h" +#include "nvd.h" /* delay 0.1 second to enable gfx off feature */ #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) @@ -2257,6 +2258,74 @@ void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring) schedule_delayed_work(&ring->adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT); } +/** + * amdgpu_gfx_csb_preamble_start - Set CSB preamble start + * + * @buffer: This is an output variable that gets the PACKET3 preamble setup. + * + * Return: + * return the latest index. + */ +u32 amdgpu_gfx_csb_preamble_start(volatile u32 *buffer) +{ + u32 count = 0; + + buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); + + buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); + buffer[count++] = cpu_to_le32(0x80000000); + buffer[count++] = cpu_to_le32(0x80000000); + + return count; +} + +/** + * amdgpu_gfx_csb_data_parser - Parser CS data + * + * @adev: amdgpu_device pointer used to get the CS data and other gfx info. + * @buffer: This is an output variable that gets the PACKET3 preamble end. + * @count: Index to start set the preemble end. + * + * Return: + * return the latest index. + */ +u32 amdgpu_gfx_csb_data_parser(struct amdgpu_device *adev, volatile u32 *buffer, u32 count) +{ + const struct cs_section_def *sect = NULL; + const struct cs_extent_def *ext = NULL; + u32 i; + + for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) { + for (ext = sect->section; ext->extent != NULL; ++ext) { + if (sect->id == SECT_CONTEXT) { + buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); + buffer[count++] = cpu_to_le32(ext->reg_index - PACKET3_SET_CONTEXT_REG_START); + + for (i = 0; i < ext->reg_count; i++) + buffer[count++] = cpu_to_le32(ext->extent[i]); + } + } + } + + return count; +} + +/** + * amdgpu_gfx_csb_preamble_end - Set CSB preamble end + * + * @buffer: This is an output variable that gets the PACKET3 preamble end. + * @count: Index to start set the preemble end. + */ +void amdgpu_gfx_csb_preamble_end(volatile u32 *buffer, u32 count) +{ + buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); + + buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); + buffer[count++] = cpu_to_le32(0); +} + /* * debugfs for to enable/disable gfx job submission to specific core. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index ed54095e6ad6..9187b0b3bff6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h @@ -599,6 +599,9 @@ void amdgpu_gfx_enforce_isolation_ring_end_use(struct amdgpu_ring *ring); void amdgpu_gfx_profile_idle_work_handler(struct work_struct *work); void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring); void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring); +u32 amdgpu_gfx_csb_preamble_start(volatile u32 *buffer); +u32 amdgpu_gfx_csb_data_parser(struct amdgpu_device *adev, volatile u32 *buffer, u32 count); +void amdgpu_gfx_csb_preamble_end(volatile u32 *buffer, u32 count); void amdgpu_debugfs_gfx_sched_mask_init(struct amdgpu_device *adev); void amdgpu_debugfs_compute_sched_mask_init(struct amdgpu_device *adev); -- 2.51.0 From 106172df6ece4fc0a53471c71e0d05e9140fa2cc Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 21 Apr 2025 16:12:19 -0600 Subject: [PATCH 13/16] drm/amdgpu/gfx: Use CSB helpers in gfx_v11_0_get_csb_buffer Part of the code in gfx_v11_0_get_csb_buffer can be removed in favor of some GFX CSB helpers. This commit removes the duplicated part for the GFX 11 CSB function. Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 34 ++++---------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index ac7ac58e25a6..2df11f4127cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -848,9 +848,7 @@ static u32 gfx_v11_0_get_csb_size(struct amdgpu_device *adev) static void gfx_v11_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer) { - u32 count = 0, i; - const struct cs_section_def *sect = NULL; - const struct cs_extent_def *ext = NULL; + u32 count = 0; int ctx_reg_offset; if (adev->gfx.rlc.cs_data == NULL) @@ -858,37 +856,15 @@ static void gfx_v11_0_get_csb_buffer(struct amdgpu_device *adev, if (buffer == NULL) return; - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); - buffer[count++] = cpu_to_le32(0x80000000); - buffer[count++] = cpu_to_le32(0x80000000); - - for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) { - for (ext = sect->section; ext->extent != NULL; ++ext) { - if (sect->id == SECT_CONTEXT) { - buffer[count++] = - cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); - buffer[count++] = cpu_to_le32(ext->reg_index - - PACKET3_SET_CONTEXT_REG_START); - for (i = 0; i < ext->reg_count; i++) - buffer[count++] = cpu_to_le32(ext->extent[i]); - } - } - } + count = amdgpu_gfx_csb_preamble_start(buffer); + count = amdgpu_gfx_csb_data_parser(adev, buffer, count); - ctx_reg_offset = - SOC15_REG_OFFSET(GC, 0, regPA_SC_TILE_STEERING_OVERRIDE) - PACKET3_SET_CONTEXT_REG_START; + ctx_reg_offset = SOC15_REG_OFFSET(GC, 0, regPA_SC_TILE_STEERING_OVERRIDE) - PACKET3_SET_CONTEXT_REG_START; buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1)); buffer[count++] = cpu_to_le32(ctx_reg_offset); buffer[count++] = cpu_to_le32(adev->gfx.config.pa_sc_tile_steering_override); - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); - buffer[count++] = cpu_to_le32(0); + amdgpu_gfx_csb_preamble_end(buffer, count); } static void gfx_v11_0_rlc_fini(struct amdgpu_device *adev) -- 2.51.0 From 0eef0e36bab1396f696983c8698c3c2f2a9d6a9d Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 21 Apr 2025 16:12:20 -0600 Subject: [PATCH 14/16] drm/amdgpu/gfx: Use CSB helpers in gfx_v10_0_get_csb_buffer Remove duplicate code by using CSB helpers. Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 34 ++++---------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index e140f673d25a..75ea071744eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -4325,9 +4325,7 @@ static u32 gfx_v10_0_get_csb_size(struct amdgpu_device *adev) static void gfx_v10_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer) { - u32 count = 0, i; - const struct cs_section_def *sect = NULL; - const struct cs_extent_def *ext = NULL; + u32 count = 0; int ctx_reg_offset; if (adev->gfx.rlc.cs_data == NULL) @@ -4335,37 +4333,15 @@ static void gfx_v10_0_get_csb_buffer(struct amdgpu_device *adev, if (buffer == NULL) return; - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); - buffer[count++] = cpu_to_le32(0x80000000); - buffer[count++] = cpu_to_le32(0x80000000); - - for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) { - for (ext = sect->section; ext->extent != NULL; ++ext) { - if (sect->id == SECT_CONTEXT) { - buffer[count++] = - cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); - buffer[count++] = cpu_to_le32(ext->reg_index - - PACKET3_SET_CONTEXT_REG_START); - for (i = 0; i < ext->reg_count; i++) - buffer[count++] = cpu_to_le32(ext->extent[i]); - } - } - } + count = amdgpu_gfx_csb_preamble_start(buffer); + count = amdgpu_gfx_csb_data_parser(adev, buffer, count); - ctx_reg_offset = - SOC15_REG_OFFSET(GC, 0, mmPA_SC_TILE_STEERING_OVERRIDE) - PACKET3_SET_CONTEXT_REG_START; + ctx_reg_offset = SOC15_REG_OFFSET(GC, 0, mmPA_SC_TILE_STEERING_OVERRIDE) - PACKET3_SET_CONTEXT_REG_START; buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1)); buffer[count++] = cpu_to_le32(ctx_reg_offset); buffer[count++] = cpu_to_le32(adev->gfx.config.pa_sc_tile_steering_override); - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); - buffer[count++] = cpu_to_le32(0); + amdgpu_gfx_csb_preamble_end(buffer, count); } static void gfx_v10_0_rlc_fini(struct amdgpu_device *adev) -- 2.51.0 From 9fec2e92fa991c882df424ab29f12779b217ab94 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 21 Apr 2025 16:12:21 -0600 Subject: [PATCH 15/16] drm/amdgpu/gfx: Use CSB helpers in gfx_v9_0_get_csb_buffer Eliminate code duplication in gfx_v9_0_get_csb_buffer by using CSB helpers. Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 32 ++++----------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index a63ba6642b18..d377a7c57d5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1651,40 +1651,16 @@ static u32 gfx_v9_0_get_csb_size(struct amdgpu_device *adev) static void gfx_v9_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer) { - u32 count = 0, i; - const struct cs_section_def *sect = NULL; - const struct cs_extent_def *ext = NULL; + u32 count = 0; if (adev->gfx.rlc.cs_data == NULL) return; if (buffer == NULL) return; - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); - buffer[count++] = cpu_to_le32(0x80000000); - buffer[count++] = cpu_to_le32(0x80000000); - - for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) { - for (ext = sect->section; ext->extent != NULL; ++ext) { - if (sect->id == SECT_CONTEXT) { - buffer[count++] = - cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); - buffer[count++] = cpu_to_le32(ext->reg_index - - PACKET3_SET_CONTEXT_REG_START); - for (i = 0; i < ext->reg_count; i++) - buffer[count++] = cpu_to_le32(ext->extent[i]); - } - } - } - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); - buffer[count++] = cpu_to_le32(0); + count = amdgpu_gfx_csb_preamble_start(buffer); + count = amdgpu_gfx_csb_data_parser(adev, buffer, count); + amdgpu_gfx_csb_preamble_end(buffer, count); } static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev) -- 2.51.0 From b990cb52340aedc2071fcf79e331a5b4bb7514ea Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Mon, 21 Apr 2025 16:12:22 -0600 Subject: [PATCH 16/16] drm/amdgpu/gfx: Use CSB helpers in gfx_v8_0_get_csb_buffer Remove code duplication from gfx_v8_0_get_csb_buffer by using CSB helpers. Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 34 ++++----------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index fc73be4ab068..5ee2237d8ee8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1223,46 +1223,22 @@ out: static void gfx_v8_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer) { - u32 count = 0, i; - const struct cs_section_def *sect = NULL; - const struct cs_extent_def *ext = NULL; + u32 count = 0; if (adev->gfx.rlc.cs_data == NULL) return; if (buffer == NULL) return; - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); - buffer[count++] = cpu_to_le32(0x80000000); - buffer[count++] = cpu_to_le32(0x80000000); - - for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) { - for (ext = sect->section; ext->extent != NULL; ++ext) { - if (sect->id == SECT_CONTEXT) { - buffer[count++] = - cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); - buffer[count++] = cpu_to_le32(ext->reg_index - - PACKET3_SET_CONTEXT_REG_START); - for (i = 0; i < ext->reg_count; i++) - buffer[count++] = cpu_to_le32(ext->extent[i]); - } - } - } + count = amdgpu_gfx_csb_preamble_start(buffer); + count = amdgpu_gfx_csb_data_parser(adev, buffer, count); buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - buffer[count++] = cpu_to_le32(mmPA_SC_RASTER_CONFIG - - PACKET3_SET_CONTEXT_REG_START); + buffer[count++] = cpu_to_le32(mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); buffer[count++] = cpu_to_le32(adev->gfx.config.rb_config[0][0].raster_config); buffer[count++] = cpu_to_le32(adev->gfx.config.rb_config[0][0].raster_config_1); - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); - - buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); - buffer[count++] = cpu_to_le32(0); + amdgpu_gfx_csb_preamble_end(buffer, count); } static int gfx_v8_0_cp_jump_table_num(struct amdgpu_device *adev) -- 2.51.0