linux/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
<<
>>
Prefs
   1/*
   2 * Copyright 2017 Valve Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: Andres Rodriguez <andresx7@gmail.com>
  23 */
  24
  25#include <linux/fdtable.h>
  26#include <linux/file.h>
  27#include <linux/pid.h>
  28
  29#include <drm/amdgpu_drm.h>
  30
  31#include "amdgpu.h"
  32
  33#include "amdgpu_vm.h"
  34
  35enum drm_sched_priority amdgpu_to_sched_priority(int amdgpu_priority)
  36{
  37        switch (amdgpu_priority) {
  38        case AMDGPU_CTX_PRIORITY_VERY_HIGH:
  39                return DRM_SCHED_PRIORITY_HIGH_HW;
  40        case AMDGPU_CTX_PRIORITY_HIGH:
  41                return DRM_SCHED_PRIORITY_HIGH_SW;
  42        case AMDGPU_CTX_PRIORITY_NORMAL:
  43                return DRM_SCHED_PRIORITY_NORMAL;
  44        case AMDGPU_CTX_PRIORITY_LOW:
  45        case AMDGPU_CTX_PRIORITY_VERY_LOW:
  46                return DRM_SCHED_PRIORITY_LOW;
  47        case AMDGPU_CTX_PRIORITY_UNSET:
  48                return DRM_SCHED_PRIORITY_UNSET;
  49        default:
  50                WARN(1, "Invalid context priority %d\n", amdgpu_priority);
  51                return DRM_SCHED_PRIORITY_INVALID;
  52        }
  53}
  54
  55static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
  56                                                  int fd,
  57                                                  enum drm_sched_priority priority)
  58{
  59        struct fd f = fdget(fd);
  60        struct amdgpu_fpriv *fpriv;
  61        struct amdgpu_ctx *ctx;
  62        uint32_t id;
  63        int r;
  64
  65        if (!f.file)
  66                return -EINVAL;
  67
  68        r = amdgpu_file_to_fpriv(f.file, &fpriv);
  69        if (r) {
  70                fdput(f);
  71                return r;
  72        }
  73
  74        idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
  75                amdgpu_ctx_priority_override(ctx, priority);
  76
  77        fdput(f);
  78        return 0;
  79}
  80
  81static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
  82                                                  int fd,
  83                                                  unsigned ctx_id,
  84                                                  enum drm_sched_priority priority)
  85{
  86        struct fd f = fdget(fd);
  87        struct amdgpu_fpriv *fpriv;
  88        struct amdgpu_ctx *ctx;
  89        int r;
  90
  91        if (!f.file)
  92                return -EINVAL;
  93
  94        r = amdgpu_file_to_fpriv(f.file, &fpriv);
  95        if (r) {
  96                fdput(f);
  97                return r;
  98        }
  99
 100        ctx = amdgpu_ctx_get(fpriv, ctx_id);
 101
 102        if (!ctx) {
 103                fdput(f);
 104                return -EINVAL;
 105        }
 106
 107        amdgpu_ctx_priority_override(ctx, priority);
 108        amdgpu_ctx_put(ctx);
 109        fdput(f);
 110
 111        return 0;
 112}
 113
 114int amdgpu_sched_ioctl(struct drm_device *dev, void *data,
 115                       struct drm_file *filp)
 116{
 117        union drm_amdgpu_sched *args = data;
 118        struct amdgpu_device *adev = dev->dev_private;
 119        enum drm_sched_priority priority;
 120        int r;
 121
 122        priority = amdgpu_to_sched_priority(args->in.priority);
 123        if (priority == DRM_SCHED_PRIORITY_INVALID)
 124                return -EINVAL;
 125
 126        switch (args->in.op) {
 127        case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
 128                r = amdgpu_sched_process_priority_override(adev,
 129                                                           args->in.fd,
 130                                                           priority);
 131                break;
 132        case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE:
 133                r = amdgpu_sched_context_priority_override(adev,
 134                                                           args->in.fd,
 135                                                           args->in.ctx_id,
 136                                                           priority);
 137                break;
 138        default:
 139                DRM_ERROR("Invalid sched op specified: %d\n", args->in.op);
 140                r = -EINVAL;
 141                break;
 142        }
 143
 144        return r;
 145}
 146