mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
drm/amdgpu: Simplify filtering rings during IP block soft reset
Instead of storing pointers to affected rings in an array, just iterate over all rings of the device and filter the affected rings by type using the type mask. This is done to save memory used by the array of affected rings which was sized AMDGPU_MAX_RINGS. Suggested-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Reviewed-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com> # for the series Link: https://patch.msgid.link/20260624073829.40835-1-timur.kristof@gmail.com Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
aa7e29cf9a
commit
070e834f97
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user