[PATCH 09/14] drm/amd/display: Fixed read/write pointer issue for get dmub trace
Eryk Brol
eryk.brol at amd.com
Fri Mar 5 20:02:56 UTC 2021
From: Yongqiang Sun <yongqiang.sun at amd.com>
[Why]
Driver get wrap around dmub trace data due to read pointer being
increased incorrectly when there are multiple interrupt
queues with very short interval
[How]
Check read/write pointer before copying data from ring buffer
Signed-off-by: Yongqiang Sun <yongqiang.sun at amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
Acked-by: Eryk Brol <eryk.brol at amd.com>
---
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 8 ++------
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 2 +-
drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 +-
.../gpu/drm/amd/display/dmub/src/dmub_srv.c | 19 +++++++++----------
4 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index b9d8cfef0a1a..68453c29c617 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -172,14 +172,10 @@ bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
stream_mask, timeout) == DMUB_STATUS_OK;
}
-enum dmub_status dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_buf_entry *entry)
+bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_buf_entry *entry)
{
struct dmub_srv *dmub = dc->ctx->dmub_srv->dmub;
- enum dmub_status status;
-
- status = dmub_srv_get_outbox0_msg(dmub, entry);
-
- return status;
+ return dmub_srv_get_outbox0_msg(dmub, entry);
}
void dc_dmub_trace_event_control(struct dc *dc, bool enable)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index eefec9cc21a8..338f776990db 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -62,7 +62,7 @@ bool dc_dmub_srv_cmd_with_reply_data(struct dc_dmub_srv *dc_dmub_srv, union dmub
bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
unsigned int stream_mask);
-enum dmub_status dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_buf_entry *entry);
+bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_buf_entry *entry);
void dc_dmub_trace_event_control(struct dc *dc, bool enable);
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 16d1976b041f..b4e14960b164 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -667,7 +667,7 @@ enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub,
enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub,
union dmub_rb_cmd *cmd);
-enum dmub_status dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry);
+bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry);
#if defined(__cplusplus)
}
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index 1f1375c49aa5..1ee2000ad099 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -725,27 +725,26 @@ static inline bool dmub_rb_out_trace_buffer_front(struct dmub_rb *rb,
const uint64_t *src = (const uint64_t *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
uint64_t *dst = (uint64_t *)entry;
uint8_t i;
+ uint8_t loop_count;
+ if (rb->rptr == rb->wrpt)
+ return false;
+
+ loop_count = sizeof(struct dmcub_trace_buf_entry) / sizeof(uint64_t);
// copying data
- for (i = 0; i < sizeof(struct dmcub_trace_buf_entry) / sizeof(uint64_t); i++)
+ for (i = 0; i < loop_count; i++)
*dst++ = *src++;
rb->rptr += sizeof(struct dmcub_trace_buf_entry);
rb->rptr %= rb->capacity;
- if (rb->rptr == rb->wrpt)
- return true;
-
- return false;
+ return true;
}
-enum dmub_status dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry)
+bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry)
{
dmub->outbox0_rb.wrpt = dmub->hw_funcs.get_outbox0_wptr(dmub);
- if (dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry))
- return DMUB_STATUS_OK;
-
- return DMUB_STATUS_QUEUE_FULL;
+ return dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry);
}
--
2.25.1
More information about the amd-gfx
mailing list