Commit 8652920d authored by Tao Zhou's avatar Tao Zhou Committed by Alex Deucher
Browse files

drm/amdgpu: add mutex lock for cper ring



Avoid the confliction between read and write of ring buffer.

Signed-off-by: default avatarTao Zhou <tao.zhou1@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b1118df1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -440,6 +440,7 @@ void amdgpu_cper_ring_write(struct amdgpu_ring *ring,

	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);
@@ -468,6 +469,7 @@ 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);
@@ -497,6 +499,8 @@ static int amdgpu_cper_ring_init(struct amdgpu_device *adev)
{
	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;
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct amdgpu_cper {

	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,
+16 −5
Original line number Diff line number Diff line
@@ -510,13 +510,18 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
	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;
@@ -547,12 +552,14 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,

		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;
@@ -562,6 +569,10 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
		}
	}

out:
	if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
		mutex_unlock(&ring->adev->cper.ring_lock);

	return result;
}