Skip to content

Commit 27ce1c8

Browse files
BobBeckettmikesart
authored andcommitted
Add support for importing generic DRM sched timing events.
Import generic drm scheduler events in to AMD timelime. DRM scheduler is based on AMD scheduler, so the semantics are mostly the same. Signed-off-by: Robert Beckett <[email protected]>
1 parent 9cbe3e4 commit 27ce1c8

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

src/gpuvis.cpp

+122
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,13 @@ static bool is_amd_timeline_event( const trace_event_t &event )
688688
!strcmp( event.name, "amdgpu_sched_run_job" ) );
689689
}
690690

691+
static bool is_drm_sched_timeline_event( const trace_event_t &event )
692+
{
693+
return ( !strcmp( event.name, "drm_sched_job" ) ||
694+
!strcmp( event.name, "drm_run_job" ) ||
695+
!strcmp( event.name, "drm_sched_process_job" ) );
696+
}
697+
691698
static void add_sched_switch_pid_comm( trace_info_t &trace_info, const trace_event_t &event,
692699
const char *pidstr, const char *commstr )
693700
{
@@ -1763,6 +1770,11 @@ uint32_t TraceEvents::get_event_gfxcontext_hash( const trace_event_t &event )
17631770
return atoi( get_event_field_val( event, "seqno", "0" ) );
17641771
}
17651772

1773+
if ( is_drm_sched_timeline_event( event ) )
1774+
{
1775+
return event.seqno;
1776+
}
1777+
17661778
if ( event.seqno )
17671779
{
17681780
const char *context = get_event_field_val( event, "context", NULL );
@@ -1959,6 +1971,107 @@ void TraceEvents::init_msm_timeline_event( trace_event_t &event )
19591971
}
19601972
}
19611973

