hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
....@@ -23,51 +23,102 @@
2323 */
2424
2525 #include <linux/fdtable.h>
26
+#include <linux/file.h>
2627 #include <linux/pid.h>
28
+
2729 #include <drm/amdgpu_drm.h>
30
+
2831 #include "amdgpu.h"
2932
3033 #include "amdgpu_vm.h"
3134
32
-enum drm_sched_priority amdgpu_to_sched_priority(int amdgpu_priority)
35
+int amdgpu_to_sched_priority(int amdgpu_priority,
36
+ enum drm_sched_priority *prio)
3337 {
3438 switch (amdgpu_priority) {
3539 case AMDGPU_CTX_PRIORITY_VERY_HIGH:
36
- return DRM_SCHED_PRIORITY_HIGH_HW;
40
+ *prio = DRM_SCHED_PRIORITY_HIGH;
41
+ break;
3742 case AMDGPU_CTX_PRIORITY_HIGH:
38
- return DRM_SCHED_PRIORITY_HIGH_SW;
43
+ *prio = DRM_SCHED_PRIORITY_HIGH;
44
+ break;
3945 case AMDGPU_CTX_PRIORITY_NORMAL:
40
- return DRM_SCHED_PRIORITY_NORMAL;
46
+ *prio = DRM_SCHED_PRIORITY_NORMAL;
47
+ break;
4148 case AMDGPU_CTX_PRIORITY_LOW:
4249 case AMDGPU_CTX_PRIORITY_VERY_LOW:
43
- return DRM_SCHED_PRIORITY_LOW;
50
+ *prio = DRM_SCHED_PRIORITY_MIN;
51
+ break;
4452 case AMDGPU_CTX_PRIORITY_UNSET:
45
- return DRM_SCHED_PRIORITY_UNSET;
53
+ *prio = DRM_SCHED_PRIORITY_UNSET;
54
+ break;
4655 default:
4756 WARN(1, "Invalid context priority %d\n", amdgpu_priority);
48
- return DRM_SCHED_PRIORITY_INVALID;
57
+ return -EINVAL;
4958 }
59
+
60
+ return 0;
5061 }
5162
5263 static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
5364 int fd,
5465 enum drm_sched_priority priority)
5566 {
56
- struct file *filp = fget(fd);
57
- struct drm_file *file;
67
+ struct fd f = fdget(fd);
5868 struct amdgpu_fpriv *fpriv;
69
+ struct amdgpu_ctx_mgr *mgr;
5970 struct amdgpu_ctx *ctx;
6071 uint32_t id;
72
+ int r;
6173
62
- if (!filp)
74
+ if (!f.file)
6375 return -EINVAL;
6476
65
- file = filp->private_data;
66
- fpriv = file->driver_priv;
67
- idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
68
- amdgpu_ctx_priority_override(ctx, priority);
77
+ r = amdgpu_file_to_fpriv(f.file, &fpriv);
78
+ if (r) {
79
+ fdput(f);
80
+ return r;
81
+ }
6982
70
- fput(filp);
83
+ mgr = &fpriv->ctx_mgr;
84
+ mutex_lock(&mgr->lock);
85
+ idr_for_each_entry(&mgr->ctx_handles, ctx, id)
86
+ amdgpu_ctx_priority_override(ctx, priority);
87
+ mutex_unlock(&mgr->lock);
88
+
89
+ fdput(f);
90
+ return 0;
91
+}
92
+
93
+static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
94
+ int fd,
95
+ unsigned ctx_id,
96
+ enum drm_sched_priority priority)
97
+{
98
+ struct fd f = fdget(fd);
99
+ struct amdgpu_fpriv *fpriv;
100
+ struct amdgpu_ctx *ctx;
101
+ int r;
102
+
103
+ if (!f.file)
104
+ return -EINVAL;
105
+
106
+ r = amdgpu_file_to_fpriv(f.file, &fpriv);
107
+ if (r) {
108
+ fdput(f);
109
+ return r;
110
+ }
111
+
112
+ ctx = amdgpu_ctx_get(fpriv, ctx_id);
113
+
114
+ if (!ctx) {
115
+ fdput(f);
116
+ return -EINVAL;
117
+ }
118
+
119
+ amdgpu_ctx_priority_override(ctx, priority);
120
+ amdgpu_ctx_put(ctx);
121
+ fdput(f);
71122
72123 return 0;
73124 }
....@@ -76,13 +127,24 @@
76127 struct drm_file *filp)
77128 {
78129 union drm_amdgpu_sched *args = data;
79
- struct amdgpu_device *adev = dev->dev_private;
130
+ struct amdgpu_device *adev = drm_to_adev(dev);
80131 enum drm_sched_priority priority;
81132 int r;
82133
83
- priority = amdgpu_to_sched_priority(args->in.priority);
84
- if (args->in.flags || priority == DRM_SCHED_PRIORITY_INVALID)
134
+ /* First check the op, then the op's argument.
135
+ */
136
+ switch (args->in.op) {
137
+ case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
138
+ case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE:
139
+ break;
140
+ default:
141
+ DRM_ERROR("Invalid sched op specified: %d\n", args->in.op);
85142 return -EINVAL;
143
+ }
144
+
145
+ r = amdgpu_to_sched_priority(args->in.priority, &priority);
146
+ if (r)
147
+ return r;
86148
87149 switch (args->in.op) {
88150 case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
....@@ -90,8 +152,15 @@
90152 args->in.fd,
91153 priority);
92154 break;
155
+ case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE:
156
+ r = amdgpu_sched_context_priority_override(adev,
157
+ args->in.fd,
158
+ args->in.ctx_id,
159
+ priority);
160
+ break;
93161 default:
94
- DRM_ERROR("Invalid sched op specified: %d\n", args->in.op);
162
+ /* Impossible.
163
+ */
95164 r = -EINVAL;
96165 break;
97166 }