drm/amdgpu: add VCE VM session tracking
Fix the problems with killing VCE sessions in VM mode. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-and-Tested by: Leo Liu <leo.liu@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									45088efc85
								
							
						
					
					
						commit
						9861470181
					
				| @ -791,6 +791,96 @@ out: | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * amdgpu_vce_cs_parse_vm - parse the command stream in VM mode | ||||
|  * | ||||
|  * @p: parser context | ||||
|  * | ||||
|  */ | ||||
| int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx) | ||||
| { | ||||
| 	struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; | ||||
| 	int session_idx = -1; | ||||
| 	uint32_t destroyed = 0; | ||||
| 	uint32_t created = 0; | ||||
| 	uint32_t allocated = 0; | ||||
| 	uint32_t tmp, handle = 0; | ||||
| 	int i, r = 0, idx = 0; | ||||
| 
 | ||||
| 	while (idx < ib->length_dw) { | ||||
| 		uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); | ||||
| 		uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); | ||||
| 
 | ||||
| 		if ((len < 8) || (len & 3)) { | ||||
| 			DRM_ERROR("invalid VCE command length (%d)!\n", len); | ||||
| 			r = -EINVAL; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		switch (cmd) { | ||||
| 		case 0x00000001: /* session */ | ||||
| 			handle = amdgpu_get_ib_value(p, ib_idx, idx + 2); | ||||
| 			session_idx = amdgpu_vce_validate_handle(p, handle, | ||||
| 								 &allocated); | ||||
| 			if (session_idx < 0) { | ||||
| 				r = session_idx; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			break; | ||||
| 
 | ||||
| 		case 0x01000001: /* create */ | ||||
| 			created |= 1 << session_idx; | ||||
| 			if (destroyed & (1 << session_idx)) { | ||||
| 				destroyed &= ~(1 << session_idx); | ||||
| 				allocated |= 1 << session_idx; | ||||
| 
 | ||||
| 			} else if (!(allocated & (1 << session_idx))) { | ||||
| 				DRM_ERROR("Handle already in use!\n"); | ||||
| 				r = -EINVAL; | ||||
| 				goto out; | ||||
| 			} | ||||
| 
 | ||||
| 			break; | ||||
| 
 | ||||
| 		case 0x02000001: /* destroy */ | ||||
| 			destroyed |= 1 << session_idx; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (session_idx == -1) { | ||||
| 			DRM_ERROR("no session command at start of IB\n"); | ||||
| 			r = -EINVAL; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		idx += len / 4; | ||||
| 	} | ||||
| 
 | ||||
| 	if (allocated & ~created) { | ||||
| 		DRM_ERROR("New session without create command!\n"); | ||||
| 		r = -ENOENT; | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	if (!r) { | ||||
| 		/* No error, free all destroyed handle slots */ | ||||
| 		tmp = destroyed; | ||||
| 		amdgpu_ib_free(p->adev, ib, NULL); | ||||
| 	} else { | ||||
| 		/* Error during parsing, free all allocated handle slots */ | ||||
| 		tmp = allocated; | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i) | ||||
| 		if (tmp & (1 << i)) | ||||
| 			atomic_set(&p->adev->vce.handles[i], 0); | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * amdgpu_vce_ring_emit_ib - execute indirect buffer | ||||
|  * | ||||
|  | ||||
| @ -34,6 +34,7 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | ||||
| 			       bool direct, struct fence **fence); | ||||
| void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); | ||||
| int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); | ||||
| int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx); | ||||
| void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib, | ||||
| 			     unsigned vm_id, bool ctx_switch); | ||||
| void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, | ||||
|  | ||||
| @ -856,6 +856,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = { | ||||
| 	.get_rptr = vce_v3_0_ring_get_rptr, | ||||
| 	.get_wptr = vce_v3_0_ring_get_wptr, | ||||
| 	.set_wptr = vce_v3_0_ring_set_wptr, | ||||
| 	.parse_cs = amdgpu_vce_ring_parse_cs_vm, | ||||
| 	.emit_frame_size = | ||||
| 		6 + /* vce_v3_0_emit_vm_flush */ | ||||
| 		4 + /* vce_v3_0_emit_pipeline_sync */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user