[PATCH 2/3] drm/xe/xe_oa: Avoid checking and setting fields in the OA report
Umesh Nerlige Ramappa <[email protected]> Thu, 30 Jul 2026 16:35:42 -0700
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
OA unit updates the HW TAIL register to indicate that a new report is available, although it does not guarantee that the report is visible in memory. Also the currently running workload contributes to some latency in seeing this report in memory. In the past we would set some fields in the OA report and check if the fields are populated to non-zero values by the HW, but this is no longer sufficient since some parts of the report may land out of order under heavy workloads. Drop this WA and add a new logic in subsequent patches to return updated reports to the user. Signed-off-by: Umesh Nerlige Ramappa <[email protected]> --- drivers/gpu/drm/xe/xe_oa.c | 79 +------------------------------------- 1 file changed, 2 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 5eb8f6739fae..c7f9c3955cb5 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -216,42 +216,6 @@ static u32 xe_oa_hw_tail_read(struct xe_oa_stream *stream) #define oa_report_header_64bit(__s) \ ((__s)->oa_buffer.format->header == HDR_64_BIT) -static u64 oa_report_id(struct xe_oa_stream *stream, u32 report_offset) -{ - struct iosys_map *map = &stream->oa_buffer.bo->vmap; - - return oa_report_header_64bit(stream) ? - xe_map_rd(stream->oa->xe, map, report_offset, u64) : - xe_map_rd(stream->oa->xe, map, report_offset, u32); -} - -static void oa_report_id_clear(struct xe_oa_stream *stream, u32 report_offset) -{ - struct iosys_map *map = &stream->oa_buffer.bo->vmap; - - oa_report_header_64bit(stream) ? - xe_map_wr(stream->oa->xe, map, report_offset, u64, 0) : - xe_map_wr(stream->oa->xe, map, report_offset, u32, 0); -} - -static u64 oa_timestamp(struct xe_oa_stream *stream, u32 report_offset) -{ - struct iosys_map *map = &stream->oa_buffer.bo->vmap; - - return oa_report_header_64bit(stream) ? - xe_map_rd(stream->oa->xe, map, report_offset + 8, u64) : - xe_map_rd(stream->oa->xe, map, report_offset + 4, u32); -} - -static void oa_timestamp_clear(struct xe_oa_stream *stream, u32 report_offset) -{ - struct iosys_map *map = &stream->oa_buffer.bo->vmap; - - oa_report_header_64bit(stream) ? - xe_map_wr(stream->oa->xe, map, report_offset + 8, u64, 0) : - xe_map_wr(stream->oa->xe, map, report_offset + 4, u32, 0); -} - static bool mert_wa_14026633728(struct xe_oa_stream *s) { return s->oa_unit->type == DRM_XE_OA_UNIT_TYPE_MERT && XE_DEVICE_WA(s->oa->xe, 14026633728); @@ -260,7 +224,7 @@ static bool mert_wa_14026633728(struct xe_oa_stream *s) static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream) { u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); - u32 tail, hw_tail, partial_report_size, available; + u32 hw_tail, partial_report_size, available; int report_size = stream->oa_buffer.format->size; unsigned long flags; @@ -280,29 +244,7 @@ static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream) /* Subtract partial amount off the tail */ hw_tail = xe_oa_circ_diff(stream, hw_tail, partial_report_size); - tail = hw_tail; - - /* - * Walk the stream backward until we find a report with report id and timestamp - * not 0. We can't tell whether a report has fully landed in memory before the - * report id and timestamp of the following report have landed. - * - * This is assuming that the writes of the OA unit land in memory in the order - * they were written. If not : (╯°□°)╯︵ ┻━┻ - */ - while (xe_oa_circ_diff(stream, tail, stream->oa_buffer.tail) >= report_size) { - if (oa_report_id(stream, tail) || oa_timestamp(stream, tail)) - break; - - tail = xe_oa_circ_diff(stream, tail, report_size); - } - - if (xe_oa_circ_diff(stream, hw_tail, tail) > report_size) - drm_dbg(&stream->oa->xe->drm, - "unlanded report(s) head=0x%x tail=0x%x hw_tail=0x%x\n", - stream->oa_buffer.head, tail, hw_tail); - - stream->oa_buffer.tail = tail; + stream->oa_buffer.tail = hw_tail; available = xe_oa_circ_diff(stream, stream->oa_buffer.tail, stream->oa_buffer.head); stream->pollin = available >= stream->wait_num_reports * report_size; @@ -387,23 +329,6 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf, ret = xe_oa_append_report(stream, buf, count, offset, head); if (ret) break; - - if (!(stream->oa_buffer.circ_size % report_size)) { - /* Clear out report id and timestamp to detect unlanded reports */ - oa_report_id_clear(stream, head); - oa_timestamp_clear(stream, head); - } else { - struct iosys_map *map = &stream->oa_buffer.bo->vmap; - u32 part = stream->oa_buffer.circ_size - head; - - /* Zero out the entire report */ - if (report_size <= part) { - xe_map_memset(stream->oa->xe, map, head, 0, report_size); - } else { - xe_map_memset(stream->oa->xe, map, head, 0, part); - xe_map_memset(stream->oa->xe, map, 0, 0, report_size - part); - } - } } if (start_offset != *offset) { -- 2.51.0