]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: Fix computation for remain size of CPER ring
authorXiang Liu <xiang.liu@amd.com>
Thu, 13 Mar 2025 03:24:55 +0000 (11:24 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 18 Mar 2025 18:03:46 +0000 (14:03 -0400)
The mistake of computation for remain size of CPER ring will cause
unbreakable while cycle when CPER ring overflow.

Signed-off-by: Xiang Liu <xiang.liu@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c

index 3f291b30b79f617eb78eb8ca91dc788bc0cc6672..360e07a5c7c1fb574a321c091bcb47aafabfd740 100644 (file)
@@ -455,10 +455,10 @@ calc:
                return umin(rec_len, chunk);
 }
 
-void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
-                                             void *src, int count)
+void amdgpu_cper_ring_write(struct amdgpu_ring *ring, void *src, int count)
 {
        u64 pos, wptr_old, rptr = *ring->rptr_cpu_addr & ring->ptr_mask;
+       int rec_cnt_dw = count >> 2;
        u32 chunk, ent_sz;
        u8 *s = (u8 *)src;
 
@@ -485,6 +485,9 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
                s += chunk;
        }
 
+       if (ring->count_dw < rec_cnt_dw)
+               ring->count_dw = 0;
+
        /* the buffer is overflow, adjust rptr */
        if (((wptr_old < rptr) && (rptr <= ring->wptr)) ||
            ((ring->wptr < wptr_old) && (wptr_old < rptr)) ||
@@ -501,12 +504,10 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
                        pos = rptr;
                } while (!amdgpu_cper_is_hdr(ring, rptr));
        }
-       mutex_unlock(&ring->adev->cper.ring_lock);
 
-       if (ring->count_dw >= (count >> 2))
-               ring->count_dw -= (count >> 2);
-       else
-               ring->count_dw = 0;
+       if (ring->count_dw >= rec_cnt_dw)
+               ring->count_dw -= rec_cnt_dw;
+       mutex_unlock(&ring->adev->cper.ring_lock);
 }
 
 static u64 amdgpu_cper_ring_get_rptr(struct amdgpu_ring *ring)