1974+
void TraceEvents::init_drm_sched_timeline_event( trace_event_t &event )
1975+
{
1976+
uint32_t gfxcontext_hash = get_event_gfxcontext_hash( event );
1977+
std::string str;
1978+
const char *ring;
1979+
uint32_t fence;
1980+
1981+
fence = strtoul( get_event_field_val( event, "fence", "0" ), nullptr, 0 );
1982+
event.flags |= TRACE_FLAG_TIMELINE;
1983+
1984+
if ( !strcmp( event.name, "drm_sched_job" ) )
1985+
{
1986+
event.flags |= TRACE_FLAG_SW_QUEUE;
1987+
event.id_start = INVALID_ID;
1988+
event.graph_row_id = atoi( get_event_field_val( event, "job_count", "0" ) ) +
1989+
atoi( get_event_field_val( event, "hw_job_count", "0" ) );
1990+
event.seqno = strtoul( get_event_field_val( event, "id", "0" ), nullptr, 0 );
1991+
m_drm_sched.outstanding_jobs[fence] = event.seqno;
1992+
ring = get_event_field_val( event, "name", "<unknown>" );
1993+
str = string_format( "drm sched %s", ring );
1994+
m_drm_sched.rings.insert(str);
1995+
m_amd_timeline_locs.add_location_str( str.c_str(), event.id );
1996+
m_gfxcontext_locs.add_location_u32( event.seqno, event.id );
1997+
return;
1998+
}
1999+
2000+
auto job = m_drm_sched.outstanding_jobs.find( fence );
2001+
if ( job == m_drm_sched.outstanding_jobs.end() ) {
2002+
// no in flight job. This event will be dropped
2003+
return;
2004+
}
2005+
2006+
const std::vector< uint32_t > *plocs = get_gfxcontext_locs( job->second );
2007+
if ( plocs->size() < 1 )
2008+
{
2009+
// no previous start event. This event will be dropped
2010+
return;
2011+
}
2012+
2013+
if ( !strcmp( event.name, "drm_run_job" ) )
2014+
{
2015+
for ( auto it = plocs->rbegin(); it != plocs->rend(); ++it )
2016+
{
2017+
const trace_event_t &e = m_events[ *it ];
2018+
if ( e.flags & TRACE_FLAG_FENCE_SIGNALED )
2019+
{
2020+
// if we hit an end event, we should have already found a start
2021+
// event. Ignore this event, it will be dropped
2022+
return;
2023+
}
2024+
2025+
if ( e.flags & TRACE_FLAG_SW_QUEUE )
2026+
{
2027+
ring = get_event_field_val( e, "name", "<unknown>" );
2028+
str = string_format( "drm sched %s", ring );
2029+
m_drm_sched.rings.insert( str );
2030+
m_amd_timeline_locs.add_location_str( str.c_str(), event.id );
2031+
event.user_comm = e.comm;
2032+
event.id_start = e.id;
2033+
event.flags |= TRACE_FLAG_HW_QUEUE;
2034+
event.graph_row_id = e.graph_row_id;
2035+
event.seqno = e.seqno;
2036+
m_gfxcontext_locs.add_location_u32( event.seqno, event.id );
2037+
break;
2038+
}
2039+
}
2040+
}
2041+
2042+
if ( !strcmp( event.name, "drm_sched_process_job" ) )
2043+
{
2044+
// fence can be reused across multiple jobs, but never at the same
2045+
// time. Find the previous event with TRACE_FLAG_SW_QUEUE as start event.
2046+
for ( auto it = plocs->rbegin(); it != plocs->rend(); ++it )
2047+
{
2048+
const trace_event_t &e = m_events[ *it ];
2049+
if ( e.flags & TRACE_FLAG_FENCE_SIGNALED )
2050+
{
2051+
// if we hit an end event, we should have already found a start
2052+
// event. Ignore this event, it will be dropped
2053+
return;
2054+
}
2055+
2056+
if ( e.flags & TRACE_FLAG_HW_QUEUE )
2057+
{
2058+
ring = get_event_field_val( e, "name", "<unknown>" );
2059+
str = string_format( "drm sched %s", ring );
2060+
m_drm_sched.rings.insert( str );
2061+
m_amd_timeline_locs.add_location_str( str.c_str(), event.id );
2062+
event.user_comm = e.comm;
2063+
event.id_start = e.id;
2064+
event.flags |= TRACE_FLAG_FENCE_SIGNALED;
2065+
event.graph_row_id = e.graph_row_id;
2066+
event.seqno = e.seqno;
2067+
m_gfxcontext_locs.add_location_u32( event.seqno, event.id );
2068+
m_drm_sched.outstanding_jobs.erase( fence );
2069+
break;
2070+
}
2071+
}
2072+
}
2073+
}
2074+
19622075
void TraceEvents::init_i915_event( trace_event_t &event )
19632076
{
19642077
i915_type_t event_type = get_i915_reqtype( event );
@@ -2187,6 +2300,10 @@ void TraceEvents::init_new_event( trace_event_t &event )
21872300
{
21882301
init_amd_timeline_event( event );
21892302
}
2303+
else if ( is_drm_sched_timeline_event( event ) )
2304+
{
2305+
init_drm_sched_timeline_event( event );
2306+
}
21902307
else if ( is_msm_timeline_event( event.name ) )
21912308
{
21922309
init_msm_timeline_event( event );
@@ -2808,6 +2925,11 @@ const std::vector< uint32_t > *TraceEvents::get_locs( const char *name,
28082925
}
28092926
plocs = m_amd_timeline_locs.get_locations_str( timeline_name.c_str() );
28102927
}
2928+
else if ( !strncmp( name, "drm sched", 9 ) )
2929+
{
2930+
type = LOC_TYPE_AMDTimeline;
2931+
plocs = m_amd_timeline_locs.get_locations_str( name );
2932+
}
28112933
else
28122934
{
28132935
size_t len = strlen( name );

src/gpuvis.h

+9
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ class TraceEvents
459459
void init_sched_process_fork( trace_event_t &event );
460460
void init_amd_timeline_event( trace_event_t &event );
461461
void init_msm_timeline_event( trace_event_t &event );
462+
void init_drm_sched_timeline_event( trace_event_t &event );
462463
void init_i915_event( trace_event_t &event );
463464
void init_i915_perf_event( trace_event_t &event );
464465

@@ -597,6 +598,14 @@ class TraceEvents
597598
SDL_atomic_t m_eventsloaded = { 1 };
598599

599600
struct intel_perf_data_reader *i915_perf_reader = NULL;
601+
602+
struct {
603+
// set of rings discovered during event parsing
604+
std::unordered_set< std::string > rings;
605+
606+
// mapping from fence to outstanding job id
607+
std::map<uint32_t, uint32_t> outstanding_jobs;
608+
} m_drm_sched;
600609
};
601610

602611
class GraphRows

src/gpuvis_graphrows.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,20 @@ void GraphRows::init( TraceEvents &trace_events )
345345
}
346346
}
347347

348+
// drm sched timeline
349+
{
350+
std::string ring;
351+
352+
for ( std::string ring : trace_events.m_drm_sched.rings)
353+
{
354+
if ( strncmp( "drm sched", ring.c_str(), 9 ) )
355+
continue;
356+
357+
if ( (plocs = trace_events.get_locs( ring.c_str(), &type ) ) )
358+
push_row( ring, type, plocs->size() );
359+
}
360+
}
361+
348362
if ( ( plocs = trace_events.get_locs( "cpu graph", &type ) ) )
349363
{
350364
push_row( "cpu graph", type, plocs->size(), false );

0 commit comments

Comments
 (0)