mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 11:33:28 +02:00
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: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Eryk Brol <eryk.brol@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
61a74712c8
commit
6804287bd1
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user