gpu: nvgpu: Update runlist_id in TSG

Update the runlist_id field in struct tsg to now be a pointer to
the relevant runlist. This further cleans up the rampant use of
runlist_ids throughout the driver.

Change-Id: I3dce990f198d534a80caa9ca95982255dcf104ad
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2470305
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Tejal Kudav <tkudav@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Alex Waterman
2020-12-31 23:01:58 -06:00
committed by mobile promotions
parent d03bd05c90
commit bd1b395b5c
7 changed files with 54 additions and 73 deletions

View File

@@ -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)) {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;

View File

@@ -24,6 +24,7 @@
#include <nvgpu/channel.h>
#include <nvgpu/tsg.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/runlist.h>
#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);
}

View File

@@ -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 <nvgpu/channel.h>
#include <nvgpu/engines.h>
#include <nvgpu/runlist.h>
#include <nvgpu/nvgpu_mem.h>
#include <nvgpu/tsg.h>
#include <nvgpu/dma.h>
@@ -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;

View File

@@ -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.
*