diff --git a/drivers/gpu/nvgpu/common/fifo/preempt.c b/drivers/gpu/nvgpu/common/fifo/preempt.c index a76a7a1bc..89d2db0d0 100644 --- a/drivers/gpu/nvgpu/common/fifo/preempt.c +++ b/drivers/gpu/nvgpu/common/fifo/preempt.c @@ -40,25 +40,22 @@ u32 nvgpu_preempt_get_timeout(struct gk20a *g) int nvgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg) { - struct nvgpu_fifo *f = &g->fifo; int ret = 0; #ifdef CONFIG_NVGPU_LS_PMU u32 token = PMU_INVALID_MUTEX_OWNER_ID; int mutex_ret = 0; #endif - u32 runlist_id; nvgpu_log_fn(g, "tsgid: %d", tsg->tsgid); - runlist_id = tsg->runlist_id; - if (runlist_id == NVGPU_INVALID_RUNLIST_ID) { + if (tsg->runlist == NULL) { return 0; } - nvgpu_mutex_acquire(&f->runlists[runlist_id]->runlist_lock); + nvgpu_mutex_acquire(&tsg->runlist->runlist_lock); - /* WAR for Bug 2065990 */ - nvgpu_tsg_disable_sched(g, tsg); + nvgpu_runlist_set_state(g, BIT32(tsg->runlist->runlist_id), + RUNLIST_DISABLED); #ifdef CONFIG_NVGPU_LS_PMU mutex_ret = nvgpu_pmu_lock_acquire(g, g->pmu, PMU_MUTEX_ID_FIFO, &token); @@ -80,10 +77,10 @@ int nvgpu_fifo_preempt_tsg(struct gk20a *g, struct nvgpu_tsg *tsg) } } #endif - /* WAR for Bug 2065990 */ - nvgpu_tsg_enable_sched(g, tsg); + nvgpu_runlist_set_state(g, BIT32(tsg->runlist->runlist_id), + RUNLIST_ENABLED); - nvgpu_mutex_release(&f->runlists[runlist_id]->runlist_lock); + nvgpu_mutex_release(&tsg->runlist->runlist_lock); if (ret != 0) { if (nvgpu_platform_is_silicon(g)) { @@ -115,8 +112,6 @@ int nvgpu_preempt_channel(struct gk20a *g, struct nvgpu_channel *ch) int nvgpu_preempt_poll_tsg_on_pbdma(struct gk20a *g, struct nvgpu_tsg *tsg) { - struct nvgpu_fifo *f = &g->fifo; - u32 runlist_id; unsigned long runlist_served_pbdmas; unsigned long pbdma_id_bit; u32 tsgid, pbdma_id; @@ -126,8 +121,7 @@ int nvgpu_preempt_poll_tsg_on_pbdma(struct gk20a *g, } tsgid = tsg->tsgid; - runlist_id = tsg->runlist_id; - runlist_served_pbdmas = f->runlists[runlist_id]->pbdma_bitmask; + runlist_served_pbdmas = tsg->runlist->pbdma_bitmask; for_each_set_bit(pbdma_id_bit, &runlist_served_pbdmas, nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA)) { diff --git a/drivers/gpu/nvgpu/common/fifo/runlist.c b/drivers/gpu/nvgpu/common/fifo/runlist.c index d4fc8756c..fe1a685d9 100644 --- a/drivers/gpu/nvgpu/common/fifo/runlist.c +++ b/drivers/gpu/nvgpu/common/fifo/runlist.c @@ -876,9 +876,16 @@ u32 nvgpu_runlist_get_runlists_mask(struct gk20a *g, u32 id, if (id_type != ID_TYPE_UNKNOWN) { if (id_type == ID_TYPE_TSG) { - runlists_mask |= BIT32(f->tsg[id].runlist_id); + runlist = f->tsg[id].runlist; } else { - runlists_mask |= BIT32(f->channel[id].runlist->runlist_id); + runlist = f->channel[id].runlist; + } + + if (runlist == NULL) { + /* Warning on Linux, real assert on QNX. */ + nvgpu_assert(runlist != NULL); + } else { + runlists_mask |= BIT32(runlist->runlist_id); } } else { if (bitmask_disabled) { diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index c0f475971..e164026a1 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -113,14 +113,17 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch) ch->runqueue_sel = 1; } - /* all the channel part of TSG should need to be same runlist_id */ - if (tsg->runlist_id == NVGPU_INVALID_TSG_ID) { - tsg->runlist_id = ch->runlist->runlist_id; + /* + * All the channels in a TSG must share the same runlist. + */ + if (tsg->runlist == NULL) { + tsg->runlist = ch->runlist; } else { - if (tsg->runlist_id != ch->runlist->runlist_id) { + if (tsg->runlist != ch->runlist) { nvgpu_err(tsg->g, - "runlist_id mismatch ch[%d] tsg[%d]", - ch->runlist->runlist_id, tsg->runlist_id); + "runlist_id mismatch ch[%d] tsg[%d]", + ch->runlist->runlist_id, + tsg->runlist->runlist_id); return -EINVAL; } } @@ -673,11 +676,11 @@ int nvgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 level) tsg->interleave_level = level; /* TSG may not be bound yet */ - if (tsg->runlist_id == NVGPU_INVALID_RUNLIST_ID) { + if (tsg->runlist == NULL) { return 0; } - return g->ops.runlist.reload(g, g->fifo.runlists[tsg->runlist_id], true, true); + return g->ops.runlist.reload(g, tsg->runlist, true, true); } int nvgpu_tsg_set_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us) @@ -695,11 +698,11 @@ int nvgpu_tsg_set_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us) tsg->timeslice_us = timeslice_us; /* TSG may not be bound yet */ - if (tsg->runlist_id == NVGPU_INVALID_RUNLIST_ID) { + if (tsg->runlist == NULL) { return 0; } - return g->ops.runlist.reload(g, g->fifo.runlists[tsg->runlist_id], true, true); + return g->ops.runlist.reload(g, tsg->runlist, true, true); } u32 nvgpu_tsg_get_timeslice(struct nvgpu_tsg *tsg) @@ -713,19 +716,6 @@ u32 nvgpu_tsg_default_timeslice_us(struct gk20a *g) return NVGPU_TSG_TIMESLICE_DEFAULT_US; } -void nvgpu_tsg_enable_sched(struct gk20a *g, struct nvgpu_tsg *tsg) -{ - nvgpu_runlist_set_state(g, BIT32(tsg->runlist_id), - RUNLIST_ENABLED); - -} - -void nvgpu_tsg_disable_sched(struct gk20a *g, struct nvgpu_tsg *tsg) -{ - nvgpu_runlist_set_state(g, BIT32(tsg->runlist_id), - RUNLIST_DISABLED); -} - static void nvgpu_tsg_release_used_tsg(struct nvgpu_fifo *f, struct nvgpu_tsg *tsg) { @@ -778,7 +768,7 @@ int nvgpu_tsg_open_common(struct gk20a *g, struct nvgpu_tsg *tsg, pid_t pid) tsg->vm = NULL; tsg->interleave_level = NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW; tsg->timeslice_us = g->ops.tsg.default_timeslice_us(g); - tsg->runlist_id = NVGPU_INVALID_TSG_ID; + tsg->runlist = NULL; #ifdef CONFIG_NVGPU_DEBUGGER tsg->sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE; #endif diff --git a/drivers/gpu/nvgpu/hal/fifo/preempt_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/preempt_gv11b_fusa.c index 83b299e6c..74fdb83e2 100644 --- a/drivers/gpu/nvgpu/hal/fifo/preempt_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/preempt_gv11b_fusa.c @@ -322,7 +322,7 @@ int gv11b_fifo_is_preempt_pending(struct gk20a *g, u32 id, u32 tsgid; if (id_type == ID_TYPE_TSG) { - rl = f->runlists[f->tsg[id].runlist_id]; + rl = f->tsg[id].runlist; tsgid = id; } else { rl = f->channel[id].runlist; diff --git a/drivers/gpu/nvgpu/hal/fifo/tsg_gk20a.c b/drivers/gpu/nvgpu/hal/fifo/tsg_gk20a.c index 99d84c0e1..7cd1cbe9b 100644 --- a/drivers/gpu/nvgpu/hal/fifo/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/hal/fifo/tsg_gk20a.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "hal/fifo/tsg_gk20a.h" @@ -32,7 +33,16 @@ void gk20a_tsg_enable(struct nvgpu_tsg *tsg) struct gk20a *g = tsg->g; struct nvgpu_channel *ch; - nvgpu_tsg_disable_sched(g, tsg); + if (tsg->runlist == NULL) { + /* + * Enabling a TSG that has no runlist (implies no channels) + * is just a noop. + */ + return; + } + + nvgpu_runlist_set_state(g, BIT32(tsg->runlist->runlist_id), + RUNLIST_DISABLED); /* * Due to h/w bug that exists in Maxwell and Pascal, @@ -63,5 +73,6 @@ void gk20a_tsg_enable(struct nvgpu_tsg *tsg) } nvgpu_rwsem_up_read(&tsg->ch_list_lock); - nvgpu_tsg_enable_sched(g, tsg); + nvgpu_runlist_set_state(g, BIT32(tsg->runlist->runlist_id), + RUNLIST_ENABLED); } diff --git a/drivers/gpu/nvgpu/hal/fifo/tsg_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/tsg_gv11b_fusa.c index 1811d90d3..9917a9884 100644 --- a/drivers/gpu/nvgpu/hal/fifo/tsg_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/tsg_gv11b_fusa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -88,12 +89,14 @@ void gv11b_tsg_bind_channel_eng_method_buffers(struct nvgpu_tsg *tsg, struct gk20a *g = tsg->g; u64 gpu_va; + nvgpu_assert(tsg->runlist != NULL); + if (tsg->eng_method_buffers == NULL) { nvgpu_log_info(g, "eng method buffer NULL"); return; } - if (tsg->runlist_id == nvgpu_engine_get_fast_ce_runlist_id(g)) { + if (tsg->runlist->runlist_id == nvgpu_engine_get_fast_ce_runlist_id(g)) { gpu_va = tsg->eng_method_buffers[ASYNC_CE_RUNQUE].gpu_va; } else { gpu_va = tsg->eng_method_buffers[GR_RUNQUE].gpu_va; diff --git a/drivers/gpu/nvgpu/include/nvgpu/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/tsg.h index 962ce924e..7938ab8f6 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/tsg.h @@ -53,6 +53,7 @@ struct nvgpu_channel; struct nvgpu_gr_ctx; struct nvgpu_channel_hw_state; struct nvgpu_profiler_object; +struct nvgpu_runlist; #ifdef CONFIG_NVGPU_CHANNEL_TSG_CONTROL enum nvgpu_event_id_type; @@ -148,13 +149,10 @@ struct nvgpu_tsg { u32 tsgid; /** - * There is maximum number of runlists defined by the h/w. Usually it - * is one runlist per engine (graphics and grcopy share a runlist). - * The runlist_id specifies the h/w runlist to which a runlist in - * memory is being submitted. Each runlist serves a specific set of - * engines. Refer to device.h. + * Runlist this TSG will be assigned to. */ - u32 runlist_id; + struct nvgpu_runlist *runlist; + /** tgid (OS specific) of the process that openend the TSG. */ pid_t tgid; /** @@ -528,28 +526,6 @@ int nvgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 level); */ u32 nvgpu_tsg_default_timeslice_us(struct gk20a *g); -/** - * @brief Enable h/w runlist scheduler corresponding to the runlist_id - * of the TSG. - * - * @param g [in] The GPU driver struct. - * @param tsg [in] Pointer to the TSG struct. - * - * Enable h/w runlist scheduler for #nvgpu_tsg.runlist_id. - */ -void nvgpu_tsg_enable_sched(struct gk20a *g, struct nvgpu_tsg *tsg); - -/** - * @brief Disable h/w runlist scheduler corresponding to the runlist_id - * of the TSG. - * - * @param g [in] The GPU driver struct. - * @param tsg [in] Pointer to the TSG struct. - * - * Disable h/w runlist scheduler for #nvgpu_tsg.runlist_id. - */ -void nvgpu_tsg_disable_sched(struct gk20a *g, struct nvgpu_tsg *tsg); - /** * @brief Allocate zero initialized memory to store SM errors. *