drm/amdkfd: Add function to set queue gws
Add functions in process queue manager to set/unset queue gws. Also set process's number of gws used. Currently only one queue in process can use and use all gws. Signed-off-by: Oak Zeng <Oak.Zeng@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@ -455,6 +455,9 @@ struct queue_properties {
|
|||||||
*
|
*
|
||||||
* @device: The kfd device that created this queue.
|
* @device: The kfd device that created this queue.
|
||||||
*
|
*
|
||||||
|
* @gws: Pointing to gws kgd_mem if this is a gws control queue; NULL
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
* This structure represents user mode compute queues.
|
* This structure represents user mode compute queues.
|
||||||
* It contains all the necessary data to handle such queues.
|
* It contains all the necessary data to handle such queues.
|
||||||
*
|
*
|
||||||
@ -476,6 +479,7 @@ struct queue {
|
|||||||
|
|
||||||
struct kfd_process *process;
|
struct kfd_process *process;
|
||||||
struct kfd_dev *device;
|
struct kfd_dev *device;
|
||||||
|
void *gws;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -869,6 +873,8 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
|
|||||||
struct queue_properties *p);
|
struct queue_properties *p);
|
||||||
int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
|
int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
|
||||||
struct queue_properties *p);
|
struct queue_properties *p);
|
||||||
|
int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
|
||||||
|
void *gws);
|
||||||
struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
|
struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
|
||||||
unsigned int qid);
|
unsigned int qid);
|
||||||
int pqm_get_wave_state(struct process_queue_manager *pqm,
|
int pqm_get_wave_state(struct process_queue_manager *pqm,
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "kfd_device_queue_manager.h"
|
#include "kfd_device_queue_manager.h"
|
||||||
#include "kfd_priv.h"
|
#include "kfd_priv.h"
|
||||||
#include "kfd_kernel_queue.h"
|
#include "kfd_kernel_queue.h"
|
||||||
|
#include "amdgpu_amdkfd.h"
|
||||||
|
|
||||||
static inline struct process_queue_node *get_queue_by_qid(
|
static inline struct process_queue_node *get_queue_by_qid(
|
||||||
struct process_queue_manager *pqm, unsigned int qid)
|
struct process_queue_manager *pqm, unsigned int qid)
|
||||||
@ -74,6 +75,55 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
|
|||||||
pdd->already_dequeued = true;
|
pdd->already_dequeued = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
|
||||||
|
void *gws)
|
||||||
|
{
|
||||||
|
struct kfd_dev *dev = NULL;
|
||||||
|
struct process_queue_node *pqn;
|
||||||
|
struct kfd_process_device *pdd;
|
||||||
|
struct kgd_mem *mem = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pqn = get_queue_by_qid(pqm, qid);
|
||||||
|
if (!pqn) {
|
||||||
|
pr_err("Queue id does not match any known queue\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pqn->q)
|
||||||
|
dev = pqn->q->device;
|
||||||
|
if (WARN_ON(!dev))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
pdd = kfd_get_process_device_data(dev, pqm->process);
|
||||||
|
if (!pdd) {
|
||||||
|
pr_err("Process device data doesn't exist\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only allow one queue per process can have GWS assigned */
|
||||||
|
if (gws && pdd->qpd.num_gws)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!gws && pdd->qpd.num_gws == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (gws)
|
||||||
|
ret = amdgpu_amdkfd_add_gws_to_process(pdd->process->kgd_process_info,
|
||||||
|
gws, &mem);
|
||||||
|
else
|
||||||
|
ret = amdgpu_amdkfd_remove_gws_from_process(pdd->process->kgd_process_info,
|
||||||
|
pqn->q->gws);
|
||||||
|
if (unlikely(ret))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
pqn->q->gws = mem;
|
||||||
|
pdd->qpd.num_gws = gws ? amdgpu_amdkfd_get_num_gws(dev->kgd) : 0;
|
||||||
|
|
||||||
|
return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
|
||||||
|
pqn->q);
|
||||||
|
}
|
||||||
|
|
||||||
void kfd_process_dequeue_from_all_devices(struct kfd_process *p)
|
void kfd_process_dequeue_from_all_devices(struct kfd_process *p)
|
||||||
{
|
{
|
||||||
struct kfd_process_device *pdd;
|
struct kfd_process_device *pdd;
|
||||||
@ -330,6 +380,13 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
|
|||||||
if (retval != -ETIME)
|
if (retval != -ETIME)
|
||||||
goto err_destroy_queue;
|
goto err_destroy_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pqn->q->gws) {
|
||||||
|
amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info,
|
||||||
|
pqn->q->gws);
|
||||||
|
pdd->qpd.num_gws = 0;
|
||||||
|
}
|
||||||
|
|
||||||
kfree(pqn->q->properties.cu_mask);
|
kfree(pqn->q->properties.cu_mask);
|
||||||
pqn->q->properties.cu_mask = NULL;
|
pqn->q->properties.cu_mask = NULL;
|
||||||
uninit_queue(pqn->q);
|
uninit_queue(pqn->q);
|
||||||
|
Reference in New Issue
Block a user