diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c index 65505bc50399..99ed0b0d82e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c @@ -481,28 +481,6 @@ static u32 amdgpu_ring_mask_from_ip(const enum amd_ip_block_type ip_type) } } -/** - * amdgpu_filter_rings() - Filter rings according to a mask. - * - * @adev: amdgpu_device pointer - * @ring_type_mask: Mask of ring types you are looking for - * @out_rings: Array of rings which is going to be filled - * @out_num_rings: Number of rings which were filtered - */ -static void amdgpu_filter_rings(struct amdgpu_device *adev, const u32 ring_type_mask, - struct amdgpu_ring **out_rings, u32 *out_num_rings) -{ - u32 num_rings = 0; - int i; - - for (i = 0; i < adev->num_rings; ++i) { - if (BIT(adev->rings[i]->funcs->type) & ring_type_mask) - out_rings[num_rings++] = adev->rings[i]; - } - - *out_num_rings = num_rings; -} - /** * amdgpu_device_ip_soft_reset() - Perform a graceful soft reset on an IP block. * @@ -524,10 +502,9 @@ int amdgpu_device_ip_soft_reset(struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence) { struct amdgpu_device *adev = guilty_ring->adev; - struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; struct amdgpu_ip_block *ip_block; enum amd_ip_block_type ip_type; - u32 num_rings, ring_type_mask; + u32 ring_type_mask; int r; ip_type = amdgpu_ip_from_ring(guilty_ring->funcs->type); @@ -543,14 +520,13 @@ int amdgpu_device_ip_soft_reset(struct amdgpu_ring *guilty_ring, ip_block->version->funcs->name); ring_type_mask = amdgpu_ring_mask_from_ip(ip_type); - amdgpu_filter_rings(adev, ring_type_mask, rings, &num_rings); amdgpu_device_lock_reset_domain(adev->reset_domain); - amdgpu_multi_ring_reset_helper_begin(rings, num_rings, guilty_ring, guilty_fence); + amdgpu_multi_ring_reset_helper_begin(ring_type_mask, guilty_ring, guilty_fence); r = ip_block->version->funcs->soft_reset(ip_block); - r = amdgpu_multi_ring_reset_helper_end(rings, num_rings, guilty_ring, r); + r = amdgpu_multi_ring_reset_helper_end(ring_type_mask, guilty_ring, r); amdgpu_device_unlock_reset_domain(adev->reset_domain); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 3f78aa6ed82f..6e6aadba006c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -938,8 +938,7 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, /** * amdgpu_multi_ring_reset_helper_begin() - Prepare multiple rings for a reset. * - * @rings: Pointer to an array of amdgpu rings that are affected. - * @num_rings: Number of rings in the array. + * @ring_type_mask: Bitmask of affected ring types * @guilty_ring: The ring which is guilty of causing a reset. * @guilty_fence: The fence which didn't signal on the guilty ring. * @@ -958,7 +957,7 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, * After the reset is complete, the caller should then call * amdgpu_multi_ring_reset_helper_end() to restore the rings. */ -void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_rings, +void amdgpu_multi_ring_reset_helper_begin(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence) { @@ -969,8 +968,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri int i; u32 t; - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; /* Don't accept new submissions on the ring. */ if (amdgpu_ring_sched_ready(ring) && !drm_sched_is_stopped(&ring->sched)) @@ -1003,8 +1005,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri rings_busy = false; /* Check if any of the non-guilty rings are busy */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (ring == guilty_ring) continue; @@ -1020,8 +1025,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri mdelay(10); } - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; /* * Find guilty fences, ie. the fences that didn't signal @@ -1045,8 +1053,7 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri /** * amdgpu_multi_ring_reset_helper_end() - Prepare multiple rings for a reset. * - * @rings: Pointer to an array of amdgpu rings that are affected. - * @num_rings: Number of rings in the array. + * @ring_type_mask: Bitmask of affected ring types * @guilty_ring: The ring which is guilty of causing a reset. * @ret: Return code from the reset function. * @@ -1058,7 +1065,7 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri * be called to restore some state, but it won't attempt to * fully restore the ring contents. */ -int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings, +int amdgpu_multi_ring_reset_helper_end(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, int ret) { struct amdgpu_device *adev = guilty_ring->adev; @@ -1066,8 +1073,11 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings int i, r; /* Set preempt condition, rings are now allowed to execute submissions */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (ring->funcs->init_cond_exec) amdgpu_ring_set_preempt_cond_exec(ring, true); @@ -1081,9 +1091,13 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings return ret; /* Restore contents of all rings */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; + + /* Restore contents of the ring */ r = amdgpu_ring_reset_helper_end(ring, ring->guilty_fence); if (r) { dev_err(adev->dev, @@ -1094,8 +1108,11 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings } /* Accept submissions on all rings again */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (!amdgpu_ring_sched_ready(ring)) continue; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index c272e0b028ad..9d3934b4f106 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -595,10 +595,10 @@ void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring, struct amdgpu_fence *guilty_fence); int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, struct amdgpu_fence *guilty_fence); -void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_rings, +void amdgpu_multi_ring_reset_helper_begin(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence); -int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings, +int amdgpu_multi_ring_reset_helper_end(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, int ret); bool amdgpu_ring_is_reset_type_supported(struct amdgpu_ring *ring, u32 reset_type);