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/pid.h> |
27 | #include <drm/amdgpu_drm.h> |
28 | #include "amdgpu.h" |
29 | |
30 | #include "amdgpu_vm.h" |
31 | |
32 | enum drm_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) |
33 | { |
34 | switch (amdgpu_priority) { |
35 | case AMDGPU_CTX_PRIORITY_VERY_HIGH: |
36 | return DRM_SCHED_PRIORITY_HIGH_HW; |
37 | case AMDGPU_CTX_PRIORITY_HIGH: |
38 | return DRM_SCHED_PRIORITY_HIGH_SW; |
39 | case AMDGPU_CTX_PRIORITY_NORMAL: |
40 | return DRM_SCHED_PRIORITY_NORMAL; |
41 | case AMDGPU_CTX_PRIORITY_LOW: |
42 | case AMDGPU_CTX_PRIORITY_VERY_LOW: |
43 | return DRM_SCHED_PRIORITY_LOW; |
44 | case AMDGPU_CTX_PRIORITY_UNSET: |
45 | return DRM_SCHED_PRIORITY_UNSET; |
46 | default: |
47 | WARN(1, "Invalid context priority %d\n" , amdgpu_priority); |
48 | return DRM_SCHED_PRIORITY_INVALID; |
49 | } |
50 | } |
51 | |
52 | static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, |
53 | int fd, |
54 | enum drm_sched_priority priority) |
55 | { |
56 | struct file *filp = fget(fd); |
57 | struct amdgpu_fpriv *fpriv; |
58 | struct amdgpu_ctx *ctx; |
59 | uint32_t id; |
60 | int r; |
61 | |
62 | if (!filp) |
63 | return -EINVAL; |
64 | |
65 | r = amdgpu_file_to_fpriv(filp, &fpriv); |
66 | if (r) { |
67 | fput(filp); |
68 | return r; |
69 | } |
70 | |
71 | idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) |
72 | amdgpu_ctx_priority_override(ctx, priority); |
73 | |
74 | fput(filp); |
75 | |
76 | return 0; |
77 | } |
78 | |
79 | static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev, |
80 | int fd, |
81 | unsigned ctx_id, |
82 | enum drm_sched_priority priority) |
83 | { |
84 | struct file *filp = fget(fd); |
85 | struct amdgpu_fpriv *fpriv; |
86 | struct amdgpu_ctx *ctx; |
87 | int r; |
88 | |
89 | if (!filp) |
90 | return -EINVAL; |
91 | |
92 | r = amdgpu_file_to_fpriv(filp, &fpriv); |
93 | if (r) { |
94 | fput(filp); |
95 | return r; |
96 | } |
97 | |
98 | ctx = amdgpu_ctx_get(fpriv, ctx_id); |
99 | |
100 | if (!ctx) { |
101 | fput(filp); |
102 | return -EINVAL; |
103 | } |
104 | |
105 | amdgpu_ctx_priority_override(ctx, priority); |
106 | amdgpu_ctx_put(ctx); |
107 | fput(filp); |
108 | |
109 | return 0; |
110 | } |
111 | |
112 | int amdgpu_sched_ioctl(struct drm_device *dev, void *data, |
113 | struct drm_file *filp) |
114 | { |
115 | union drm_amdgpu_sched *args = data; |
116 | struct amdgpu_device *adev = dev->dev_private; |
117 | enum drm_sched_priority priority; |
118 | int r; |
119 | |
120 | priority = amdgpu_to_sched_priority(args->in.priority); |
121 | if (priority == DRM_SCHED_PRIORITY_INVALID) |
122 | return -EINVAL; |
123 | |
124 | switch (args->in.op) { |
125 | case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE: |
126 | r = amdgpu_sched_process_priority_override(adev, |
127 | args->in.fd, |
128 | priority); |
129 | break; |
130 | case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE: |
131 | r = amdgpu_sched_context_priority_override(adev, |
132 | args->in.fd, |
133 | args->in.ctx_id, |
134 | priority); |
135 | break; |
136 | default: |
137 | DRM_ERROR("Invalid sched op specified: %d\n" , args->in.op); |
138 | r = -EINVAL; |
139 | break; |
140 | } |
141 | |
142 | return r; |
143 | } |
144 | |