@@ -241,22 +241,83 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state,
241241 if (!state_bo -> data )
242242 goto out ;
243243
244- msm_gem_lock (obj );
245244 ptr = msm_gem_get_vaddr_active (obj );
246- msm_gem_unlock (obj );
247245 if (IS_ERR (ptr )) {
248246 kvfree (state_bo -> data );
249247 state_bo -> data = NULL ;
250248 goto out ;
251249 }
252250
253251 memcpy (state_bo -> data , ptr + offset , size );
254- msm_gem_put_vaddr (obj );
252+ msm_gem_put_vaddr_locked (obj );
255253 }
256254out :
257255 state -> nr_bos ++ ;
258256}
259257
258+ static void crashstate_get_bos (struct msm_gpu_state * state , struct msm_gem_submit * submit )
259+ {
260+ extern bool rd_full ;
261+
262+ if (!submit )
263+ return ;
264+
265+ if (msm_context_is_vmbind (submit -> queue -> ctx )) {
266+ struct drm_exec exec ;
267+ struct drm_gpuva * vma ;
268+ unsigned cnt = 0 ;
269+
270+ drm_exec_init (& exec , DRM_EXEC_IGNORE_DUPLICATES , 0 );
271+ drm_exec_until_all_locked (& exec ) {
272+ cnt = 0 ;
273+
274+ drm_exec_lock_obj (& exec , drm_gpuvm_resv_obj (submit -> vm ));
275+ drm_exec_retry_on_contention (& exec );
276+
277+ drm_gpuvm_for_each_va (vma , submit -> vm ) {
278+ if (!vma -> gem .obj )
279+ continue ;
280+
281+ cnt ++ ;
282+ drm_exec_lock_obj (& exec , vma -> gem .obj );
283+ drm_exec_retry_on_contention (& exec );
284+ }
285+
286+ }
287+
288+ drm_gpuvm_for_each_va (vma , submit -> vm )
289+ cnt ++ ;
290+
291+ state -> bos = kcalloc (cnt , sizeof (struct msm_gpu_state_bo ), GFP_KERNEL );
292+
293+ drm_gpuvm_for_each_va (vma , submit -> vm ) {
294+ bool dump = rd_full || (vma -> flags & MSM_VMA_DUMP );
295+
296+ /* Skip MAP_NULL/PRR VMAs: */
297+ if (!vma -> gem .obj )
298+ continue ;
299+
300+ msm_gpu_crashstate_get_bo (state , vma -> gem .obj , vma -> va .addr ,
301+ dump , vma -> gem .offset , vma -> va .range );
302+ }
303+
304+ drm_exec_fini (& exec );
305+ } else {
306+ state -> bos = kcalloc (submit -> nr_bos ,
307+ sizeof (struct msm_gpu_state_bo ), GFP_KERNEL );
308+
309+ for (int i = 0 ; state -> bos && i < submit -> nr_bos ; i ++ ) {
310+ struct drm_gem_object * obj = submit -> bos [i ].obj ;;
311+ bool dump = rd_full || (submit -> bos [i ].flags & MSM_SUBMIT_BO_DUMP );
312+
313+ msm_gem_lock (obj );
314+ msm_gpu_crashstate_get_bo (state , obj , submit -> bos [i ].iova ,
315+ dump , 0 , obj -> size );
316+ msm_gem_unlock (obj );
317+ }
318+ }
319+ }
320+
260321static void msm_gpu_crashstate_capture (struct msm_gpu * gpu ,
261322 struct msm_gem_submit * submit , struct msm_gpu_fault_info * fault_info ,
262323 char * comm , char * cmd )
@@ -281,30 +342,17 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
281342 if (fault_info )
282343 state -> fault_info = * fault_info ;
283344
284- if (submit ) {
285- extern bool rd_full ;
286- int i ;
287-
288- if (state -> fault_info .ttbr0 ) {
289- struct msm_gpu_fault_info * info = & state -> fault_info ;
290- struct msm_mmu * mmu = to_msm_vm (submit -> vm )-> mmu ;
345+ if (submit && state -> fault_info .ttbr0 ) {
346+ struct msm_gpu_fault_info * info = & state -> fault_info ;
347+ struct msm_mmu * mmu = to_msm_vm (submit -> vm )-> mmu ;
291348
292- msm_iommu_pagetable_params (mmu , & info -> pgtbl_ttbr0 ,
293- & info -> asid );
294- msm_iommu_pagetable_walk (mmu , info -> iova , info -> ptes );
295- }
296-
297- state -> bos = kcalloc (submit -> nr_bos ,
298- sizeof (struct msm_gpu_state_bo ), GFP_KERNEL );
299-
300- for (i = 0 ; state -> bos && i < submit -> nr_bos ; i ++ ) {
301- struct drm_gem_object * obj = submit -> bos [i ].obj ;
302- bool dump = rd_full || (submit -> bos [i ].flags & MSM_SUBMIT_BO_DUMP );
303- msm_gpu_crashstate_get_bo (state , obj , submit -> bos [i ].iova ,
304- dump , 0 , obj -> size );
305- }
349+ msm_iommu_pagetable_params (mmu , & info -> pgtbl_ttbr0 ,
350+ & info -> asid );
351+ msm_iommu_pagetable_walk (mmu , info -> iova , info -> ptes );
306352 }
307353
354+ crashstate_get_bos (state , submit );
355+
308356 /* Set the active crash state to be dumped on failure */
309357 gpu -> crashstate = state ;
310358
0 commit comments