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

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
Loading
Loading
Loading
Loading
+41 −19
Original line number Diff line number Diff line
@@ -144,7 +144,13 @@ static void decrement_queue_count(struct device_queue_manager *dqm,
		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;

@@ -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
		 * preserve the user mode ABI.
		 */

		if (restore_id && *restore_id != q->properties.queue_id)
			return -EINVAL;

		q->doorbell_id = q->properties.queue_id;
	} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
			q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
@@ -160,15 +170,26 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
		 * The doobell index distance between RLC (2*i) and (2*i+1)
		 * 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;
		uint32_t valid_id = idx_offset[q->properties.sdma_engine_id]
						+ (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 {
		/* For CP queues on SOC15 */
		if (restore_id) {
			/* make sure that ID is free  */
			if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
				return -EINVAL;

			q->doorbell_id = *restore_id;
		} else {
		/* For CP queues on SOC15 reserve a free doorbell ID */
			/* or reserve a free doorbell ID */
			unsigned int found;

			found = find_first_zero_bit(qpd->doorbell_bitmap,
@@ -180,6 +201,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
			set_bit(found, qpd->doorbell_bitmap);
			q->doorbell_id = found;
		}
	}

	q->properties.doorbell_off =
		kfd_get_doorbell_dw_offset_in_bar(dev, qpd_to_pdd(qpd),
@@ -346,7 +368,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
		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)
		goto out_deallocate_hqd;

@@ -1333,7 +1355,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
			goto out;
	}

	retval = allocate_doorbell(qpd, q);
	retval = allocate_doorbell(qpd, q, qd ? &qd->doorbell_id : NULL);
	if (retval)
		goto out_deallocate_sdma_queue;