It is required to support fence per context. v2: add amdgpu_ctx_get/put v3: improve get/put v4: squash hlock fix
Unified · Split
| @@ -1902,6 +1902,8 @@ int amdgpu_ctx_query(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, · 1901 unmodified lines | ||
| 1902 | 1902 | uint32_t id,struct amdgpu_ctx_state *state); |
| 1903 | 1903 | |
| 1904 | 1904 | void amdgpu_ctx_fini(struct amdgpu_fpriv *fpriv); |
| 1905 | +struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); | |
| 1906 | +int amdgpu_ctx_put(struct amdgpu_ctx *ctx); | |
| 1905 | 1907 | |
| 1906 | 1908 | extern int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, |
| 1907 | 1909 | struct drm_file *filp); |
| @@ -768,8 +768,13 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, · 767 unmodified lines | ||
| 768 | 768 | uint64_t seq[AMDGPU_MAX_RINGS] = {0}; |
| 769 | 769 | struct amdgpu_ring *ring = NULL; |
| 770 | 770 | unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout); |
| 771 | + struct amdgpu_ctx *ctx; | |
| 771 | 772 | long r; |
| 772 | 773 | |
| 774 | + ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); | |
| 775 | + if (ctx == NULL) | |
| 776 | + return -EINVAL; | |
| 777 | + | |
| 773 | 778 | r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance, |
| 774 | 779 | wait->in.ring, &ring); |
| 775 | 780 | if (r) |
| @@ -778,6 +783,7 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, · 2 unmodified lines | ||
| 778 | 783 | seq[ring->idx] = wait->in.handle; |
| 779 | 784 | |
| 780 | 785 | r = amdgpu_fence_wait_seq_timeout(adev, seq, true, timeout); |
| 786 | + amdgpu_ctx_put(ctx); | |
| 781 | 787 | if (r < 0) |
| 782 | 788 | return r; |
| 783 | 789 | |
| @@ -151,3 +151,33 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | return r; |
| 153 | 153 | } |
| 154 | + | |
| 155 | +struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id) | |
| 156 | +{ | |
| 157 | + struct amdgpu_ctx *ctx; | |
| 158 | + struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | |
| 159 | + | |
| 160 | + mutex_lock(&mgr->lock); | |
| 161 | + ctx = idr_find(&mgr->ctx_handles, id); | |
| 162 | + if (ctx) | |
| 163 | + kref_get(&ctx->refcount); | |
| 164 | + mutex_unlock(&mgr->lock); | |
| 165 | + return ctx; | |
| 166 | +} | |
| 167 | + | |
| 168 | +int amdgpu_ctx_put(struct amdgpu_ctx *ctx) | |
| 169 | +{ | |
| 170 | + struct amdgpu_fpriv *fpriv; | |
| 171 | + struct amdgpu_ctx_mgr *mgr; | |
| 172 | + | |
| 173 | + if (ctx == NULL) | |
| 174 | + return -EINVAL; | |
| 175 | + | |
| 176 | + fpriv = ctx->fpriv; | |
| 177 | + mgr = &fpriv->ctx_mgr; | |
| 178 | + mutex_lock(&mgr->lock); | |
| 179 | + kref_put(&ctx->refcount, amdgpu_ctx_do_release); | |
| 180 | + mutex_unlock(&mgr->lock); | |
| 181 | + | |
| 182 | + return 0; | |
| 183 | +} | |
| @@ -260,7 +260,7 @@ struct drm_amdgpu_wait_cs_in { · 259 unmodified lines | ||
| 260 | 260 | uint32_t ip_type; |
| 261 | 261 | uint32_t ip_instance; |
| 262 | 262 | uint32_t ring; |
| 263 | − uint32_t _pad; | |
| 263 | + uint32_t ctx_id; | |
| 264 | 264 | }; |
| 265 | 265 | |
| 266 | 266 | struct drm_amdgpu_wait_cs_out { |