mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 15:22:21 -04:00
drm/amdkfd: add sdma queue counter for gfxv9.4.3
since gfx 9.4.3 HW is calculating accumulated activity counter per-queue in register sdmax_rlcx_utilization_hi/lo, CPFW adds it in sdma MQD for save/restore, KFD will read it from there. gfx 9.4.2 will still keep the way to read from memory at rptr+8. v2: read dynamic counter directly from utilization register v3: add CPFW supported version check (Harish) Signed-off-by: Eric Huang <jinhuieric.huang@amd.com> Reviewed-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -530,6 +530,66 @@ static uint32_t kgd_v9_4_3_ptl_ctrl(struct amdgpu_device *adev,
|
|||||||
ptl_state, fmt1, fmt2);
|
ptl_state, fmt1, fmt2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kgd_gfx_v9_4_3_hqd_sdma_get_counter(struct amdgpu_device *adev,
|
||||||
|
void *mqd, uint32_t num_sdma_queues_per_eng,
|
||||||
|
uint64_t *val)
|
||||||
|
{
|
||||||
|
struct v9_sdma_mqd *m = get_sdma_mqd(mqd);
|
||||||
|
uint32_t sdma_rlc_reg_offset = 0;
|
||||||
|
uint32_t sdma_rlc_rb_cntl;
|
||||||
|
uint32_t engine_id, queue_id;
|
||||||
|
uint32_t engines = adev->sdma.num_instances;
|
||||||
|
uint32_t sdma_rlcx_rb_base, sdma_rlcx_rb_base_hi;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (!m)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||||
|
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4)) &&
|
||||||
|
adev->gfx.mec_fw_version < 194) ||
|
||||||
|
(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0) &&
|
||||||
|
adev->gfx.mec_fw_version < 44)) {
|
||||||
|
pr_warn_once("MEC FW doesn't support SDMA counter!\n");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SDMA doesn't support over-subscription, there must be
|
||||||
|
* a HQD associated with a MQD, so found must be true in
|
||||||
|
* the finding loop.
|
||||||
|
*/
|
||||||
|
for (engine_id = 0; engine_id < engines && !found; engine_id++) {
|
||||||
|
for (queue_id = 0; queue_id < num_sdma_queues_per_eng; queue_id++) {
|
||||||
|
sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
|
||||||
|
engine_id, queue_id);
|
||||||
|
sdma_rlcx_rb_base = RREG32(sdma_rlc_reg_offset +
|
||||||
|
regSDMA_RLC0_RB_BASE);
|
||||||
|
sdma_rlcx_rb_base_hi = RREG32(sdma_rlc_reg_offset +
|
||||||
|
regSDMA_RLC0_RB_BASE_HI);
|
||||||
|
|
||||||
|
if (m->sdmax_rlcx_rb_base == sdma_rlcx_rb_base &&
|
||||||
|
m->sdmax_rlcx_rb_base_hi == sdma_rlcx_rb_base_hi) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sdma_rlc_rb_cntl = RREG32(sdma_rlc_reg_offset + regSDMA_RLC0_RB_CNTL);
|
||||||
|
|
||||||
|
/* Read sdma activity counter from utilization register
|
||||||
|
* if hw queue is enabled, otherwise read from MQD.
|
||||||
|
*/
|
||||||
|
if (sdma_rlc_rb_cntl & SDMA_RLC0_RB_CNTL__RB_ENABLE_MASK)
|
||||||
|
*val = (uint64_t)RREG32(sdma_rlc_reg_offset + regSDMA_RLC0_UTILIZATION_HI) << 32 |
|
||||||
|
RREG32(sdma_rlc_reg_offset + regSDMA_RLC0_UTILIZATION_LO);
|
||||||
|
else
|
||||||
|
*val = (uint64_t)m->sdmax_rlcx_utilization_hi << 32 |
|
||||||
|
m->sdmax_rlcx_utilization_lo;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const struct kfd2kgd_calls gc_9_4_3_kfd2kgd = {
|
const struct kfd2kgd_calls gc_9_4_3_kfd2kgd = {
|
||||||
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
|
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
|
||||||
.set_pasid_vmid_mapping = kgd_gfx_v9_4_3_set_pasid_vmid_mapping,
|
.set_pasid_vmid_mapping = kgd_gfx_v9_4_3_set_pasid_vmid_mapping,
|
||||||
@@ -566,5 +626,6 @@ const struct kfd2kgd_calls gc_9_4_3_kfd2kgd = {
|
|||||||
.hqd_get_pq_addr = kgd_gfx_v9_hqd_get_pq_addr,
|
.hqd_get_pq_addr = kgd_gfx_v9_hqd_get_pq_addr,
|
||||||
.hqd_reset = kgd_gfx_v9_hqd_reset,
|
.hqd_reset = kgd_gfx_v9_hqd_reset,
|
||||||
.hqd_sdma_get_doorbell = kgd_gfx_v9_4_3_hqd_sdma_get_doorbell,
|
.hqd_sdma_get_doorbell = kgd_gfx_v9_4_3_hqd_sdma_get_doorbell,
|
||||||
.ptl_ctrl = kgd_v9_4_3_ptl_ctrl
|
.ptl_ctrl = kgd_v9_4_3_ptl_ctrl,
|
||||||
|
.hqd_sdma_get_counter = kgd_gfx_v9_4_3_hqd_sdma_get_counter
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1027,8 +1027,17 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
|
|||||||
/* Get the SDMA queue stats */
|
/* Get the SDMA queue stats */
|
||||||
if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) ||
|
if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) ||
|
||||||
(q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
(q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
||||||
retval = read_sdma_queue_counter((uint64_t __user *)q->properties.read_ptr,
|
if (KFD_GC_VERSION(dqm->dev) <= IP_VERSION(9, 4, 2))
|
||||||
&sdma_val);
|
retval = read_sdma_queue_counter(
|
||||||
|
(uint64_t __user *)q->properties.read_ptr,
|
||||||
|
&sdma_val);
|
||||||
|
else
|
||||||
|
retval = dqm->dev->kfd2kgd->hqd_sdma_get_counter ?
|
||||||
|
dqm->dev->kfd2kgd->hqd_sdma_get_counter(
|
||||||
|
dqm->dev->adev, q->mqd,
|
||||||
|
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
|
||||||
|
&sdma_val) :
|
||||||
|
-EOPNOTSUPP;
|
||||||
if (retval)
|
if (retval)
|
||||||
dev_err(dev, "Failed to read SDMA queue counter for queue: %d\n",
|
dev_err(dev, "Failed to read SDMA queue counter for queue: %d\n",
|
||||||
q->properties.queue_id);
|
q->properties.queue_id);
|
||||||
@@ -2666,8 +2675,18 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
|
|||||||
/* Get the SDMA queue stats */
|
/* Get the SDMA queue stats */
|
||||||
if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) ||
|
if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) ||
|
||||||
(q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
(q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
||||||
retval = read_sdma_queue_counter((uint64_t __user *)q->properties.read_ptr,
|
if (KFD_GC_VERSION(dqm->dev) <= IP_VERSION(9, 4, 2))
|
||||||
&sdma_val);
|
retval = read_sdma_queue_counter(
|
||||||
|
(uint64_t __user *)q->properties.read_ptr,
|
||||||
|
&sdma_val);
|
||||||
|
else
|
||||||
|
retval = dqm->dev->kfd2kgd->hqd_sdma_get_counter ?
|
||||||
|
dqm->dev->kfd2kgd->hqd_sdma_get_counter(
|
||||||
|
dqm->dev->adev, q->mqd,
|
||||||
|
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
|
||||||
|
&sdma_val) :
|
||||||
|
-EOPNOTSUPP;
|
||||||
|
|
||||||
if (retval)
|
if (retval)
|
||||||
dev_err(dev, "Failed to read SDMA queue counter for queue: %d\n",
|
dev_err(dev, "Failed to read SDMA queue counter for queue: %d\n",
|
||||||
q->properties.queue_id);
|
q->properties.queue_id);
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ struct kfd_sdma_activity_handler_workarea {
|
|||||||
|
|
||||||
struct temp_sdma_queue_list {
|
struct temp_sdma_queue_list {
|
||||||
uint64_t __user *rptr;
|
uint64_t __user *rptr;
|
||||||
|
void *mqd;
|
||||||
uint64_t sdma_val;
|
uint64_t sdma_val;
|
||||||
unsigned int queue_id;
|
unsigned int queue_id;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@@ -161,6 +162,7 @@ static void kfd_sdma_activity_worker(struct work_struct *work)
|
|||||||
|
|
||||||
INIT_LIST_HEAD(&sdma_q->list);
|
INIT_LIST_HEAD(&sdma_q->list);
|
||||||
sdma_q->rptr = (uint64_t __user *)q->properties.read_ptr;
|
sdma_q->rptr = (uint64_t __user *)q->properties.read_ptr;
|
||||||
|
sdma_q->mqd = q->mqd;
|
||||||
sdma_q->queue_id = q->properties.queue_id;
|
sdma_q->queue_id = q->properties.queue_id;
|
||||||
list_add_tail(&sdma_q->list, &sdma_q_list.list);
|
list_add_tail(&sdma_q->list, &sdma_q_list.list);
|
||||||
}
|
}
|
||||||
@@ -189,7 +191,17 @@ static void kfd_sdma_activity_worker(struct work_struct *work)
|
|||||||
|
|
||||||
list_for_each_entry(sdma_q, &sdma_q_list.list, list) {
|
list_for_each_entry(sdma_q, &sdma_q_list.list, list) {
|
||||||
val = 0;
|
val = 0;
|
||||||
ret = read_sdma_queue_counter(sdma_q->rptr, &val);
|
|
||||||
|
if (KFD_GC_VERSION(dqm->dev) <= IP_VERSION(9, 4, 2))
|
||||||
|
ret = read_sdma_queue_counter(sdma_q->rptr, &val);
|
||||||
|
else
|
||||||
|
ret = dqm->dev->kfd2kgd->hqd_sdma_get_counter ?
|
||||||
|
dqm->dev->kfd2kgd->hqd_sdma_get_counter(
|
||||||
|
dqm->dev->adev, sdma_q->mqd,
|
||||||
|
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
|
||||||
|
&val) :
|
||||||
|
-EOPNOTSUPP;
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_debug("Failed to read SDMA queue active counter for queue id: %d",
|
pr_debug("Failed to read SDMA queue active counter for queue id: %d",
|
||||||
sdma_q->queue_id);
|
sdma_q->queue_id);
|
||||||
|
|||||||
@@ -493,6 +493,10 @@
|
|||||||
#define regSDMA_RLC0_MIDCMD_DATA10_BASE_IDX 0
|
#define regSDMA_RLC0_MIDCMD_DATA10_BASE_IDX 0
|
||||||
#define regSDMA_RLC0_MIDCMD_CNTL 0x017b
|
#define regSDMA_RLC0_MIDCMD_CNTL 0x017b
|
||||||
#define regSDMA_RLC0_MIDCMD_CNTL_BASE_IDX 0
|
#define regSDMA_RLC0_MIDCMD_CNTL_BASE_IDX 0
|
||||||
|
#define regSDMA_RLC0_UTILIZATION_LO 0x017c
|
||||||
|
#define regSDMA_RLC0_UTILIZATION_LO_BASE_IDX 0
|
||||||
|
#define regSDMA_RLC0_UTILIZATION_HI 0x017d
|
||||||
|
#define regSDMA_RLC0_UTILIZATION_HI_BASE_IDX 0
|
||||||
#define regSDMA_RLC1_RB_CNTL 0x0188
|
#define regSDMA_RLC1_RB_CNTL 0x0188
|
||||||
#define regSDMA_RLC1_RB_CNTL_BASE_IDX 0
|
#define regSDMA_RLC1_RB_CNTL_BASE_IDX 0
|
||||||
#define regSDMA_RLC1_RB_BASE 0x0189
|
#define regSDMA_RLC1_RB_BASE 0x0189
|
||||||
|
|||||||
@@ -339,6 +339,9 @@ struct kfd2kgd_calls {
|
|||||||
uint32_t *ptl_state,
|
uint32_t *ptl_state,
|
||||||
enum amdgpu_ptl_fmt *fmt1,
|
enum amdgpu_ptl_fmt *fmt1,
|
||||||
enum amdgpu_ptl_fmt *fmt2);
|
enum amdgpu_ptl_fmt *fmt2);
|
||||||
|
int (*hqd_sdma_get_counter)(struct amdgpu_device *adev,
|
||||||
|
void *mqd, uint32_t num_sdma_queues_per_eng,
|
||||||
|
uint64_t *val);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* KGD_KFD_INTERFACE_H_INCLUDED */
|
#endif /* KGD_KFD_INTERFACE_H_INCLUDED */
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ struct v9_sdma_mqd {
|
|||||||
uint32_t sdmax_rlcx_midcmd_cntl;
|
uint32_t sdmax_rlcx_midcmd_cntl;
|
||||||
uint32_t reserved_42;
|
uint32_t reserved_42;
|
||||||
uint32_t reserved_43;
|
uint32_t reserved_43;
|
||||||
uint32_t reserved_44;
|
uint32_t sdmax_rlcx_utilization_lo;
|
||||||
uint32_t reserved_45;
|
uint32_t sdmax_rlcx_utilization_hi;
|
||||||
uint32_t reserved_46;
|
uint32_t reserved_46;
|
||||||
uint32_t reserved_47;
|
uint32_t reserved_47;
|
||||||
uint32_t reserved_48;
|
uint32_t reserved_48;
|
||||||
|
|||||||
Reference in New Issue
Block a user