aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2020-03-30 09:30:54 -0700
committerMarge Bot <[email protected]>2020-03-30 23:20:13 +0000
commit1b3aefad46bda59ff02c0d81c53fd3fbf249d8f4 (patch)
treee49281731ef67ec9d369b36d0f2dba0c8d39711a
parent2bf7dba80bb196bbb557e26017a5297c80fe2428 (diff)
freedreno/log: avoid duplicate ts's
In cases where `fd_log()`/`fd_log_stream()` are called multiple times back-to-back, just use the timestamp of the first trace. This seems to avoid some occasional GPU hangs I was seeing with logging enabled. Although not exactly sure the reason for the hangs. (Looks like GPU hangs *after* all the cmdstream is processed, according to crashdec.) Signed-off-by: Rob Clark <[email protected]> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4366> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4366>
-rw-r--r--src/gallium/drivers/freedreno/freedreno_log.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_log.c b/src/gallium/drivers/freedreno/freedreno_log.c
index 3edbcdede74..c1fe4da8142 100644
--- a/src/gallium/drivers/freedreno/freedreno_log.c
+++ b/src/gallium/drivers/freedreno/freedreno_log.c
@@ -67,6 +67,7 @@ struct fd_log_chunk {
struct fd_bo *timestamps_bo;
bool eof;
+ uint32_t *ring_cur;
};
static struct fd_log_chunk *
@@ -117,12 +118,21 @@ process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk)
while (u_fifo_pop(chunk->msg_fifo, (void **)&msg)) {
uint64_t ts = timestamps[n++];
uint64_t ns = ctx->ts_to_ns(ts);
- int32_t delta = last_time_ns ? ns - last_time_ns : 0;
+ int32_t delta;
if (!first_time_ns)
first_time_ns = ns;
- last_time_ns = ns;
+ if (ns) {
+ delta = last_time_ns ? ns - last_time_ns : 0;
+ last_time_ns = ns;
+ } else {
+ /* we skipped recording the timestamp, so it should be
+ * the same as last msg:
+ */
+ ns = last_time_ns;
+ delta = 0;
+ }
printf("%016"PRIu64" %016"PRIu64" %+9d: %s\n", ts, ns, delta, msg);
free(msg);
@@ -180,10 +190,23 @@ _fd_log(struct fd_batch *batch, const char *fmt, ...)
u_fifo_add(chunk->msg_fifo, msg);
assert(ctx->record_timestamp);
- ctx->record_timestamp(ring, chunk->timestamps_bo,
- chunk->num_msgs * sizeof(uint64_t));
+
+ /* If nothing else has been emitted to the ring since the last log msg,
+ * skip emitting another timestamp.
+ */
+ if (ring->cur == chunk->ring_cur) {
+ uint64_t *ts = fd_bo_map(chunk->timestamps_bo);
+ /* zero signifies an invalid timestamp to process_chunk(), so it
+ * will use the last valid timestamp for this msg instead.
+ */
+ ts[chunk->num_msgs] = 0;
+ } else {
+ ctx->record_timestamp(ring, chunk->timestamps_bo,
+ chunk->num_msgs * sizeof(uint64_t));
+ }
chunk->num_msgs++;
+ chunk->ring_cur = ring->cur;
}
void fd_log_eof(struct fd_context *ctx)