@@ -3350,6 +3350,46 @@ class runlist_impl
33503350 }
33513351 }
33523352
3353+ void
3354+ add_run_helper (xrt::run run)
3355+ {
3356+ // Get the potentially throwing action out of the way first
3357+ auto runidx = m_runlist.size ();
3358+ m_runlist.reserve (runidx + 1 );
3359+ m_bos.reserve (runidx + 1 );
3360+
3361+ auto execbuf = get_cmd_chain_for_run_at_index (runidx);
3362+ auto [cmd, pkt] = unpack (execbuf);
3363+ auto chain_data = get_ert_cmd_chain_data (pkt);
3364+
3365+ auto run_impl = run.get_handle ();
3366+ auto run_cmd = run_impl->get_cmd ();
3367+ auto run_bo = run_cmd->get_exec_bo ();
3368+ auto run_bo_props = run_bo->get_properties ();
3369+
3370+ auto data_idx = chain_data->command_count ;
3371+ chain_data->data [data_idx] = run_bo_props.kmhdl ;
3372+
3373+ // Let shim handle binding of run_bo arguments to the command
3374+ // that cahins the run_bo. This allows pinning if necessary.
3375+ // May throw, but so far no state change, so still safe.
3376+ cmd->bind_at (data_idx, run_bo, 0 , run_bo_props.size );
3377+
3378+ // Once a run object is added to a list it will be in a state that
3379+ // makes it impossible to add to another list or to same list
3380+ // twice. This state is managed by the run object itself by
3381+ // recording this runlist with the run object, but it doesn't
3382+ // proctect against caller manually controlling the run object,
3383+ // which is undefined behavior. No exceptions after this point.
3384+ run_impl->set_runlist (this ); // throws or changes state of run
3385+
3386+ // Non throwing state change
3387+ chain_data->command_count ++;
3388+ pkt->count += sizeof (uint64_t ) / word_size; // account for added command
3389+ m_runlist.push_back (std::move (run)); // move of shared_ptr is noexcept
3390+ m_bos.push_back (run_bo); // ptr noexcept
3391+ }
3392+
33533393 // Wait for runlist to complete, then check each chained command
33543394 // submitted to determine potential error within chunk. Locate the
33553395 // first failing command if any and mark all subsequent commands as
@@ -3454,41 +3494,19 @@ class runlist_impl
34543494 if (m_state != state::idle)
34553495 throw xrt_core::error (" runlist must be idle before adding run objects, current state: " + state_to_string (m_state));
34563496
3457- // Get the potentially throwing action out of the way first
3458- auto runidx = m_runlist.size ();
3459- m_runlist.reserve (runidx + 1 );
3460- m_bos.reserve (runidx + 1 );
3461-
3462- auto execbuf = get_cmd_chain_for_run_at_index (runidx);
3463- auto [cmd, pkt] = unpack (execbuf);
3464- auto chain_data = get_ert_cmd_chain_data (pkt);
3465-
3466- auto run_impl = run.get_handle ();
3467- auto run_cmd = run_impl->get_cmd ();
3468- auto run_bo = run_cmd->get_exec_bo ();
3469- auto run_bo_props = run_bo->get_properties ();
3470-
3471- auto data_idx = chain_data->command_count ;
3472- chain_data->data [data_idx] = run_bo_props.kmhdl ;
3473-
3474- // Let shim handle binding of run_bo arguments to the command
3475- // that cahins the run_bo. This allows pinning if necessary.
3476- // May throw, but so far no state change, so still safe.
3477- cmd->bind_at (data_idx, run_bo, 0 , run_bo_props.size );
3478-
3479- // Once a run object is added to a list it will be in a state that
3480- // makes it impossible to add to another list or to same list
3481- // twice. This state is managed by the run object itself by
3482- // recording this runlist with the run object, but it doesn't
3483- // proctect against caller manually controlling the run object,
3484- // which is undefined behavior. No exceptions after this point.
3485- run_impl->set_runlist (this ); // throws or changes state of run
3497+ // Get XDP init runs registered with the hwctx and add to runlist
3498+ // if not already added.
3499+ // These runs initializes AI array for profile/trace data
3500+ // The list can be empty if profile/trace is not enabled
3501+ if (m_runlist.empty ()) {
3502+ const auto & xdp_init_runs = xrt_core::hw_context_int::get_xdp_init_runs (m_hwctx);
3503+ for (const auto & init_run : xdp_init_runs) {
3504+ add_run_helper (init_run);
3505+ }
3506+ }
34863507
3487- // Non throwing state change
3488- chain_data->command_count ++;
3489- pkt->count += sizeof (uint64_t ) / word_size; // account for added command
3490- m_runlist.push_back (std::move (run)); // move of shared_ptr is noexcept
3491- m_bos.push_back (run_bo); // ptr noexcept
3508+ // Now add the original run object
3509+ add_run_helper (std::move (run));
34923510 }
34933511
34943512 void
@@ -3500,6 +3518,14 @@ class runlist_impl
35003518 if (m_runlist.empty ())
35013519 return ;
35023520
3521+ // Add XDP exit runs if any at the end of runlist before submitting
3522+ // These runs collect profile/trace data
3523+ // The list can be empty if profile/trace is not enabled
3524+ const auto & xdp_exit_runs = xrt_core::hw_context_int::get_xdp_exit_runs (m_hwctx);
3525+ for (const auto & exit_run : xdp_exit_runs) {
3526+ add_run_helper (exit_run);
3527+ }
3528+
35033529 // Prep each run object
35043530 for (auto & run : m_runlist)
35053531 run.get_handle ()->prep_start ();
@@ -3539,6 +3565,20 @@ class runlist_impl
35393565
35403566 // On succesful wait, the runlist becomes idle
35413567 m_state = state::idle;
3568+
3569+ // Remove any XDP exit runs added during execute
3570+ // This is done because runlist can be reused
3571+ // and XDP exit runs should be added at end
3572+ const auto & xdp_exit_runs = xrt_core::hw_context_int::get_xdp_exit_runs (m_hwctx);
3573+ if (xdp_exit_runs.size () > 0 ) {
3574+ // remove the exit runs from the runlist
3575+ m_runlist.erase (m_runlist.end () - xdp_exit_runs.size (), m_runlist.end ());
3576+
3577+ // clear the runlist associated with these exit runs
3578+ for (auto & run : xdp_exit_runs)
3579+ run.get_handle ()->clear_runlist ();
3580+ }
3581+
35423582 return std::cv_status::no_timeout;
35433583 }
35443584
0 commit comments