drm/amdkfd: Make sched_policy a per-device setting
authorFelix Kuehling <Felix.Kuehling@amd.com>
Thu, 4 Jan 2018 22:17:43 +0000 (17:17 -0500)
committerOded Gabbay <oded.gabbay@gmail.com>
Thu, 4 Jan 2018 22:17:43 +0000 (17:17 -0500)
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: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

index 62c3d9cd6ef18807e754fa100f3f35c63b873a4d..6fe24964540b4480be764392f3409e8dcec9e9fe 100644 (file)
@@ -901,7 +901,8 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
 
        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->kgd, args->va_addr, pdd->qpd.vmid);
 
index 3da25f7bda6ba58ca77d0e15816fb194634eec68..9d4af961c5d1f2d1b106585332c257e0d79deacf 100644 (file)
@@ -33,6 +33,7 @@
 #include "kfd_pm4_headers_diq.h"
 #include "kfd_dbgmgr.h"
 #include "kfd_dbgdev.h"
+#include "kfd_device_queue_manager.h"
 
 static DEFINE_MUTEX(kfd_dbgmgr_mutex);
 
@@ -83,7 +84,7 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
        }
 
        /* 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;
 
        kfd_dbgdev_init(new_buff->dbgdev, pdev, type);
index fafe971d1d49daaf38a3d354b671ef84a2c479be..e8ff4eab63e737080715476d68b36a95f917ea73 100644 (file)
@@ -340,7 +340,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
                 kfd->pdev->device);
 
        pr_debug("Starting kfd with the following scheduling policy %d\n",
-               sched_policy);
+               kfd->dqm->sched_policy);
 
        goto out;
 
index b21285afa4eac19f243ba1c22b3a486e1828eeae..e57781d99664c452a3a6f9193b73e0c45e84eb16 100644 (file)
@@ -385,7 +385,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
        prev_active = q->properties.is_active;
 
        /* 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,
                                KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
                if (retval) {
@@ -417,7 +417,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
        else if (!q->properties.is_active && prev_active)
                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);
        else if (q->properties.is_active &&
                 (q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
@@ -1097,7 +1097,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
                        alternate_aperture_base,
                        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);
 
        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)
        if (!dqm)
                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;
-       switch (sched_policy) {
+       switch (dqm->sched_policy) {
        case KFD_SCHED_POLICY_HWS:
        case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION:
                /* initialize dqm for cp scheduling */
@@ -1280,7 +1296,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
                dqm->ops.process_termination = process_termination_nocpsch;
                break;
        default:
-               pr_err("Invalid scheduling policy %d\n", sched_policy);
+               pr_err("Invalid scheduling policy %d\n", dqm->sched_policy);
                goto out_free;
        }
 
index c61b693bfa8c3a6aac0af58e5c45bff4d9a3cc42..9fdc9c2a107a2b88586915c812fe8bc4386b38d8 100644 (file)
@@ -180,6 +180,7 @@ struct device_queue_manager {
        unsigned int            *fence_addr;
        struct kfd_mem_obj      *fence_mem;
        bool                    active_runlist;
+       int                     sched_policy;
 };
 
 void device_queue_manager_init_cik(
index 8763806326682c4c059359ef0b44dc9855e88ef5..7817e327ea6ddbf24e73d2c6dbc018566af139d0 100644 (file)
@@ -208,7 +208,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
 
        case KFD_QUEUE_TYPE_COMPUTE:
                /* 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->queue_count >= get_queues_num(dev->dqm)))) {
                        pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");