[PATCH 109/109] drm/amd/ras: fix CPER command record retrieval
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Xiang Liu <[email protected]> The CPER command reports the next batch ID as the latest valid record and does not handle a request starting at the write pointer. Batch trace responses also copy only the ACA interpretation of the log union. Report the latest valid CPER ID, select the preceding record for a write pointer request, expose a bounded command transfer size, and copy the complete log body for batch trace records. Signed-off-by: Xiang Liu <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/cmd.c | 23 +++++++++++++++++------ drivers/gpu/drm/amd/ras/core/cmd.h | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/ras/core/cmd.c b/drivers/gpu/drm/amd/ras/core/cmd.c index 2eb67ccc562d5..66bd62a819b2e 100644 --- a/drivers/gpu/drm/amd/ras/core/cmd.c +++ b/drivers/gpu/drm/amd/ras/core/cmd.c @@ -174,16 +174,18 @@ static int ras_cmd_get_cper_snapshot(struct ras_core_context *ras_core, struct ras_cmd_cper_snapshot_rsp *output_data = (struct ras_cmd_cper_snapshot_rsp *)cmd->output_buff_raw; struct ras_log_batch_overview overview; + u64 latest_cper_id; if ((cmd->input_size != sizeof(struct ras_cmd_cper_snapshot_req)) || (cmd->output_buf_size < sizeof(*output_data))) return RAS_CMD__ERROR_INVALID_INPUT_SIZE; ras_log_ring_get_batch_overview(ras_core, &overview); + latest_cper_id = overview.logged_batch_count ? overview.last_batch_id - 1 : 0; output_data->total_cper_num = overview.logged_batch_count; output_data->start_cper_id = overview.first_batch_id; - output_data->latest_cper_id = overview.last_batch_id; + output_data->latest_cper_id = latest_cper_id; output_data->version = 0; @@ -202,7 +204,7 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core, uint32_t nr_batch_logs = MAX_RECORD_PER_BATCH; struct ras_log_batch_overview overview; uint32_t offset = 0, real_data_len = 0; - uint64_t batch_id; + u64 batch_id, start_batch_id; uint8_t *buf_ptr = (uint8_t *)(uintptr_t)req->buf_ptr; int ret = 0, i, count, valid_batch_count = 0; @@ -221,14 +223,24 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core, } ras_log_ring_get_batch_overview(ras_core, &overview); + + start_batch_id = req->cper_start_id; + if (overview.logged_batch_count && start_batch_id == overview.last_batch_id) + start_batch_id = overview.last_batch_id - 1; + for (i = 0; i < req->cper_num; i++) { - batch_id = req->cper_start_id + i; + batch_id = start_batch_id + i; if (batch_id >= overview.last_batch_id) break; count = ras_log_ring_get_batch_records(ras_core, batch_id, batch_logs, nr_batch_logs); if (count > 0) { + if (offset >= req->buf_size) { + ret = -ENOMEM; + break; + } + ret = ras_cper_generate_batch_cper(ras_core, batch_logs, count, &buf_ptr[offset], req->buf_size - offset, &real_data_len); if (ret) @@ -328,9 +340,8 @@ static int ras_cmd_get_batch_trace_records(struct ras_core_context *ras_core, record->seqno = trace_arry[j].seqno; record->timestamp = trace_arry[j].timestamp; record->event = trace_arry[j].event; - memcpy(&record->body.aca_reg, - &trace_arry[j].body.aca_reg, - sizeof(trace_arry[j].body.aca_reg)); + memcpy(&record->body, &trace_arry[j].body, + sizeof(record->body)); } } else { count = 0; diff --git a/drivers/gpu/drm/amd/ras/core/cmd.h b/drivers/gpu/drm/amd/ras/core/cmd.h index a37b050e913ab..d3f5ec3c8e5c6 100644 --- a/drivers/gpu/drm/amd/ras/core/cmd.h +++ b/drivers/gpu/drm/amd/ras/core/cmd.h @@ -359,6 +359,8 @@ struct ras_cmd_cper_snapshot_rsp { uint64_t latest_cper_id; }; +#define RAS_CMD_MAX_CPER_BUF_SZ (2 * 1024U * 1024U) /* 2 MiB */ + struct ras_cmd_cper_record_req { struct ras_cmd_dev_handle dev; uint64_t cper_start_id; -- 2.55.0