Skip to content

Commit

Permalink
drm/amdkfd: Separate mqd allocation and initialization
Browse files Browse the repository at this point in the history
Introduce a new mqd allocation interface and split the original
init_mqd function into two functions: allocate_mqd and init_mqd.
Also renamed uninit_mqd to free_mqd. This is preparation work to
fix a circular lock dependency.

Signed-off-by: Oak Zeng <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
  • Loading branch information
oakzeng authored and evadot committed May 25, 2020
1 parent f3acb29 commit a39e402
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 193 deletions.
40 changes: 22 additions & 18 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,13 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
if (retval)
goto out_deallocate_hqd;

retval = mqd_mgr->init_mqd(mqd_mgr, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (retval)
q->mqd_mem_obj = mqd_mgr->allocate_mqd(mqd_mgr->dev, &q->properties);
if (!q->mqd_mem_obj) {
retval = -ENOMEM;
goto out_deallocate_doorbell;

}
mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (q->properties.is_active) {

if (WARN(q->process->mm != current->mm,
Expand All @@ -333,7 +335,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe,
q->queue, &q->properties, current->mm);
if (retval)
goto out_uninit_mqd;
goto out_free_mqd;
}

list_add(&q->list, &qpd->queues_list);
Expand All @@ -355,8 +357,8 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
dqm->total_queue_count);
goto out_unlock;

out_uninit_mqd:
mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
out_free_mqd:
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
out_deallocate_doorbell:
deallocate_doorbell(qpd, q);
out_deallocate_hqd:
Expand Down Expand Up @@ -450,7 +452,7 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
if (retval == -ETIME)
qpd->reset_wavefronts = true;

mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);

list_del(&q->list);
if (list_empty(&qpd->queues_list)) {
Expand Down Expand Up @@ -489,7 +491,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,

static int update_queue(struct device_queue_manager *dqm, struct queue *q)
{
int retval;
int retval = 0;
struct mqd_manager *mqd_mgr;
struct kfd_process_device *pdd;
bool prev_active = false;
Expand Down Expand Up @@ -527,7 +529,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
}
}

retval = mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties);
mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties);

/*
* check active state vs. the previous state and modify
Expand Down Expand Up @@ -1160,11 +1162,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
q->properties.tba_addr = qpd->tba_addr;
q->properties.tma_addr = qpd->tma_addr;
retval = mqd_mgr->init_mqd(mqd_mgr, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (retval)
q->mqd_mem_obj = mqd_mgr->allocate_mqd(mqd_mgr->dev, &q->properties);
if (!q->mqd_mem_obj) {
retval = -ENOMEM;
goto out_deallocate_doorbell;

}
mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
dqm_lock(dqm);

list_add(&q->list, &qpd->queues_list);
Expand Down Expand Up @@ -1373,8 +1377,8 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,

dqm_unlock(dqm);

/* Do uninit_mqd after dqm_unlock(dqm) to avoid circular locking */
mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
/* Do free_mqd after dqm_unlock(dqm) to avoid circular locking */
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);

return retval;

Expand Down Expand Up @@ -1615,14 +1619,14 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
kfd_dec_compute_active(dqm->dev);

/* Lastly, free mqd resources.
* Do uninit_mqd() after dqm_unlock to avoid circular locking.
* Do free_mqd() after dqm_unlock to avoid circular locking.
*/
list_for_each_entry_safe(q, next, &qpd->queues_list, list) {
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
q->properties.type)];
list_del(&q->list);
qpd->queue_count--;
mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
}

return retval;
Expand Down
16 changes: 9 additions & 7 deletions drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,14 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
kq->queue->device = dev;
kq->queue->process = kfd_get_process(current);

retval = kq->mqd_mgr->init_mqd(kq->mqd_mgr, &kq->queue->mqd,
&kq->queue->mqd_mem_obj,
kq->queue->mqd_mem_obj = kq->mqd_mgr->allocate_mqd(kq->mqd_mgr->dev,
&kq->queue->properties);
if (!kq->queue->mqd_mem_obj)
goto err_allocate_mqd;
kq->mqd_mgr->init_mqd(kq->mqd_mgr, &kq->queue->mqd,
kq->queue->mqd_mem_obj,
&kq->queue->gart_mqd_addr,
&kq->queue->properties);
if (retval != 0)
goto err_init_mqd;

/* assign HIQ to HQD */
if (type == KFD_QUEUE_TYPE_HIQ) {
pr_debug("Assigning hiq to hqd\n");
Expand All @@ -164,7 +165,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,

return true;
err_alloc_fence:
err_init_mqd:
kq->mqd_mgr->free_mqd(kq->mqd_mgr, kq->queue->mqd, kq->queue->mqd_mem_obj);
err_allocate_mqd:
uninit_queue(kq->queue);
err_init_queue:
kfd_gtt_sa_free(dev, kq->wptr_mem);
Expand Down Expand Up @@ -193,7 +195,7 @@ static void uninitialize(struct kernel_queue *kq)
else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj);

kq->mqd_mgr->uninit_mqd(kq->mqd_mgr, kq->queue->mqd,
kq->mqd_mgr->free_mqd(kq->mqd_mgr, kq->queue->mqd,
kq->queue->mqd_mem_obj);

kfd_gtt_sa_free(kq->dev, kq->rptr_mem);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ int pipe_priority_map[] = {
KFD_PIPE_PRIORITY_CS_HIGH
};

struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_dev *dev)
struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_dev *dev, struct queue_properties *q)
{
struct kfd_mem_obj *mqd_mem_obj = NULL;

Expand Down Expand Up @@ -86,7 +86,7 @@ struct kfd_mem_obj *allocate_sdma_mqd(struct kfd_dev *dev,
return mqd_mem_obj;
}

void uninit_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd,
void free_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
WARN_ON(!mqd_mem_obj->gtt_mem);
Expand Down
18 changes: 11 additions & 7 deletions drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* @destroy_mqd: Destroys the HQD slot and by that preempt the relevant queue.
* Used only for no cp scheduling.
*
* @uninit_mqd: Releases the mqd buffer from local gpu memory.
* @free_mqd: Releases the mqd buffer from local gpu memory.
*
* @is_occupied: Checks if the relevant HQD slot is occupied.
*
Expand All @@ -64,24 +64,27 @@
*/
extern int pipe_priority_map[];
struct mqd_manager {
int (*init_mqd)(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
struct kfd_mem_obj* (*allocate_mqd)(struct kfd_dev *kfd,
struct queue_properties *q);

void (*init_mqd)(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *q);

int (*load_mqd)(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
struct queue_properties *p,
struct mm_struct *mms);

int (*update_mqd)(struct mqd_manager *mm, void *mqd,
void (*update_mqd)(struct mqd_manager *mm, void *mqd,
struct queue_properties *q);

int (*destroy_mqd)(struct mqd_manager *mm, void *mqd,
enum kfd_preempt_type type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);

void (*uninit_mqd)(struct mqd_manager *mm, void *mqd,
void (*free_mqd)(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj);

bool (*is_occupied)(struct mqd_manager *mm, void *mqd,
Expand All @@ -102,11 +105,12 @@ struct mqd_manager {
uint32_t mqd_size;
};

struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_dev *dev);
struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_dev *dev,
struct queue_properties *q);

struct kfd_mem_obj *allocate_sdma_mqd(struct kfd_dev *dev,
struct queue_properties *q);
void uninit_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd,
void free_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj);

void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
Expand Down
Loading

0 comments on commit a39e402

Please sign in to comment.