drm/amdkfd: Check HIQ's MQD for queue preemption status
MEC firmware can silently fail the queue preemption request without time out. In this case, HIQ's MQD's queue_doorbell_id will be set. Check this field to see whether last queue preemption was successful or not. Signed-off-by: Oak Zeng <Oak.Zeng@amd.com> Suggested-by: Jay Cornwall <Jay.Cornwall@amd.com> Acked-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6d909c5da0
commit
51a0f459f1
@ -1393,6 +1393,7 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
|
||||
uint32_t filter_param)
|
||||
{
|
||||
int retval = 0;
|
||||
struct mqd_manager *mqd_mgr;
|
||||
|
||||
if (!dqm->sched_running)
|
||||
return 0;
|
||||
@ -1424,6 +1425,22 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* In the current MEC firmware implementation, if compute queue
|
||||
* doesn't response to the preemption request in time, HIQ will
|
||||
* abandon the unmap request without returning any timeout error
|
||||
* to driver. Instead, MEC firmware will log the doorbell of the
|
||||
* unresponding compute queue to HIQ.MQD.queue_doorbell_id fields.
|
||||
* To make sure the queue unmap was successful, driver need to
|
||||
* check those fields
|
||||
*/
|
||||
mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ];
|
||||
if (mqd_mgr->read_doorbell_id(dqm->packets.priv_queue->queue->mqd)) {
|
||||
pr_err("HIQ MQD's queue_doorbell_id0 is not 0, Queue preemption time out\n");
|
||||
while (halt_if_hws_hang)
|
||||
schedule();
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
pm_release_ib(&dqm->packets);
|
||||
dqm->active_runlist = false;
|
||||
|
||||
|
@ -101,6 +101,7 @@ struct mqd_manager {
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
int (*debugfs_show_mqd)(struct seq_file *m, void *data);
|
||||
#endif
|
||||
uint32_t (*read_doorbell_id)(void *mqd);
|
||||
|
||||
struct mutex mqd_mutex;
|
||||
struct kfd_dev *dev;
|
||||
|
@ -226,6 +226,13 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
__update_mqd(mm, mqd, q, 1);
|
||||
}
|
||||
|
||||
static uint32_t read_doorbell_id(void *mqd)
|
||||
{
|
||||
struct cik_mqd *m = (struct cik_mqd *)mqd;
|
||||
|
||||
return m->queue_doorbell_id0;
|
||||
}
|
||||
|
||||
static void update_mqd_hawaii(struct mqd_manager *mm, void *mqd,
|
||||
struct queue_properties *q)
|
||||
{
|
||||
@ -398,6 +405,7 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
mqd->debugfs_show_mqd = debugfs_show_mqd;
|
||||
#endif
|
||||
mqd->read_doorbell_id = read_doorbell_id;
|
||||
break;
|
||||
case KFD_MQD_TYPE_DIQ:
|
||||
mqd->allocate_mqd = allocate_mqd;
|
||||
|
@ -224,6 +224,13 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
q->is_active = QUEUE_IS_ACTIVE(*q);
|
||||
}
|
||||
|
||||
static uint32_t read_doorbell_id(void *mqd)
|
||||
{
|
||||
struct v10_compute_mqd *m = (struct v10_compute_mqd *)mqd;
|
||||
|
||||
return m->queue_doorbell_id0;
|
||||
}
|
||||
|
||||
static int destroy_mqd(struct mqd_manager *mm, void *mqd,
|
||||
enum kfd_preempt_type type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
@ -425,6 +432,7 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
mqd->debugfs_show_mqd = debugfs_show_mqd;
|
||||
#endif
|
||||
mqd->read_doorbell_id = read_doorbell_id;
|
||||
pr_debug("%s@%i\n", __func__, __LINE__);
|
||||
break;
|
||||
case KFD_MQD_TYPE_DIQ:
|
||||
|
@ -276,6 +276,13 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
}
|
||||
|
||||
|
||||
static uint32_t read_doorbell_id(void *mqd)
|
||||
{
|
||||
struct v9_mqd *m = (struct v9_mqd *)mqd;
|
||||
|
||||
return m->queue_doorbell_id0;
|
||||
}
|
||||
|
||||
static int destroy_mqd(struct mqd_manager *mm, void *mqd,
|
||||
enum kfd_preempt_type type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
@ -477,6 +484,7 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
mqd->debugfs_show_mqd = debugfs_show_mqd;
|
||||
#endif
|
||||
mqd->read_doorbell_id = read_doorbell_id;
|
||||
break;
|
||||
case KFD_MQD_TYPE_DIQ:
|
||||
mqd->allocate_mqd = allocate_mqd;
|
||||
|
@ -243,6 +243,13 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
__update_mqd(mm, mqd, q, MTYPE_CC, 1);
|
||||
}
|
||||
|
||||
static uint32_t read_doorbell_id(void *mqd)
|
||||
{
|
||||
struct vi_mqd *m = (struct vi_mqd *)mqd;
|
||||
|
||||
return m->queue_doorbell_id0;
|
||||
}
|
||||
|
||||
static void update_mqd_tonga(struct mqd_manager *mm, void *mqd,
|
||||
struct queue_properties *q)
|
||||
{
|
||||
@ -446,6 +453,7 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
mqd->debugfs_show_mqd = debugfs_show_mqd;
|
||||
#endif
|
||||
mqd->read_doorbell_id = read_doorbell_id;
|
||||
break;
|
||||
case KFD_MQD_TYPE_DIQ:
|
||||
mqd->allocate_mqd = allocate_mqd;
|
||||
|
@ -397,22 +397,22 @@ struct vi_mqd {
|
||||
uint32_t reserved60;
|
||||
uint32_t reserved61;
|
||||
uint32_t reserved62;
|
||||
uint32_t reserved63;
|
||||
uint32_t reserved64;
|
||||
uint32_t reserved65;
|
||||
uint32_t reserved66;
|
||||
uint32_t reserved67;
|
||||
uint32_t reserved68;
|
||||
uint32_t reserved69;
|
||||
uint32_t reserved70;
|
||||
uint32_t reserved71;
|
||||
uint32_t reserved72;
|
||||
uint32_t reserved73;
|
||||
uint32_t reserved74;
|
||||
uint32_t reserved75;
|
||||
uint32_t reserved76;
|
||||
uint32_t reserved77;
|
||||
uint32_t reserved78;
|
||||
uint32_t queue_doorbell_id0;
|
||||
uint32_t queue_doorbell_id1;
|
||||
uint32_t queue_doorbell_id2;
|
||||
uint32_t queue_doorbell_id3;
|
||||
uint32_t queue_doorbell_id4;
|
||||
uint32_t queue_doorbell_id5;
|
||||
uint32_t queue_doorbell_id6;
|
||||
uint32_t queue_doorbell_id7;
|
||||
uint32_t queue_doorbell_id8;
|
||||
uint32_t queue_doorbell_id9;
|
||||
uint32_t queue_doorbell_id10;
|
||||
uint32_t queue_doorbell_id11;
|
||||
uint32_t queue_doorbell_id12;
|
||||
uint32_t queue_doorbell_id13;
|
||||
uint32_t queue_doorbell_id14;
|
||||
uint32_t queue_doorbell_id15;
|
||||
uint32_t reserved_t[256];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user