drm/amdkfd: Encapsulate KQ functions in ops structure
This patch does some re-org on the kernel_queue structure. It takes out all the function pointers from the structure and puts them in a new structure, called kernel_queue_ops. Then, it puts an instance of that structure inside kernel_queue. This re-org is done to prepare the KQ module to support more than one AMD APU (Kaveri). Signed-off-by: Oded Gabbay <oded.gabbay@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -293,14 +293,14 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
|
|||||||
if (!kq)
|
if (!kq)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
kq->initialize = initialize;
|
kq->ops.initialize = initialize;
|
||||||
kq->uninitialize = uninitialize;
|
kq->ops.uninitialize = uninitialize;
|
||||||
kq->acquire_packet_buffer = acquire_packet_buffer;
|
kq->ops.acquire_packet_buffer = acquire_packet_buffer;
|
||||||
kq->submit_packet = submit_packet;
|
kq->ops.submit_packet = submit_packet;
|
||||||
kq->sync_with_hw = sync_with_hw;
|
kq->ops.sync_with_hw = sync_with_hw;
|
||||||
kq->rollback_packet = rollback_packet;
|
kq->ops.rollback_packet = rollback_packet;
|
||||||
|
|
||||||
if (kq->initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
|
if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
|
||||||
pr_err("kfd: failed to init kernel queue\n");
|
pr_err("kfd: failed to init kernel queue\n");
|
||||||
kfree(kq);
|
kfree(kq);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -312,7 +312,7 @@ void kernel_queue_uninit(struct kernel_queue *kq)
|
|||||||
{
|
{
|
||||||
BUG_ON(!kq);
|
BUG_ON(!kq);
|
||||||
|
|
||||||
kq->uninitialize(kq);
|
kq->ops.uninitialize(kq);
|
||||||
kfree(kq);
|
kfree(kq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,12 +329,12 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
|
|||||||
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
|
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
|
||||||
BUG_ON(!kq);
|
BUG_ON(!kq);
|
||||||
|
|
||||||
retval = kq->acquire_packet_buffer(kq, 5, &buffer);
|
retval = kq->ops.acquire_packet_buffer(kq, 5, &buffer);
|
||||||
BUG_ON(retval != 0);
|
BUG_ON(retval != 0);
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
buffer[i] = kq->nop_packet;
|
buffer[i] = kq->nop_packet;
|
||||||
kq->submit_packet(kq);
|
kq->ops.submit_packet(kq);
|
||||||
kq->sync_with_hw(kq, 1000);
|
kq->ops.sync_with_hw(kq, 1000);
|
||||||
|
|
||||||
pr_debug("kfd: ending kernel queue test\n");
|
pr_debug("kfd: ending kernel queue test\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,31 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include "kfd_priv.h"
|
#include "kfd_priv.h"
|
||||||
|
|
||||||
struct kernel_queue {
|
/**
|
||||||
/* interface */
|
* struct kernel_queue_ops
|
||||||
|
*
|
||||||
|
* @initialize: Initialize a kernel queue, including allocations of GART memory
|
||||||
|
* needed for the queue.
|
||||||
|
*
|
||||||
|
* @uninitialize: Uninitialize a kernel queue and free all its memory usages.
|
||||||
|
*
|
||||||
|
* @acquire_packet_buffer: Returns a pointer to the location in the kernel
|
||||||
|
* queue ring buffer where the calling function can write its packet. It is
|
||||||
|
* Guaranteed that there is enough space for that packet. It also updates the
|
||||||
|
* pending write pointer to that location so subsequent calls to
|
||||||
|
* acquire_packet_buffer will get a correct write pointer
|
||||||
|
*
|
||||||
|
* @submit_packet: Update the write pointer and doorbell of a kernel queue.
|
||||||
|
*
|
||||||
|
* @sync_with_hw: Wait until the write pointer and the read pointer of a kernel
|
||||||
|
* queue are equal, which means the CP has read all the submitted packets.
|
||||||
|
*
|
||||||
|
* @rollback_packet: This routine is called if we failed to build an acquired
|
||||||
|
* packet for some reason. It just overwrites the pending wptr with the current
|
||||||
|
* one
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct kernel_queue_ops {
|
||||||
bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev,
|
bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev,
|
||||||
enum kfd_queue_type type, unsigned int queue_size);
|
enum kfd_queue_type type, unsigned int queue_size);
|
||||||
void (*uninitialize)(struct kernel_queue *kq);
|
void (*uninitialize)(struct kernel_queue *kq);
|
||||||
@@ -41,6 +64,10 @@ struct kernel_queue {
|
|||||||
int (*sync_with_hw)(struct kernel_queue *kq,
|
int (*sync_with_hw)(struct kernel_queue *kq,
|
||||||
unsigned long timeout_ms);
|
unsigned long timeout_ms);
|
||||||
void (*rollback_packet)(struct kernel_queue *kq);
|
void (*rollback_packet)(struct kernel_queue *kq);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kernel_queue {
|
||||||
|
struct kernel_queue_ops ops;
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
struct kfd_dev *dev;
|
struct kfd_dev *dev;
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ int pm_send_set_resources(struct packet_manager *pm,
|
|||||||
pr_debug("kfd: In func %s\n", __func__);
|
pr_debug("kfd: In func %s\n", __func__);
|
||||||
|
|
||||||
mutex_lock(&pm->lock);
|
mutex_lock(&pm->lock);
|
||||||
pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
|
pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
|
||||||
sizeof(*packet) / sizeof(uint32_t),
|
sizeof(*packet) / sizeof(uint32_t),
|
||||||
(unsigned int **)&packet);
|
(unsigned int **)&packet);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
@@ -375,8 +375,8 @@ int pm_send_set_resources(struct packet_manager *pm,
|
|||||||
packet->queue_mask_lo = lower_32_bits(res->queue_mask);
|
packet->queue_mask_lo = lower_32_bits(res->queue_mask);
|
||||||
packet->queue_mask_hi = upper_32_bits(res->queue_mask);
|
packet->queue_mask_hi = upper_32_bits(res->queue_mask);
|
||||||
|
|
||||||
pm->priv_queue->submit_packet(pm->priv_queue);
|
pm->priv_queue->ops.submit_packet(pm->priv_queue);
|
||||||
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
||||||
|
|
||||||
mutex_unlock(&pm->lock);
|
mutex_unlock(&pm->lock);
|
||||||
|
|
||||||
@@ -402,7 +402,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
|
|||||||
packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
|
packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
|
||||||
mutex_lock(&pm->lock);
|
mutex_lock(&pm->lock);
|
||||||
|
|
||||||
retval = pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
|
retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
|
||||||
packet_size_dwords, &rl_buffer);
|
packet_size_dwords, &rl_buffer);
|
||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
goto fail_acquire_packet_buffer;
|
goto fail_acquire_packet_buffer;
|
||||||
@@ -412,15 +412,15 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
|
|||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
goto fail_create_runlist;
|
goto fail_create_runlist;
|
||||||
|
|
||||||
pm->priv_queue->submit_packet(pm->priv_queue);
|
pm->priv_queue->ops.submit_packet(pm->priv_queue);
|
||||||
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
||||||
|
|
||||||
mutex_unlock(&pm->lock);
|
mutex_unlock(&pm->lock);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
fail_create_runlist:
|
fail_create_runlist:
|
||||||
pm->priv_queue->rollback_packet(pm->priv_queue);
|
pm->priv_queue->ops.rollback_packet(pm->priv_queue);
|
||||||
fail_acquire_packet_buffer:
|
fail_acquire_packet_buffer:
|
||||||
mutex_unlock(&pm->lock);
|
mutex_unlock(&pm->lock);
|
||||||
fail_create_runlist_ib:
|
fail_create_runlist_ib:
|
||||||
@@ -438,7 +438,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
|
|||||||
BUG_ON(!pm || !fence_address);
|
BUG_ON(!pm || !fence_address);
|
||||||
|
|
||||||
mutex_lock(&pm->lock);
|
mutex_lock(&pm->lock);
|
||||||
retval = pm->priv_queue->acquire_packet_buffer(
|
retval = pm->priv_queue->ops.acquire_packet_buffer(
|
||||||
pm->priv_queue,
|
pm->priv_queue,
|
||||||
sizeof(struct pm4_query_status) / sizeof(uint32_t),
|
sizeof(struct pm4_query_status) / sizeof(uint32_t),
|
||||||
(unsigned int **)&packet);
|
(unsigned int **)&packet);
|
||||||
@@ -459,8 +459,8 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
|
|||||||
packet->data_hi = upper_32_bits((uint64_t)fence_value);
|
packet->data_hi = upper_32_bits((uint64_t)fence_value);
|
||||||
packet->data_lo = lower_32_bits((uint64_t)fence_value);
|
packet->data_lo = lower_32_bits((uint64_t)fence_value);
|
||||||
|
|
||||||
pm->priv_queue->submit_packet(pm->priv_queue);
|
pm->priv_queue->ops.submit_packet(pm->priv_queue);
|
||||||
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
||||||
mutex_unlock(&pm->lock);
|
mutex_unlock(&pm->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -482,7 +482,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
|
|||||||
BUG_ON(!pm);
|
BUG_ON(!pm);
|
||||||
|
|
||||||
mutex_lock(&pm->lock);
|
mutex_lock(&pm->lock);
|
||||||
retval = pm->priv_queue->acquire_packet_buffer(
|
retval = pm->priv_queue->ops.acquire_packet_buffer(
|
||||||
pm->priv_queue,
|
pm->priv_queue,
|
||||||
sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
|
sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
|
||||||
&buffer);
|
&buffer);
|
||||||
@@ -537,8 +537,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
pm->priv_queue->submit_packet(pm->priv_queue);
|
pm->priv_queue->ops.submit_packet(pm->priv_queue);
|
||||||
pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
pm->priv_queue->ops.sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
|
||||||
|
|
||||||
mutex_unlock(&pm->lock);
|
mutex_unlock(&pm->lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user