Commit d146c5a7 authored by Felix Kuehling's avatar Felix Kuehling Committed by Oded Gabbay

drm/amdkfd: Make sched_policy a per-device setting

Some dGPUs don't support HWS. Allow them to use a per-device
sched_policy that may be different from the global default.
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 3ee2d00c
...@@ -901,7 +901,8 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep, ...@@ -901,7 +901,8 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
mutex_unlock(&p->mutex); mutex_unlock(&p->mutex);
if (sched_policy == KFD_SCHED_POLICY_NO_HWS && pdd->qpd.vmid != 0) if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS &&
pdd->qpd.vmid != 0)
dev->kfd2kgd->set_scratch_backing_va( dev->kfd2kgd->set_scratch_backing_va(
dev->kgd, args->va_addr, pdd->qpd.vmid); dev->kgd, args->va_addr, pdd->qpd.vmid);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "kfd_pm4_headers_diq.h" #include "kfd_pm4_headers_diq.h"
#include "kfd_dbgmgr.h" #include "kfd_dbgmgr.h"
#include "kfd_dbgdev.h" #include "kfd_dbgdev.h"
#include "kfd_device_queue_manager.h"
static DEFINE_MUTEX(kfd_dbgmgr_mutex); static DEFINE_MUTEX(kfd_dbgmgr_mutex);
...@@ -83,7 +84,7 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev) ...@@ -83,7 +84,7 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
} }
/* get actual type of DBGDevice cpsch or not */ /* get actual type of DBGDevice cpsch or not */
if (sched_policy == KFD_SCHED_POLICY_NO_HWS) if (pdev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
type = DBGDEV_TYPE_NODIQ; type = DBGDEV_TYPE_NODIQ;
kfd_dbgdev_init(new_buff->dbgdev, pdev, type); kfd_dbgdev_init(new_buff->dbgdev, pdev, type);
......
...@@ -340,7 +340,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, ...@@ -340,7 +340,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->pdev->device); kfd->pdev->device);
pr_debug("Starting kfd with the following scheduling policy %d\n", pr_debug("Starting kfd with the following scheduling policy %d\n",
sched_policy); kfd->dqm->sched_policy);
goto out; goto out;
......
...@@ -385,7 +385,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) ...@@ -385,7 +385,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
prev_active = q->properties.is_active; prev_active = q->properties.is_active;
/* Make sure the queue is unmapped before updating the MQD */ /* Make sure the queue is unmapped before updating the MQD */
if (sched_policy != KFD_SCHED_POLICY_NO_HWS) { if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) {
retval = unmap_queues_cpsch(dqm, retval = unmap_queues_cpsch(dqm,
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
if (retval) { if (retval) {
...@@ -417,7 +417,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) ...@@ -417,7 +417,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
else if (!q->properties.is_active && prev_active) else if (!q->properties.is_active && prev_active)
dqm->queue_count--; dqm->queue_count--;
if (sched_policy != KFD_SCHED_POLICY_NO_HWS) if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = map_queues_cpsch(dqm); retval = map_queues_cpsch(dqm);
else if (q->properties.is_active && else if (q->properties.is_active &&
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE || (q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
...@@ -1097,7 +1097,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, ...@@ -1097,7 +1097,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
alternate_aperture_base, alternate_aperture_base,
alternate_aperture_size); alternate_aperture_size);
if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0)) if ((dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0))
program_sh_mem_settings(dqm, qpd); program_sh_mem_settings(dqm, qpd);
pr_debug("sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n", pr_debug("sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
...@@ -1242,8 +1242,24 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) ...@@ -1242,8 +1242,24 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
if (!dqm) if (!dqm)
return NULL; return NULL;
switch (dev->device_info->asic_family) {
/* HWS is not available on Hawaii. */
case CHIP_HAWAII:
/* HWS depends on CWSR for timely dequeue. CWSR is not
* available on Tonga.
*
* FIXME: This argument also applies to Kaveri.
*/
case CHIP_TONGA:
dqm->sched_policy = KFD_SCHED_POLICY_NO_HWS;
break;
default:
dqm->sched_policy = sched_policy;
break;
}
dqm->dev = dev; dqm->dev = dev;
switch (sched_policy) { switch (dqm->sched_policy) {
case KFD_SCHED_POLICY_HWS: case KFD_SCHED_POLICY_HWS:
case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION: case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION:
/* initialize dqm for cp scheduling */ /* initialize dqm for cp scheduling */
...@@ -1280,7 +1296,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) ...@@ -1280,7 +1296,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
dqm->ops.process_termination = process_termination_nocpsch; dqm->ops.process_termination = process_termination_nocpsch;
break; break;
default: default:
pr_err("Invalid scheduling policy %d\n", sched_policy); pr_err("Invalid scheduling policy %d\n", dqm->sched_policy);
goto out_free; goto out_free;
} }
......
...@@ -180,6 +180,7 @@ struct device_queue_manager { ...@@ -180,6 +180,7 @@ struct device_queue_manager {
unsigned int *fence_addr; unsigned int *fence_addr;
struct kfd_mem_obj *fence_mem; struct kfd_mem_obj *fence_mem;
bool active_runlist; bool active_runlist;
int sched_policy;
}; };
void device_queue_manager_init_cik( void device_queue_manager_init_cik(
......
...@@ -208,7 +208,8 @@ int pqm_create_queue(struct process_queue_manager *pqm, ...@@ -208,7 +208,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
case KFD_QUEUE_TYPE_COMPUTE: case KFD_QUEUE_TYPE_COMPUTE:
/* check if there is over subscription */ /* check if there is over subscription */
if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && if ((dev->dqm->sched_policy ==
KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
((dev->dqm->processes_count >= dev->vm_info.vmid_num_kfd) || ((dev->dqm->processes_count >= dev->vm_info.vmid_num_kfd) ||
(dev->dqm->queue_count >= get_queues_num(dev->dqm)))) { (dev->dqm->queue_count >= get_queues_num(dev->dqm)))) {
pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n"); pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
......
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