diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 75c933b1a432..52388b1b52c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -23,13 +23,40 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include <drm/drm_auth.h> | ||
26 | #include "amdgpu.h" | 27 | #include "amdgpu.h" |
27 | 28 | ||
28 | static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) | 29 | static int amdgpu_ctx_priority_permit(struct drm_file *filp, |
30 | enum amd_sched_priority priority) | ||
31 | { | ||
32 | /* NORMAL and below are accessible by everyone */ | ||
33 | if (priority <= AMD_SCHED_PRIORITY_NORMAL) | ||
34 | return 0; | ||
35 | |||
36 | if (capable(CAP_SYS_NICE)) | ||
37 | return 0; | ||
38 | |||
39 | if (drm_is_current_master(filp)) | ||
40 | return 0; | ||
41 | |||
42 | return -EACCES; | ||
43 | } | ||
44 | |||
45 | static int amdgpu_ctx_init(struct amdgpu_device *adev, | ||
46 | enum amd_sched_priority priority, | ||
47 | struct drm_file *filp, | ||
48 | struct amdgpu_ctx *ctx) | ||
29 | { | 49 | { |
30 | unsigned i, j; | 50 | unsigned i, j; |
31 | int r; | 51 | int r; |
32 | 52 | ||
53 | if (priority < 0 || priority >= AMD_SCHED_PRIORITY_MAX) | ||
54 | return -EINVAL; | ||
55 | |||
56 | r = amdgpu_ctx_priority_permit(filp, priority); | ||
57 | if (r) | ||
58 | return r; | ||
59 | |||
33 | memset(ctx, 0, sizeof(*ctx)); | 60 | memset(ctx, 0, sizeof(*ctx)); |
34 | ctx->adev = adev; | 61 | ctx->adev = adev; |
35 | kref_init(&ctx->refcount); | 62 | kref_init(&ctx->refcount); |
@@ -51,7 +78,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) | |||
51 | struct amdgpu_ring *ring = adev->rings[i]; | 78 | struct amdgpu_ring *ring = adev->rings[i]; |
52 | struct amd_sched_rq *rq; | 79 | struct amd_sched_rq *rq; |
53 | 80 | ||
54 | rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; | 81 | rq = &ring->sched.sched_rq[priority]; |
55 | 82 | ||
56 | if (ring == &adev->gfx.kiq.ring) | 83 | if (ring == &adev->gfx.kiq.ring) |
57 | continue; | 84 | continue; |
@@ -100,6 +127,8 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) | |||
100 | 127 | ||
101 | static int amdgpu_ctx_alloc(struct amdgpu_device *adev, | 128 | static int amdgpu_ctx_alloc(struct amdgpu_device *adev, |
102 | struct amdgpu_fpriv *fpriv, | 129 | struct amdgpu_fpriv *fpriv, |
130 | struct drm_file *filp, | ||
131 | enum amd_sched_priority priority, | ||
103 | uint32_t *id) | 132 | uint32_t *id) |
104 | { | 133 | { |
105 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | 134 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; |
@@ -117,8 +146,9 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, | |||
117 | kfree(ctx); | 146 | kfree(ctx); |
118 | return r; | 147 | return r; |
119 | } | 148 | } |
149 | |||
120 | *id = (uint32_t)r; | 150 | *id = (uint32_t)r; |
121 | r = amdgpu_ctx_init(adev, ctx); | 151 | r = amdgpu_ctx_init(adev, priority, filp, ctx); |
122 | if (r) { | 152 | if (r) { |
123 | idr_remove(&mgr->ctx_handles, *id); | 153 | idr_remove(&mgr->ctx_handles, *id); |
124 | *id = 0; | 154 | *id = 0; |
@@ -188,11 +218,30 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev, | |||
188 | return 0; | 218 | return 0; |
189 | } | 219 | } |
190 | 220 | ||
221 | static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) | ||
222 | { | ||
223 | switch (amdgpu_priority) { | ||
224 | case AMDGPU_CTX_PRIORITY_HIGH_HW: | ||
225 | return AMD_SCHED_PRIORITY_HIGH_HW; | ||
226 | case AMDGPU_CTX_PRIORITY_HIGH_SW: | ||
227 | return AMD_SCHED_PRIORITY_HIGH_SW; | ||
228 | case AMDGPU_CTX_PRIORITY_NORMAL: | ||
229 | return AMD_SCHED_PRIORITY_NORMAL; | ||
230 | case AMDGPU_CTX_PRIORITY_LOW_SW: | ||
231 | case AMDGPU_CTX_PRIORITY_LOW_HW: | ||
232 | return AMD_SCHED_PRIORITY_LOW; | ||
233 | default: | ||
234 | WARN(1, "Invalid context priority %d\n", amdgpu_priority); | ||
235 | return AMD_SCHED_PRIORITY_NORMAL; | ||
236 | } | ||
237 | } | ||
238 | |||
191 | int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | 239 | int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, |
192 | struct drm_file *filp) | 240 | struct drm_file *filp) |
193 | { | 241 | { |
194 | int r; | 242 | int r; |
195 | uint32_t id; | 243 | uint32_t id; |
244 | enum amd_sched_priority priority; | ||
196 | 245 | ||
197 | union drm_amdgpu_ctx *args = data; | 246 | union drm_amdgpu_ctx *args = data; |
198 | struct amdgpu_device *adev = dev->dev_private; | 247 | struct amdgpu_device *adev = dev->dev_private; |
@@ -200,10 +249,14 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | |||
200 | 249 | ||
201 | r = 0; | 250 | r = 0; |
202 | id = args->in.ctx_id; | 251 | id = args->in.ctx_id; |
252 | priority = amdgpu_to_sched_priority(args->in.priority); | ||
253 | |||
254 | if (priority >= AMD_SCHED_PRIORITY_MAX) | ||
255 | return -EINVAL; | ||
203 | 256 | ||
204 | switch (args->in.op) { | 257 | switch (args->in.op) { |
205 | case AMDGPU_CTX_OP_ALLOC_CTX: | 258 | case AMDGPU_CTX_OP_ALLOC_CTX: |
206 | r = amdgpu_ctx_alloc(adev, fpriv, &id); | 259 | r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id); |
207 | args->out.alloc.ctx_id = id; | 260 | args->out.alloc.ctx_id = id; |
208 | break; | 261 | break; |
209 | case AMDGPU_CTX_OP_FREE_CTX: | 262 | case AMDGPU_CTX_OP_FREE_CTX: |