diff mbox

[i-g-t,5/7] trace.pl: Fix incomplete request handling

Message ID 20180508173115.24550-5-tvrtko.ursulin@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tvrtko Ursulin May 8, 2018, 5:31 p.m. UTC
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Incomplete requests (no notify, no context complete) have to be corrected
by looking at the engine timeline, and not the sorted-by-start-time view
as was previously used.

Per-engine timelines are generated on demand and cached for later use.

v2: Find end of current context on the engine timeline instead of just
    using the next request for adjusting the incomplete start time.

v3: Improve scaling with large datasets by only walking each engine
    timeline once and some caching. (John Harrison)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: John Harrison <John.C.Harrison@intel.com>
---
 scripts/trace.pl | 102 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 75 insertions(+), 27 deletions(-)
diff mbox

Patch

diff --git a/scripts/trace.pl b/scripts/trace.pl
index 696c18e8b1cf..0ec33cd37e4a 100755
--- a/scripts/trace.pl
+++ b/scripts/trace.pl
@@ -498,39 +498,83 @@  foreach my $key (keys %db) {
 	}
 }
 
-# Fix up incompletes
 my $key_count = scalar(keys %db);
-foreach my $key (keys %db) {
-	next unless exists $db{$key}->{'incomplete'};
 
-	# End the incomplete batch at the time next one starts
-	my $ring = $db{$key}->{'ring'};
-	my $ctx = $db{$key}->{'ctx'};
-	my $seqno = $db{$key}->{'seqno'};
-	my $next_key;
-	my $i = 1;
-	my $end;
-
-	do {
-		$next_key = db_key($ring, $ctx, $seqno + $i);
-		$i++;
-	} until ((exists $db{$next_key} and not exists $db{$next_key}->{'incomplete'})
-		 or $i > $key_count);  # ugly stop hack
+my %engine_timelines;
 
-	if (exists $db{$next_key}) {
-		$end = $db{$next_key}->{'end'};
-	} else {
-		# No info at all, fake it:
-		$end = $db{$key}->{'start'} + 999;
-	}
+sub sortEngine {
+	my $as = $db{$a}->{'global'};
+	my $bs = $db{$b}->{'global'};
+	my $val;
 
-	$db{$key}->{'notify'} = $end;
-	$db{$key}->{'end'} = $end;
+	$val = $as <=> $bs;
+
+	die if $val == 0;
+
+	return $val;
 }
 
-# GPU time accounting
-my (%running, %runnable, %queued, %batch_avg, %batch_total_avg, %batch_count);
-my (%submit_avg, %execute_avg, %ctxsave_avg);
+sub get_engine_timeline {
+	my ($ring) = @_;
+	my @timeline;
+
+	return $engine_timelines{$ring} if exists $engine_timelines{$ring};
+
+	@timeline = grep { $db{$_}->{'ring'} == $ring } keys %db;
+	# FIXME seqno restart
+	@timeline = sort sortEngine @timeline;
+
+	$engine_timelines{$ring} = \@timeline;
+
+	return \@timeline;
+}
+
+# Fix up incompletes by ending them when the last request of a coalesced group
+# ends. (Or first of a different context starts.)
+foreach my $gid (sort keys %rings) {
+	my $ring = $ringmap{$rings{$gid}};
+	my $timeline = get_engine_timeline($ring);
+	my $last_complete = -1;
+	my $complete;
+
+	foreach my $pos (0..$#{$timeline}) {
+		my $key = @{$timeline}[$pos];
+		my $end;
+
+		next unless exists $db{$key}->{'incomplete'};
+
+		# Find first following complete request
+		if ($pos > $last_complete) {
+			my $next = $pos;
+
+			undef $complete;
+
+			while ($next < $#{$timeline}) {
+				my $next_key = ${$timeline}[++$next];
+
+				next if exists $db{$next_key}->{'incomplete'};
+
+				$last_complete = $next;
+				$complete = $next_key;
+				last;
+			}
+		}
+
+		if (defined $complete) {
+			if ($db{$key}->{'ctx'} == $db{$complete}->{'ctx'}) {
+				$end = $db{$complete}->{'end'};
+			} else {
+				$end = $db{$complete}->{'start'};
+			}
+		} else {
+			# No next submission, fake it.
+			$end = $db{$key}->{'start'} + 999;
+		}
+
+		$db{$key}->{'notify'} = $end;
+		$db{$key}->{'end'} = $end;
+	}
+}
 
 sub sortStart {
 	my $as = $db{$a}->{'start'};
@@ -579,6 +623,10 @@  foreach my $key (@sorted_keys) {
 
 @sorted_keys = sort sortStart keys %db if $re_sort;
 
+# GPU time accounting
+my (%running, %runnable, %queued, %batch_avg, %batch_total_avg, %batch_count);
+my (%submit_avg, %execute_avg, %ctxsave_avg);
+
 my $last_ts = 0;
 my $first_ts;
 my ($min_ctx, $max_ctx);