Avoid the confliction between read and write of ring buffer.
Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
wptr_old = ring->wptr;
+ mutex_lock(&ring->adev->cper.ring_lock);
while (count) {
ent_sz = amdgpu_cper_ring_get_ent_sz(ring, ring->wptr);
chunk = umin(ent_sz, count);
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);
{
struct amdgpu_ring *ring = &(adev->cper.ring_buf);
+ mutex_init(&adev->cper.ring_lock);
+
ring->adev = NULL;
ring->ring_obj = NULL;
ring->use_doorbell = false;
void *ring[CPER_MAX_ALLOWED_COUNT];
struct amdgpu_ring ring_buf;
+ struct mutex ring_lock;
};
void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,
result = 0;
if (*pos < 12) {
+ if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
+ mutex_lock(&ring->adev->cper.ring_lock);
+
early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask;
early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask;
early[2] = ring->wptr & ring->buf_mask;
for (i = *pos / 4; i < 3 && size; i++) {
r = put_user(early[i], (uint32_t *)buf);
- if (r)
- return r;
+ if (r) {
+ result = r;
+ goto out;
+ }
buf += 4;
result += 4;
size -= 4;
while (size) {
if (p == early[1])
- return result;
+ goto out;
value = ring->ring[p];
r = put_user(value, (uint32_t *)buf);
- if (r)
- return r;
+ if (r) {
+ result = r;
+ goto out;
+ }
buf += 4;
result += 4;
}
}
+out:
+ if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
+ mutex_unlock(&ring->adev->cper.ring_lock);
+
return result;
}