@@ -214,7 +214,9 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
214214 struct drm_print_iterator iter ;
215215 struct amdgpu_vm_fault_info * fault_info ;
216216 struct amdgpu_ip_block * ip_block ;
217- int ver ;
217+ struct amdgpu_ring * ring ;
218+ int ver , i , j ;
219+ u32 ring_idx , off ;
218220
219221 iter .data = buffer ;
220222 iter .offset = 0 ;
@@ -303,23 +305,25 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
303305
304306 /* Add ring buffer information */
305307 drm_printf (& p , "Ring buffer information\n" );
306- for (int i = 0 ; i < coredump -> adev -> num_rings ; i ++ ) {
307- int j = 0 ;
308- struct amdgpu_ring * ring = coredump -> adev -> rings [i ];
309-
310- drm_printf (& p , "ring name: %s\n" , ring -> name );
311- drm_printf (& p , "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n" ,
312- amdgpu_ring_get_rptr (ring ),
313- amdgpu_ring_get_wptr (ring ),
314- ring -> buf_mask );
315- drm_printf (& p , "Ring size in dwords: %d\n" ,
316- ring -> ring_size / 4 );
317- drm_printf (& p , "Ring contents\n" );
318- drm_printf (& p , "Offset \t Value\n" );
319-
320- while (j < ring -> ring_size ) {
321- drm_printf (& p , "0x%x \t 0x%x\n" , j , ring -> ring [j / 4 ]);
322- j += 4 ;
308+ if (coredump -> num_rings ) {
309+ for (i = 0 ; i < coredump -> num_rings ; i ++ ) {
310+ ring_idx = coredump -> rings [i ].ring_index ;
311+ ring = coredump -> adev -> rings [ring_idx ];
312+ off = coredump -> rings [i ].offset ;
313+
314+ drm_printf (& p , "ring name: %s\n" , ring -> name );
315+ drm_printf (& p , "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n" ,
316+ coredump -> rings [i ].rptr ,
317+ coredump -> rings [i ].wptr ,
318+ ring -> buf_mask );
319+ drm_printf (& p , "Ring size in dwords: %d\n" ,
320+ ring -> ring_size / 4 );
321+ drm_printf (& p , "Ring contents\n" );
322+ drm_printf (& p , "Offset \t Value\n" );
323+
324+ for (j = 0 ; j < ring -> ring_size ; j += 4 )
325+ drm_printf (& p , "0x%x \t 0x%x\n" , j ,
326+ coredump -> rings_dw [off + j / 4 ]);
323327 }
324328 }
325329
@@ -359,6 +363,8 @@ static void amdgpu_devcoredump_free(void *data)
359363 struct amdgpu_coredump_info * coredump = data ;
360364
361365 kvfree (coredump -> formatted );
366+ kvfree (coredump -> rings );
367+ kvfree (coredump -> rings_dw );
362368 kvfree (data );
363369}
364370
@@ -396,6 +402,9 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
396402 struct drm_device * dev = adev_to_drm (adev );
397403 struct amdgpu_coredump_info * coredump ;
398404 struct drm_sched_job * s_job ;
405+ u64 total_ring_size , ring_count ;
406+ struct amdgpu_ring * ring ;
407+ int i , off , idx ;
399408
400409 /* No need to generate a new coredump if there's one in progress already. */
401410 if (work_pending (& adev -> coredump_work ))
@@ -423,6 +432,47 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
423432 coredump -> ring = to_amdgpu_ring (s_job -> sched );
424433 }
425434
435+ /* Dump ring content if memory allocation succeeds. */
436+ ring_count = 0 ;
437+ total_ring_size = 0 ;
438+ for (i = 0 ; i < adev -> num_rings ; i ++ ) {
439+ ring = adev -> rings [i ];
440+
441+ /* Only dump rings with unsignalled fences. */
442+ if (atomic_read (& ring -> fence_drv .last_seq ) == ring -> fence_drv .sync_seq &&
443+ coredump -> ring != ring )
444+ continue ;
445+
446+ total_ring_size += ring -> ring_size ;
447+ ring_count ++ ;
448+ }
449+ coredump -> rings_dw = kzalloc (total_ring_size , GFP_NOWAIT );
450+ coredump -> rings = kcalloc (ring_count , sizeof (struct amdgpu_coredump_ring ), GFP_NOWAIT );
451+ if (coredump -> rings && coredump -> rings_dw ) {
452+ for (i = 0 , off = 0 , idx = 0 ; i < adev -> num_rings ; i ++ ) {
453+ ring = adev -> rings [i ];
454+
455+ if (atomic_read (& ring -> fence_drv .last_seq ) == ring -> fence_drv .sync_seq &&
456+ coredump -> ring != ring )
457+ continue ;
458+
459+ coredump -> rings [idx ].ring_index = ring -> idx ;
460+ coredump -> rings [idx ].rptr = amdgpu_ring_get_rptr (ring );
461+ coredump -> rings [idx ].wptr = amdgpu_ring_get_wptr (ring );
462+ coredump -> rings [idx ].offset = off ;
463+
464+ memcpy (& coredump -> rings_dw [off ], ring -> ring , ring -> ring_size );
465+ off += ring -> ring_size ;
466+ idx ++ ;
467+ }
468+ coredump -> num_rings = idx ;
469+ } else {
470+ kvfree (coredump -> rings_dw );
471+ kvfree (coredump -> rings );
472+ coredump -> rings_dw = NULL ;
473+ coredump -> rings = NULL ;
474+ }
475+
426476 coredump -> adev = adev ;
427477
428478 ktime_get_ts64 (& coredump -> reset_time );
0 commit comments