amdkfd: Implement the Set Memory Policy IOCTL
authorAndrew Lewycky <Andrew.Lewycky@amd.com>
Wed, 16 Jul 2014 22:46:17 +0000 (01:46 +0300)
committerOded Gabbay <oded.gabbay@amd.com>
Wed, 16 Jul 2014 22:46:17 +0000 (01:46 +0300)
Signed-off-by: Andrew Lewycky <Andrew.Lewycky@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

index d342035..1020faf 100644 (file)
@@ -35,6 +35,7 @@
 #include <uapi/asm-generic/mman-common.h>
 #include <asm/processor.h>
 #include "kfd_priv.h"
+#include "kfd_device_queue_manager.h"
 
 static long kfd_ioctl(struct file *, unsigned int, unsigned long);
 static int kfd_open(struct inode *, struct file *);
@@ -345,7 +346,56 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
 static long kfd_ioctl_set_memory_policy(struct file *filep,
                                struct kfd_process *p, void __user *arg)
 {
-       return -ENODEV;
+       struct kfd_ioctl_set_memory_policy_args args;
+       struct kfd_dev *dev;
+       int err = 0;
+       struct kfd_process_device *pdd;
+       enum cache_policy default_policy, alternate_policy;
+
+       if (copy_from_user(&args, arg, sizeof(args)))
+               return -EFAULT;
+
+       if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
+           && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
+               return -EINVAL;
+       }
+
+       if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
+           && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
+               return -EINVAL;
+       }
+
+       dev = kfd_device_by_id(args.gpu_id);
+       if (dev == NULL)
+               return -EINVAL;
+
+       mutex_lock(&p->mutex);
+
+       pdd = kfd_bind_process_to_device(dev, p);
+       if (IS_ERR(pdd) < 0) {
+               err = PTR_ERR(pdd);
+               goto out;
+       }
+
+       default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
+                        ? cache_policy_coherent : cache_policy_noncoherent;
+
+       alternate_policy =
+               (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
+                  ? cache_policy_coherent : cache_policy_noncoherent;
+
+       if (!dev->dqm->set_cache_memory_policy(dev->dqm,
+                               &pdd->qpd,
+                               default_policy,
+                               alternate_policy,
+                               (void __user *)args.alternate_aperture_base,
+                               args.alternate_aperture_size))
+               err = -EINVAL;
+
+out:
+       mutex_unlock(&p->mutex);
+
+       return err;
 }
 
 static long kfd_ioctl_get_clock_counters(struct file *filep,