From c2eb26436ab644348d949eca76179417a80aa9ee Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Mon, 10 Jun 2019 15:12:47 -0700 Subject: [PATCH] gpu: nvgpu: Add doxygen documentation in runlist.h Removed the following unused fields from runlist context: - total_entries - stopped - support_tsg Renamed: - nvgpu_fifo_runlist_set_state -> nvgpu_runlist_set_state Removed RUNLIST_INVALID_ID which was redundant with NVGPU_INVALID_RUNLIST_ID. Jira NVGPU-3594 Change-Id: I23d1abdf87b73bc0138816dab6659249f2602b9f Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/2139520 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/engines.c | 4 +- drivers/gpu/nvgpu/common/fifo/runlist.c | 2 +- drivers/gpu/nvgpu/common/fifo/tsg.c | 4 +- drivers/gpu/nvgpu/hal/rc/rc_gv11b.c | 4 +- drivers/gpu/nvgpu/include/nvgpu/runlist.h | 284 ++++++++++++++++++++-- drivers/gpu/nvgpu/os/linux/cde.c | 2 +- 6 files changed, 269 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/engines.c b/drivers/gpu/nvgpu/common/fifo/engines.c index e442d9df4..fb837817d 100644 --- a/drivers/gpu/nvgpu/common/fifo/engines.c +++ b/drivers/gpu/nvgpu/common/fifo/engines.c @@ -255,7 +255,7 @@ int nvgpu_engine_enable_activity(struct gk20a *g, { nvgpu_log(g, gpu_dbg_info, "start"); - nvgpu_fifo_runlist_set_state(g, BIT32(eng_info->runlist_id), + nvgpu_runlist_set_state(g, BIT32(eng_info->runlist_id), RUNLIST_ENABLED); return 0; } @@ -309,7 +309,7 @@ int nvgpu_engine_disable_activity(struct gk20a *g, } #endif - nvgpu_fifo_runlist_set_state(g, BIT32(eng_info->runlist_id), + nvgpu_runlist_set_state(g, BIT32(eng_info->runlist_id), RUNLIST_DISABLED); /* chid from pbdma status */ diff --git a/drivers/gpu/nvgpu/common/fifo/runlist.c b/drivers/gpu/nvgpu/common/fifo/runlist.c index b9491737c..93304f2ec 100644 --- a/drivers/gpu/nvgpu/common/fifo/runlist.c +++ b/drivers/gpu/nvgpu/common/fifo/runlist.c @@ -607,7 +607,7 @@ const char *nvgpu_runlist_interleave_level_name(u32 interleave_level) return ret_string; } -void nvgpu_fifo_runlist_set_state(struct gk20a *g, u32 runlists_mask, +void nvgpu_runlist_set_state(struct gk20a *g, u32 runlists_mask, u32 runlist_state) { #ifdef CONFIG_NVGPU_LS_PMU diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 96366164e..d3ed866a4 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -584,14 +584,14 @@ u32 nvgpu_tsg_default_timeslice_us(struct gk20a *g) void nvgpu_tsg_enable_sched(struct gk20a *g, struct nvgpu_tsg *tsg) { - nvgpu_fifo_runlist_set_state(g, BIT32(tsg->runlist_id), + nvgpu_runlist_set_state(g, BIT32(tsg->runlist_id), RUNLIST_ENABLED); } void nvgpu_tsg_disable_sched(struct gk20a *g, struct nvgpu_tsg *tsg) { - nvgpu_fifo_runlist_set_state(g, BIT32(tsg->runlist_id), + nvgpu_runlist_set_state(g, BIT32(tsg->runlist_id), RUNLIST_DISABLED); } diff --git a/drivers/gpu/nvgpu/hal/rc/rc_gv11b.c b/drivers/gpu/nvgpu/hal/rc/rc_gv11b.c index 3d07b9c97..ae63ce5f1 100644 --- a/drivers/gpu/nvgpu/hal/rc/rc_gv11b.c +++ b/drivers/gpu/nvgpu/hal/rc/rc_gv11b.c @@ -189,7 +189,7 @@ void gv11b_fifo_recover(struct gk20a *g, u32 act_eng_bitmask, nvgpu_runlist_unlock_runlists(g, ~runlists_mask); /* Disable runlist scheduler */ - nvgpu_fifo_runlist_set_state(g, runlists_mask, RUNLIST_DISABLED); + nvgpu_runlist_set_state(g, runlists_mask, RUNLIST_DISABLED); if (nvgpu_cg_pg_disable(g) != 0) { nvgpu_warn(g, "fail to disable power mgmt"); @@ -294,7 +294,7 @@ void gv11b_fifo_recover(struct gk20a *g, u32 act_eng_bitmask, runlists_mask); } - nvgpu_fifo_runlist_set_state(g, runlists_mask, RUNLIST_ENABLED); + nvgpu_runlist_set_state(g, runlists_mask, RUNLIST_ENABLED); if (nvgpu_cg_pg_enable(g) != 0) { nvgpu_warn(g, "fail to enable power mgmt"); diff --git a/drivers/gpu/nvgpu/include/nvgpu/runlist.h b/drivers/gpu/nvgpu/include/nvgpu/runlist.h index 2047c5e8d..a630c94f5 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/runlist.h +++ b/drivers/gpu/nvgpu/include/nvgpu/runlist.h @@ -27,79 +27,317 @@ #include #include +/** + * @file + * + * Runlist interface. + */ struct gk20a; struct nvgpu_tsg; struct nvgpu_fifo; struct nvgpu_channel; +/** + * Low interleave level for runlist entry. TSGs with this interleave level + * typically appear only once in the runlist. + */ #define NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW 0U +/** + * Medium interleave level for runlist entry. TSGs with medium or high + * interleave levels are inserted multiple times in the runlist, so that + * they have more opportunities to run. + */ #define NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_MEDIUM 1U +/** + * High interleave level for runlist entry. + */ #define NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_HIGH 2U +/** + * Number of interleave levels. In safety build, all TSGs are handled with + * low interleave level. + */ #define NVGPU_FIFO_RUNLIST_INTERLEAVE_NUM_LEVELS 3U +/** Not enough entries in runlist buffer to accommodate all channels/TSGs. */ #define RUNLIST_APPEND_FAILURE U32_MAX -#define RUNLIST_INVALID_ID U32_MAX +/** Disable runlist. */ #define RUNLIST_DISABLED 0U +/** Enable runlist. */ #define RUNLIST_ENABLED 1U +/** Double buffering is used to build runlists */ #define MAX_RUNLIST_BUFFERS 2U -#define NVGPU_INVALID_RUNLIST_ID (~U32(0U)) +/** Runlist identifier is invalid. */ +#define NVGPU_INVALID_RUNLIST_ID U32_MAX struct nvgpu_runlist_info { + /** Runlist identifier. */ u32 runlist_id; + /** Bitmap of active channels in the runlist. One bit per chid. */ unsigned long *active_channels; + /** Bitmap of active TSGs in the runlist. One bit per tsgid. */ unsigned long *active_tsgs; - /* Each engine has its own SW and HW runlist buffer.*/ + /** Runlist buffers. Double buffering is used for each engine. */ struct nvgpu_mem mem[MAX_RUNLIST_BUFFERS]; + /** Indicates current runlist buffer used by HW. */ u32 cur_buffer; - u32 total_entries; - u32 pbdma_bitmask; /* pbdmas supported for this runlist*/ - u32 eng_bitmask; /* engines using this runlist */ - u32 reset_eng_bitmask; /* engines to be reset during recovery */ - u32 count; /* cached hw_submit parameter */ - bool stopped; - bool support_tsg; - /* protect ch/tsg/runlist preempt & runlist update */ + /** Bitmask of PBDMAs supported for this runlist. */ + u32 pbdma_bitmask; + /** Bitmask of engines using this runlist. */ + u32 eng_bitmask; + /** Bitmask of engines to be reset during recovery. */ + u32 reset_eng_bitmask; + /** Cached hw_submit parameter. */ + u32 count; + /** Protect ch/tsg/runlist preempt & runlist update. */ struct nvgpu_mutex runlist_lock; }; - +/** + * @brief Rebuild runlist + * + * @param f[in] The FIFO context using this runlist. + * @param runlist[in] Runlist context. + * @param buf_id[in] Indicates which runlist buffer to use. + * @param max_entries[in] Max number of entries in runlist buffer. + * + * Walks through all active TSGs in #runlist, and constructs runlist + * buffer #buf_id. This buffer can afterwards be submitted to H/W + * to be used for scheduling. + * + * Note: Caller must hold runlist_lock before invoking this function. + * + * @return Number of entries in the runlist. + * @retval #RUNLIST_APPEND_FAILURE in case there is not enough entries in + * runlist buffer to describe all active channels and TSGs. + */ u32 nvgpu_runlist_construct_locked(struct nvgpu_fifo *f, - struct nvgpu_runlist_info *runlist, - u32 buf_id, - u32 max_entries); + struct nvgpu_runlist_info *runlist, + u32 buf_id, u32 max_entries); + +/** + * @brief Add/remove channel to/from runlist (locked) + * + * @param g[in] The GPU driver struct owning this runlist. + * @param runlist_id[in] Runlist identifier. + * @param ch[in] Channel to be added/removed or NULL. + * @param add[in] True to add a channel, false to remove it. + * @param wait_for_finish[in] True to wait for runlist update completion. + * + * When #ch is NULL, this function has same behavior as #nvgpu_runlist_reload. + * When #ch is non NULL, this function has same behavior as + * #nvgpu_runlist_update_for_channel. + * + * The only difference with #nvgpu_runlist_reload is that the caller already + * holds the runlist_lock before calling this function. + * + * @return 0 in case of success, < 0 in case of failure. + * @retval -E2BIG in case there are not enough entries in runlist buffer to + * describe all active channels and TSGs. + */ int nvgpu_runlist_update_locked(struct gk20a *g, u32 runlist_id, - struct nvgpu_channel *ch, bool add, - bool wait_for_finish); + struct nvgpu_channel *ch, bool add, bool wait_for_finish); #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING int nvgpu_runlist_reschedule(struct nvgpu_channel *ch, bool preempt_next, bool wait_preempt); #endif +/** + * @brief Add/remove channel to/from runlist + * + * @param g[in] The GPU driver struct owning this runlist. + * @param runlist_id[in] Runlist identifier + * @param ch[in] Channel to be added/removed (must be non NULL) + * @param add[in] True to add channel to runlist + * @param wait_for_finish[in] True to wait for completion + * + * When #add is true, adds #ch to active channels of runlist #runlist_id. + * When #add is false, removes #ch from active channels of runlist #runlist_id. + * A new runlist is then constructed for active channels/TSGs, and submitted + * to H/W. + * + * When transitioning from prior runlist to the new runlist, H/W may have + * to preempt current TSG. When #wait_for_finish is true, the function polls + * H/W until it is done transitionning to the new runlist. In this case + * the function may fail with -ETIMEDOUT if transition to the new runlist takes + * too long. + * + * Note: function asserts that #ch is not NULL. + * + * @return 0 in case of success, < 0 in case of failure. + * @retval -E2BIG in case there are not enough entries in runlist buffer to + * accommodate all active channels/TSGs. + */ int nvgpu_runlist_update_for_channel(struct gk20a *g, u32 runlist_id, - struct nvgpu_channel *ch, - bool add, bool wait_for_finish); + struct nvgpu_channel *ch, bool add, bool wait_for_finish); + +/** + * @brief Reload runlist + * + * @param g[in] The GPU driver struct owning this runlist. + * @param runlist_id[in] Runlist identifier. + * @param add[in] True to submit a runlist buffer with all active + * channels. False to submit an empty runlist + * buffer. + * @param wait_for_finish[in] True to wait for runlist update completion. + * + * When #add is true, all entries are updated for the runlist. A runlist buffer + * is built with all active channels/TSGs for the runlist and submitted to H/W. + * When #add is false, an empty runlist buffer is submitted to H/W. Submitting + * a NULL runlist results in Host expiring the current timeslices and + * effectively disabling scheduling for that runlist processor until the next + * runlist is submitted. + * + * @return 0 in case of success, < 0 in case of failure. + * @retval -ETIMEDOUT if transition to the new runlist takes too long, and + * #wait_for_finish was requested. + * @retval -E2BIG in case there are not enough entries in the runlist buffer + * to accommodate all active channels/TSGs. + */ int nvgpu_runlist_reload(struct gk20a *g, u32 runlist_id, - bool add, bool wait_for_finish); + bool add, bool wait_for_finish); + +/** + * @brief Reload a set of runlists + * + * @param g[in] The GPU driver struct owning the runlists. + * @param runlist_ids[in] Bitmask of runlists, one bit per runlist_id. + * @param add[in] True to submit a runlist buffer with all active + * channels. False to submit an empty runlist + * buffer. + * + * This function is similar to nvgpu_runlist_reload, but takes a set of + * runlists as a parameter. It also always waits for runlist update completion. + * + * @return 0 in case of success, < 0 in case of failure. + * @retval -ETIMEDOUT if runlist update takes too long for one of the runlists. + * @retval -E2BIG in case there are not enough entries in one runlist buffer + * to accommodate all active channels/TSGs. + */ int nvgpu_runlist_reload_ids(struct gk20a *g, u32 runlist_ids, bool add); +/** + * @brief Interleave level name. + * + * @param interleave_level Interleave level. + * (e.g. #NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW) + * + * @return String representing the name of runlist interleave level. + */ const char *nvgpu_runlist_interleave_level_name(u32 interleave_level); -void nvgpu_fifo_runlist_set_state(struct gk20a *g, u32 runlists_mask, +/** + * @brief Enable/disable a set of runlists + * + * @param g[in] The GPU driver struct owning the runlists. + * @param runlist_mask[in] Bitmask of runlist, one bit per runlist_id. + * @param runlist_state[in] #RUNLIST_ENABLE or #RUNLIST_DISABLE. + * + * If scheduling of a runlist is disabled, no new channels will be scheduled + * to run from that runlist. It does not stop the scheduler from finishing + * parsing a TSG that was in flight at the point scheduling was disabled, + * but no channels will be scheduled from that TSG. The currently running + * channel will continue to run, and any scheduler events for this runlist + * will continue to be handled. In particular, the PBDMA unit will continue + * processing methods for the channel, and the downstream engine will continue + * processing methods. + */ +void nvgpu_runlist_set_state(struct gk20a *g, u32 runlists_mask, u32 runlist_state); +/** + * @brief Initialize runlist context + * + * @param g[in] The GPU driver struct owning the runlists. + * + * Initializes runlist context for current GPU: + * - Determine number of runlists and max entries per runlists. + * - Determine active runlists, i.e. runlists that are mapped to one engine. + * - For each active runlist, + * - Build mapping between runlist_id (H/W) and runlist info. + * - Allocate runlist buffers. + * - Allocate bitmaps to track active channels and TSGs. + * - Determine bitmask of engines serviced by this runlist. + * - Determine bitmask of PBDMAs servicing this runlist. + * + * @return 0 in case of success, < 0 in case of failure. + * @retval -ENOMEM in case insufficient memory is available. + */ int nvgpu_runlist_setup_sw(struct gk20a *g); + +/** + * @brief De-initialize runlist context + * + * @param g[in] The GPU driver struct owning the runlists. + * + * Cleans up runlist context for current GPU: + * - Free runlist buffers. + * - Free bitmaps to track active channels and TSGs. + * - Free runlists. + */ void nvgpu_runlist_cleanup_sw(struct gk20a *g); +/** + * @brief Acquire lock for active runlists + * + * @param g[in] The GPU driver struct owning the runlists. + * + * Walk through runlist ids, and acquire runlist lock for runlists that are + * actually in use (i.e. mapped to one engine). + */ void nvgpu_runlist_lock_active_runlists(struct gk20a *g); + +/** + * @brief Release lock for active runlists + * + * @param g[in] The GPU driver struct owning the runlists. + * + * Walk through runlist ids, and release runlist lock for runlists that are + * actually in use (i.e. mapped to one engine). + */ void nvgpu_runlist_unlock_active_runlists(struct gk20a *g); +/** + * @brief Release lock for a set of runlists + * + * @param g[in] The GPU driver struct owning the runlists. + * @param runlists_mask[in] Set of runlists to release lock for. One bit + * per runlist_id. + * + * Walk through runlist ids, and release runlist lock for runlists that are + * actually in use (i.e. mapped to one engine). + */ +void nvgpu_runlist_unlock_runlists(struct gk20a *g, u32 runlists_mask); + +/** + * @brief Get list of runlists per engine/PBDMA/TSG + * + * @param g[in] The GPU driver struct owning the runlists. + * @param id[in] TSG or Channel Identifier (see #id_type). + * @param id_type[in] Identifier Type (#ID_TYPE_CHANNEL, #ID_TYPE_TSG + * or #ID_TYPE_UNKNOWN). + * @param act_eng_bitmask[in] Bitmask of active engines, one bit per + * engine id. + * @param pbdma_bitmask[in] Bitmask of PBDMAs, one bit per PBDMA id. + * + * If engines or PBDMAs are known (i.e. non-zero #act_eng_bitmask and/or + * #pbdma_bitmask), the function looks up for all runlists servicing those + * engines and/or PBDMAs. + * + * If #id_type is known (i.e. ID_TYPE_CHANNEL or ID_TYPE_TSG), the function + * looks up for the runlist servicing related channel/TSG. + * + * @return A bitmask of runlists servicing specified engines/PBDMAs/channel/TSG. + * @retval If both #id_type and engine/PBDMAs are known, the function returns + * the set of runlist servicing #id or engine/PBDMA. + * @retval If both #id_type and engines/PBDMAs are unknown (i.e. + * #ID_TYPE_UNKNOWN and both #act_eng_bitmask and #pbdma_bitmask are + * equal to 0), the function returns a bitmask of all active runlists. + */ u32 nvgpu_runlist_get_runlists_mask(struct gk20a *g, u32 id, unsigned int id_type, u32 act_eng_bitmask, u32 pbdma_bitmask); -void nvgpu_runlist_unlock_runlists(struct gk20a *g, u32 runlists_mask); - #endif /* NVGPU_RUNLIST_H */ diff --git a/drivers/gpu/nvgpu/os/linux/cde.c b/drivers/gpu/nvgpu/os/linux/cde.c index 9312a5a2b..11b07dad9 100644 --- a/drivers/gpu/nvgpu/os/linux/cde.c +++ b/drivers/gpu/nvgpu/os/linux/cde.c @@ -1344,7 +1344,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) ch = gk20a_open_new_channel_with_cb(g, gk20a_cde_finished_ctx_cb, cde_ctx, - RUNLIST_INVALID_ID, + NVGPU_INVALID_RUNLIST_ID, false); if (!ch) { nvgpu_warn(g, "cde: gk20a channel not available");