aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
diff options
context:
space:
mode:
authorAndres Rodriguez <andresx7@gmail.com>2016-12-22 17:06:50 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-10-09 16:30:20 -0400
commitc2636dc53abd8269a0930bccd564f2f195dba729 (patch)
treee397399dbfcdf636586b82aa92be742fb7aaf739 /drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
parent177ae09b5d699a5ebd1cafcee78889db968abf54 (diff)
drm/amdgpu: add parameter to allocate high priority contexts v11
Add a new context creation parameter to express a global context priority. The priority ranking in descending order is as follows: * AMDGPU_CTX_PRIORITY_HIGH_HW * AMDGPU_CTX_PRIORITY_HIGH_SW * AMDGPU_CTX_PRIORITY_NORMAL * AMDGPU_CTX_PRIORITY_LOW_SW * AMDGPU_CTX_PRIORITY_LOW_HW The driver will attempt to schedule work to the hardware according to the priorities. No latency or throughput guarantees are provided by this patch. This interface intends to service the EGL_IMG_context_priority extension, and vulkan equivalents. Setting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER. v2: Instead of using flags, repurpose __pad v3: Swap enum values of _NORMAL _HIGH for backwards compatibility v4: Validate usermode priority and store it v5: Move priority validation into amdgpu_ctx_ioctl(), headline reword v6: add UAPI note regarding priorities requiring CAP_SYS_ADMIN v7: remove ctx->priority v8: added AMDGPU_CTX_PRIORITY_LOW, s/CAP_SYS_ADMIN/CAP_SYS_NICE v9: change the priority parameter to __s32 v10: split priorities into _SW and _HW v11: Allow DRM_MASTER without CAP_SYS_NICE Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c61
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
28static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) 29static 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
45static 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
101static int amdgpu_ctx_alloc(struct amdgpu_device *adev, 128static 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
221static 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
191int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, 239int 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: