Skip to content

Commit 54d18bc

Browse files
Jie1zhangalexdeucher
authored andcommitted
drm/amdgpu/userq: add a detect and reset callback
Add a detect and reset callback and add the implementation for mes. The callback will detect all hung queues of a particular ip type (e.g., GFX or compute or SDMA) and reset them. v2: increase reset counter and set fence force completion v3: Removed userq_mutex in mes_userq_detect_and_reset since the driver holds it when calling Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent cbda64f commit 54d18bc

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ struct amdgpu_userq_funcs {
8282
struct amdgpu_usermode_queue *queue);
8383
int (*restore)(struct amdgpu_userq_mgr *uq_mgr,
8484
struct amdgpu_usermode_queue *queue);
85+
int (*detect_and_reset)(struct amdgpu_device *adev,
86+
int queue_type);
8587
};
8688

8789
/* Usermode queues for gfx */

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* OTHER DEALINGS IN THE SOFTWARE.
2222
*
2323
*/
24+
#include <drm/drm_drv.h>
2425
#include "amdgpu.h"
2526
#include "amdgpu_gfx.h"
2627
#include "mes_userqueue.h"
@@ -198,6 +199,53 @@ static int mes_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
198199
return 0;
199200
}
200201

202+
static int mes_userq_detect_and_reset(struct amdgpu_device *adev,
203+
int queue_type)
204+
{
205+
int db_array_size = amdgpu_mes_get_hung_queue_db_array_size(adev);
206+
struct mes_detect_and_reset_queue_input input;
207+
struct amdgpu_usermode_queue *queue;
208+
struct amdgpu_userq_mgr *uqm, *tmp;
209+
unsigned int hung_db_num = 0;
210+
int queue_id, r, i;
211+
u32 db_array[4];
212+
213+
if (db_array_size > 4) {
214+
dev_err(adev->dev, "DB array size (%d vs 4) too small\n",
215+
db_array_size);
216+
return -EINVAL;
217+
}
218+
219+
memset(&input, 0x0, sizeof(struct mes_detect_and_reset_queue_input));
220+
221+
input.queue_type = queue_type;
222+
223+
amdgpu_mes_lock(&adev->mes);
224+
r = amdgpu_mes_detect_and_reset_hung_queues(adev, queue_type, false,
225+
&hung_db_num, db_array);
226+
amdgpu_mes_unlock(&adev->mes);
227+
if (r) {
228+
dev_err(adev->dev, "Failed to detect and reset queues, err (%d)\n", r);
229+
} else if (hung_db_num) {
230+
list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) {
231+
idr_for_each_entry(&uqm->userq_idr, queue, queue_id) {
232+
if (queue->queue_type == queue_type) {
233+
for (i = 0; i < hung_db_num; i++) {
234+
if (queue->doorbell_index == db_array[i]) {
235+
queue->state = AMDGPU_USERQ_STATE_HUNG;
236+
atomic_inc(&adev->gpu_reset_counter);
237+
amdgpu_userq_fence_driver_force_completion(queue);
238+
drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL);
239+
}
240+
}
241+
}
242+
}
243+
}
244+
}
245+
246+
return r;
247+
}
248+
201249
static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr,
202250
struct drm_amdgpu_userq_in *args_in,
203251
struct amdgpu_usermode_queue *queue)
@@ -352,4 +400,5 @@ const struct amdgpu_userq_funcs userq_mes_funcs = {
352400
.mqd_destroy = mes_userq_mqd_destroy,
353401
.unmap = mes_userq_unmap,
354402
.map = mes_userq_map,
403+
.detect_and_reset = mes_userq_detect_and_reset,
355404
};

0 commit comments

Comments
 (0)