Commit 6804287b authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher

drm/amd/display: Fixed read/write pointer issue for get dmub trace

[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
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarEryk Brol <eryk.brol@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 61a74712
...@@ -172,14 +172,10 @@ bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv, ...@@ -172,14 +172,10 @@ bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
stream_mask, timeout) == DMUB_STATUS_OK; 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; struct dmub_srv *dmub = dc->ctx->dmub_srv->dmub;
enum dmub_status status; return dmub_srv_get_outbox0_msg(dmub, entry);
status = dmub_srv_get_outbox0_msg(dmub, entry);
return status;
} }
void dc_dmub_trace_event_control(struct dc *dc, bool enable) void dc_dmub_trace_event_control(struct dc *dc, bool enable)
......
...@@ -62,7 +62,7 @@ bool dc_dmub_srv_cmd_with_reply_data(struct dc_dmub_srv *dc_dmub_srv, union dmub ...@@ -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, bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
unsigned int stream_mask); 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); void dc_dmub_trace_event_control(struct dc *dc, bool enable);
......
...@@ -667,7 +667,7 @@ enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub, ...@@ -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, enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub,
union dmub_rb_cmd *cmd); 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) #if defined(__cplusplus)
} }
......
...@@ -725,27 +725,26 @@ static inline bool dmub_rb_out_trace_buffer_front(struct dmub_rb *rb, ...@@ -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); const uint64_t *src = (const uint64_t *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
uint64_t *dst = (uint64_t *)entry; uint64_t *dst = (uint64_t *)entry;
uint8_t i; 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 // 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++; *dst++ = *src++;
rb->rptr += sizeof(struct dmcub_trace_buf_entry); rb->rptr += sizeof(struct dmcub_trace_buf_entry);
rb->rptr %= rb->capacity; rb->rptr %= rb->capacity;
if (rb->rptr == rb->wrpt)
return true; return true;
return false;
} }
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); 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_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry);
return DMUB_STATUS_OK;
return DMUB_STATUS_QUEUE_FULL;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment