Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45c9a5e4 authored by Oded Gabbay's avatar Oded Gabbay
Browse files

drm/amdkfd: Encapsulate DQM functions in ops structure



This patch does some re-org on the device_queue_manager structure. It takes out
all the function pointers from the structure and puts them in a new structure,
called device_queue_manager_ops. Then, it puts an instance of that structure
inside device_queue_manager.

This re-org is done to prepare the DQM module to support more than one AMD APU
(Kaveri).

Signed-off-by: default avatarOded Gabbay <oded.gabbay@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9216ed29
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -439,7 +439,7 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,
		(args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
		   ? cache_policy_coherent : cache_policy_noncoherent;

	if (!dev->dqm->set_cache_memory_policy(dev->dqm,
	if (!dev->dqm->ops.set_cache_memory_policy(dev->dqm,
				&pdd->qpd,
				default_policy,
				alternate_policy,
+3 −3
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
		goto device_queue_manager_error;
	}

	if (kfd->dqm->start(kfd->dqm) != 0) {
	if (kfd->dqm->ops.start(kfd->dqm) != 0) {
		dev_err(kfd_device,
			"Error starting queuen manager for device (%x:%x)\n",
			kfd->pdev->vendor, kfd->pdev->device);
@@ -307,7 +307,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd)
	BUG_ON(kfd == NULL);

	if (kfd->init_complete) {
		kfd->dqm->stop(kfd->dqm);
		kfd->dqm->ops.stop(kfd->dqm);
		amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
		amd_iommu_free_device(kfd->pdev);
	}
@@ -328,7 +328,7 @@ int kgd2kfd_resume(struct kfd_dev *kfd)
			return -ENXIO;
		amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
						iommu_pasid_shutdown_callback);
		kfd->dqm->start(kfd->dqm);
		kfd->dqm->ops.start(kfd->dqm);
	}

	return 0;
+34 −34
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,

	BUG_ON(!dqm || !q || !qpd);

	mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
	mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
	if (mqd == NULL)
		return -ENOMEM;

@@ -305,14 +305,14 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
	mutex_lock(&dqm->lock);

	if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) {
		mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
		mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
		if (mqd == NULL) {
			retval = -ENOMEM;
			goto out;
		}
		deallocate_hqd(dqm, q);
	} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
		mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
		mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
		if (mqd == NULL) {
			retval = -ENOMEM;
			goto out;
@@ -348,7 +348,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
	BUG_ON(!dqm || !q || !q->mqd);

	mutex_lock(&dqm->lock);
	mqd = dqm->get_mqd_manager(dqm, q->properties.type);
	mqd = dqm->ops.get_mqd_manager(dqm, q->properties.type);
	if (mqd == NULL) {
		mutex_unlock(&dqm->lock);
		return -ENOMEM;
@@ -515,7 +515,7 @@ static int init_pipelines(struct device_queue_manager *dqm,

	memset(hpdptr, 0, CIK_HPD_EOP_BYTES * pipes_num);

	mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
	mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
	if (mqd == NULL) {
		kfd_gtt_sa_free(dqm->dev, dqm->pipeline_mem);
		return -ENOMEM;
@@ -646,7 +646,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
	struct mqd_manager *mqd;
	int retval;

	mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
	mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
	if (!mqd)
		return -ENOMEM;

@@ -849,7 +849,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
	if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
		select_sdma_engine_id(q);

	mqd = dqm->get_mqd_manager(dqm,
	mqd = dqm->ops.get_mqd_manager(dqm,
			get_mqd_type_from_queue_type(q->properties.type));

	if (mqd == NULL) {
@@ -994,7 +994,7 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,

	/* remove queue from list to prevent rescheduling after preemption */
	mutex_lock(&dqm->lock);
	mqd = dqm->get_mqd_manager(dqm,
	mqd = dqm->ops.get_mqd_manager(dqm,
			get_mqd_type_from_queue_type(q->properties.type));
	if (!mqd) {
		retval = -ENOMEM;
@@ -1116,40 +1116,40 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
	case KFD_SCHED_POLICY_HWS:
	case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION:
		/* initialize dqm for cp scheduling */
		dqm->create_queue = create_queue_cpsch;
		dqm->initialize = initialize_cpsch;
		dqm->start = start_cpsch;
		dqm->stop = stop_cpsch;
		dqm->destroy_queue = destroy_queue_cpsch;
		dqm->update_queue = update_queue;
		dqm->get_mqd_manager = get_mqd_manager_nocpsch;
		dqm->register_process = register_process_nocpsch;
		dqm->unregister_process = unregister_process_nocpsch;
		dqm->uninitialize = uninitialize_nocpsch;
		dqm->create_kernel_queue = create_kernel_queue_cpsch;
		dqm->destroy_kernel_queue = destroy_kernel_queue_cpsch;
		dqm->set_cache_memory_policy = set_cache_memory_policy;
		dqm->ops.create_queue = create_queue_cpsch;
		dqm->ops.initialize = initialize_cpsch;
		dqm->ops.start = start_cpsch;
		dqm->ops.stop = stop_cpsch;
		dqm->ops.destroy_queue = destroy_queue_cpsch;
		dqm->ops.update_queue = update_queue;
		dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch;
		dqm->ops.register_process = register_process_nocpsch;
		dqm->ops.unregister_process = unregister_process_nocpsch;
		dqm->ops.uninitialize = uninitialize_nocpsch;
		dqm->ops.create_kernel_queue = create_kernel_queue_cpsch;
		dqm->ops.destroy_kernel_queue = destroy_kernel_queue_cpsch;
		dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
		break;
	case KFD_SCHED_POLICY_NO_HWS:
		/* initialize dqm for no cp scheduling */
		dqm->start = start_nocpsch;
		dqm->stop = stop_nocpsch;
		dqm->create_queue = create_queue_nocpsch;
		dqm->destroy_queue = destroy_queue_nocpsch;
		dqm->update_queue = update_queue;
		dqm->get_mqd_manager = get_mqd_manager_nocpsch;
		dqm->register_process = register_process_nocpsch;
		dqm->unregister_process = unregister_process_nocpsch;
		dqm->initialize = initialize_nocpsch;
		dqm->uninitialize = uninitialize_nocpsch;
		dqm->set_cache_memory_policy = set_cache_memory_policy;
		dqm->ops.start = start_nocpsch;
		dqm->ops.stop = stop_nocpsch;
		dqm->ops.create_queue = create_queue_nocpsch;
		dqm->ops.destroy_queue = destroy_queue_nocpsch;
		dqm->ops.update_queue = update_queue;
		dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch;
		dqm->ops.register_process = register_process_nocpsch;
		dqm->ops.unregister_process = unregister_process_nocpsch;
		dqm->ops.initialize = initialize_nocpsch;
		dqm->ops.uninitialize = uninitialize_nocpsch;
		dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
		break;
	default:
		BUG();
		break;
	}

	if (dqm->initialize(dqm) != 0) {
	if (dqm->ops.initialize(dqm) != 0) {
		kfree(dqm);
		return NULL;
	}
@@ -1161,7 +1161,7 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm)
{
	BUG_ON(!dqm);

	dqm->uninitialize(dqm);
	dqm->ops.uninitialize(dqm);
	kfree(dqm);
}
+17 −8
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ struct device_process_node {
};

/**
 * struct device_queue_manager
 * struct device_queue_manager_ops
 *
 * @create_queue: Queue creation routine.
 *
@@ -81,15 +81,9 @@ struct device_process_node {
 * @set_cache_memory_policy: Sets memory policy (cached/ non cached) for the
 * memory apertures.
 *
 * This struct is a base class for the kfd queues scheduler in the
 * device level. The device base class should expose the basic operations
 * for queue creation and queue destruction. This base class hides the
 * scheduling mode of the driver and the specific implementation of the
 * concrete device. This class is the only class in the queues scheduler
 * that configures the H/W.
 */

struct device_queue_manager {
struct device_queue_manager_ops {
	int	(*create_queue)(struct device_queue_manager *dqm,
				struct queue *q,
				struct qcm_process_device *qpd,
@@ -124,7 +118,22 @@ struct device_queue_manager {
					   enum cache_policy alternate_policy,
					   void __user *alternate_aperture_base,
					   uint64_t alternate_aperture_size);
};

/**
 * struct device_queue_manager
 *
 * This struct is a base class for the kfd queues scheduler in the
 * device level. The device base class should expose the basic operations
 * for queue creation and queue destruction. This base class hides the
 * scheduling mode of the driver and the specific implementation of the
 * concrete device. This class is the only class in the queues scheduler
 * that configures the H/W.
 *
 */

struct device_queue_manager {
	struct device_queue_manager_ops ops;

	struct mqd_manager	*mqds[KFD_MQD_TYPE_MAX];
	struct packet_manager	packets;
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
	switch (type) {
	case KFD_QUEUE_TYPE_DIQ:
	case KFD_QUEUE_TYPE_HIQ:
		kq->mqd = dev->dqm->get_mqd_manager(dev->dqm,
		kq->mqd = dev->dqm->ops.get_mqd_manager(dev->dqm,
						KFD_MQD_TYPE_HIQ);
		break;
	default:
Loading