@@ -688,6 +688,13 @@ static bool is_amd_timeline_event( const trace_event_t &event )
688
688
!strcmp ( event.name , " amdgpu_sched_run_job" ) );
689
689
}
690
690
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
+
691
698
static void add_sched_switch_pid_comm ( trace_info_t &trace_info, const trace_event_t &event,
692
699
const char *pidstr, const char *commstr )
693
700
{
@@ -1763,6 +1770,11 @@ uint32_t TraceEvents::get_event_gfxcontext_hash( const trace_event_t &event )
1763
1770
return atoi ( get_event_field_val ( event, " seqno" , " 0" ) );
1764
1771
}
1765
1772
1773
+ if ( is_drm_sched_timeline_event ( event ) )
1774
+ {
1775
+ return event.seqno ;
1776
+ }
1777
+
1766
1778
if ( event.seqno )
1767
1779
{
1768
1780
const char *context = get_event_field_val ( event, " context" , NULL );
@@ -1959,6 +1971,107 @@ void TraceEvents::init_msm_timeline_event( trace_event_t &event )
1959
1971
}
1960
1972
}
1961
1973
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
+
1962
2075
void TraceEvents::init_i915_event ( trace_event_t &event )
1963
2076
{
1964
2077
i915_type_t event_type = get_i915_reqtype ( event );
@@ -2187,6 +2300,10 @@ void TraceEvents::init_new_event( trace_event_t &event )
2187
2300
{
2188
2301
init_amd_timeline_event ( event );
2189
2302
}
2303
+ else if ( is_drm_sched_timeline_event ( event ) )
2304
+ {
2305
+ init_drm_sched_timeline_event ( event );
2306
+ }
2190
2307
else if ( is_msm_timeline_event ( event.name ) )
2191
2308
{
2192
2309
init_msm_timeline_event ( event );
@@ -2808,6 +2925,11 @@ const std::vector< uint32_t > *TraceEvents::get_locs( const char *name,
2808
2925
}
2809
2926
plocs = m_amd_timeline_locs.get_locations_str ( timeline_name.c_str () );
2810
2927
}
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
+ }
2811
2933
else
2812
2934
{
2813
2935
size_t len = strlen ( name );
0 commit comments