Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: validate userq va for GEM unmap

When a user unmaps a userq VA, the driver must ensure
the queue has no in-flight jobs. If there is pending work,
the kernel should wait for the attached eviction (bookkeeping)
fence to signal before deleting the mapping.

Suggested-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Prike Liang and committed by
Alex Deucher
2e7ceac0 89926812

+46
+31
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 1195 1195 mutex_unlock(&adev->userq_mutex); 1196 1196 return ret; 1197 1197 } 1198 + 1199 + int amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev, 1200 + struct amdgpu_bo_va_mapping *mapping, 1201 + uint64_t saddr) 1202 + { 1203 + u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev); 1204 + struct amdgpu_bo_va *bo_va = mapping->bo_va; 1205 + struct dma_resv *resv = bo_va->base.bo->tbo.base.resv; 1206 + int ret = 0; 1207 + 1208 + if (!ip_mask) 1209 + return 0; 1210 + 1211 + dev_warn_once(adev->dev, "now unmapping a vital queue va:%llx\n", saddr); 1212 + /** 1213 + * The userq VA mapping reservation should include the eviction fence, 1214 + * if the eviction fence can't signal successfully during unmapping, 1215 + * then driver will warn to flag this improper unmap of the userq VA. 1216 + * Note: The eviction fence may be attached to different BOs, and this 1217 + * unmap is only for one kind of userq VAs, so at this point suppose 1218 + * the eviction fence is always unsignaled. 1219 + */ 1220 + if (!dma_resv_test_signaled(resv, DMA_RESV_USAGE_BOOKKEEP)) { 1221 + ret = dma_resv_wait_timeout(resv, DMA_RESV_USAGE_BOOKKEEP, true, 1222 + MAX_SCHEDULE_TIMEOUT); 1223 + if (ret <= 0) 1224 + return -EBUSY; 1225 + } 1226 + 1227 + return 0; 1228 + }
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
··· 146 146 u32 idx); 147 147 int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, 148 148 u64 addr, u64 expected_size); 149 + int amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev, 150 + struct amdgpu_bo_va_mapping *mapping, 151 + uint64_t saddr); 149 152 #endif
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 1952 1952 struct amdgpu_bo_va_mapping *mapping; 1953 1953 struct amdgpu_vm *vm = bo_va->base.vm; 1954 1954 bool valid = true; 1955 + int r; 1955 1956 1956 1957 saddr /= AMDGPU_GPU_PAGE_SIZE; 1957 1958 ··· 1971 1970 1972 1971 if (&mapping->list == &bo_va->invalids) 1973 1972 return -ENOENT; 1973 + } 1974 + 1975 + /* It's unlikely to happen that the mapping userq hasn't been idled 1976 + * during user requests GEM unmap IOCTL except for forcing the unmap 1977 + * from user space. 1978 + */ 1979 + if (unlikely(atomic_read(&bo_va->userq_va_mapped) > 0)) { 1980 + r = amdgpu_userq_gem_va_unmap_validate(adev, mapping, saddr); 1981 + if (unlikely(r == -EBUSY)) 1982 + dev_warn_once(adev->dev, 1983 + "Attempt to unmap an active userq buffer\n"); 1974 1984 } 1975 1985 1976 1986 list_del(&mapping->list);