Skip to content

Commit 8652920

Browse files
Tao Zhoualexdeucher
authored andcommitted
drm/amdgpu: add mutex lock for cper ring
Avoid the confliction between read and write of ring buffer. Signed-off-by: Tao Zhou <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent b1118df commit 8652920

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
440440

441441
wptr_old = ring->wptr;
442442

443+
mutex_lock(&ring->adev->cper.ring_lock);
443444
while (count) {
444445
ent_sz = amdgpu_cper_ring_get_ent_sz(ring, ring->wptr);
445446
chunk = umin(ent_sz, count);
@@ -468,6 +469,7 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
468469
pos = rptr;
469470
} while (!amdgpu_cper_is_hdr(ring, rptr));
470471
}
472+
mutex_unlock(&ring->adev->cper.ring_lock);
471473

472474
if (ring->count_dw >= (count >> 2))
473475
ring->count_dw -= (count >> 2);
@@ -497,6 +499,8 @@ static int amdgpu_cper_ring_init(struct amdgpu_device *adev)
497499
{
498500
struct amdgpu_ring *ring = &(adev->cper.ring_buf);
499501

502+
mutex_init(&adev->cper.ring_lock);
503+
500504
ring->adev = NULL;
501505
ring->ring_obj = NULL;
502506
ring->use_doorbell = false;

drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct amdgpu_cper {
6464

6565
void *ring[CPER_MAX_ALLOWED_COUNT];
6666
struct amdgpu_ring ring_buf;
67+
struct mutex ring_lock;
6768
};
6869

6970
void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,

drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,13 +510,18 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
510510
result = 0;
511511

512512
if (*pos < 12) {
513+
if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
514+
mutex_lock(&ring->adev->cper.ring_lock);
515+
513516
early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask;
514517
early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask;
515518
early[2] = ring->wptr & ring->buf_mask;
516519
for (i = *pos / 4; i < 3 && size; i++) {
517520
r = put_user(early[i], (uint32_t *)buf);
518-
if (r)
519-
return r;
521+
if (r) {
522+
result = r;
523+
goto out;
524+
}
520525
buf += 4;
521526
result += 4;
522527
size -= 4;
@@ -547,12 +552,14 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
547552

548553
while (size) {
549554
if (p == early[1])
550-
return result;
555+
goto out;
551556

552557
value = ring->ring[p];
553558
r = put_user(value, (uint32_t *)buf);
554-
if (r)
555-
return r;
559+
if (r) {
560+
result = r;
561+
goto out;
562+
}
556563

557564
buf += 4;
558565
result += 4;
@@ -562,6 +569,10 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
562569
}
563570
}
564571

572+
out:
573+
if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
574+
mutex_unlock(&ring->adev->cper.ring_lock);
575+
565576
return result;
566577
}
567578

0 commit comments

Comments
 (0)