Commit 5bb6a8fa authored by David Yat Sin's avatar David Yat Sin Committed by Alex Deucher

drm/amdkfd: CRIU restore queue doorbell id

When re-creating queues during CRIU restore, restore the queue with the
same doorbell id value used during CRIU dump.
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarDavid Yat Sin <david.yatsin@amd.com>
Signed-off-by: default avatarRajneesh Bhardwaj <rajneesh.bhardwaj@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2485c12c
...@@ -144,7 +144,13 @@ static void decrement_queue_count(struct device_queue_manager *dqm, ...@@ -144,7 +144,13 @@ static void decrement_queue_count(struct device_queue_manager *dqm,
dqm->active_cp_queue_count--; dqm->active_cp_queue_count--;
} }
static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q) /*
* Allocate a doorbell ID to this queue.
* If doorbell_id is passed in, make sure requested ID is valid then allocate it.
*/
static int allocate_doorbell(struct qcm_process_device *qpd,
struct queue *q,
uint32_t const *restore_id)
{ {
struct kfd_dev *dev = qpd->dqm->dev; struct kfd_dev *dev = qpd->dqm->dev;
...@@ -152,6 +158,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q) ...@@ -152,6 +158,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
/* On pre-SOC15 chips we need to use the queue ID to /* On pre-SOC15 chips we need to use the queue ID to
* preserve the user mode ABI. * preserve the user mode ABI.
*/ */
if (restore_id && *restore_id != q->properties.queue_id)
return -EINVAL;
q->doorbell_id = q->properties.queue_id; q->doorbell_id = q->properties.queue_id;
} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA || } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) { q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
...@@ -160,25 +170,37 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q) ...@@ -160,25 +170,37 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
* The doobell index distance between RLC (2*i) and (2*i+1) * The doobell index distance between RLC (2*i) and (2*i+1)
* for a SDMA engine is 512. * for a SDMA engine is 512.
*/ */
uint32_t *idx_offset =
dev->shared_resources.sdma_doorbell_idx;
q->doorbell_id = idx_offset[q->properties.sdma_engine_id] uint32_t *idx_offset = dev->shared_resources.sdma_doorbell_idx;
+ (q->properties.sdma_queue_id & 1) uint32_t valid_id = idx_offset[q->properties.sdma_engine_id]
* KFD_QUEUE_DOORBELL_MIRROR_OFFSET + (q->properties.sdma_queue_id & 1)
+ (q->properties.sdma_queue_id >> 1); * KFD_QUEUE_DOORBELL_MIRROR_OFFSET
+ (q->properties.sdma_queue_id >> 1);
if (restore_id && *restore_id != valid_id)
return -EINVAL;
q->doorbell_id = valid_id;
} else { } else {
/* For CP queues on SOC15 reserve a free doorbell ID */ /* For CP queues on SOC15 */
unsigned int found; if (restore_id) {
/* make sure that ID is free */
found = find_first_zero_bit(qpd->doorbell_bitmap, if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); return -EINVAL;
if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
pr_debug("No doorbells available"); q->doorbell_id = *restore_id;
return -EBUSY; } else {
/* or reserve a free doorbell ID */
unsigned int found;
found = find_first_zero_bit(qpd->doorbell_bitmap,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
pr_debug("No doorbells available");
return -EBUSY;
}
set_bit(found, qpd->doorbell_bitmap);
q->doorbell_id = found;
} }
set_bit(found, qpd->doorbell_bitmap);
q->doorbell_id = found;
} }
q->properties.doorbell_off = q->properties.doorbell_off =
...@@ -346,7 +368,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, ...@@ -346,7 +368,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
dqm->asic_ops.init_sdma_vm(dqm, q, qpd); dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
} }
retval = allocate_doorbell(qpd, q); retval = allocate_doorbell(qpd, q, qd ? &qd->doorbell_id : NULL);
if (retval) if (retval)
goto out_deallocate_hqd; goto out_deallocate_hqd;
...@@ -1333,7 +1355,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, ...@@ -1333,7 +1355,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
goto out; goto out;
} }
retval = allocate_doorbell(qpd, q); retval = allocate_doorbell(qpd, q, qd ? &qd->doorbell_id : NULL);
if (retval) if (retval)
goto out_deallocate_sdma_queue; goto out_deallocate_sdma_queue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment