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