mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: modify wait_pending
The wait_pending HAL is now modified to simply check the pending status of a given runlist. The while loop is removed from this HAL. A new function nvgpu_runlist_wait_pending_legacy() is added that emulates the older wait_pending() HAL. nvgpu_runlist_tick() is modified to accept a 64 bit "preempt_grace_ns" value. These changes prepare for upcoming control-fifo parser changes. Jira NVGPU-8619 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Change-Id: If3f288eb6f2181743c53b657219b3b30d56d26bc Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2766100 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
1e2817e022
commit
143034daab
@@ -453,11 +453,31 @@ void nvgpu_runlist_swap_mem(struct gk20a *g, struct nvgpu_runlist_domain *domain
|
||||
nvgpu_spinlock_release(&domain->lock);
|
||||
}
|
||||
|
||||
static int nvgpu_runlist_domain_actual_submit(struct gk20a *g, struct nvgpu_runlist *rl,
|
||||
bool wait_for_finish)
|
||||
int nvgpu_runlist_wait_pending_legacy(struct gk20a *g, struct nvgpu_runlist *rl)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nvgpu_timeout timeout;
|
||||
u32 delay = POLL_DELAY_MIN_US;
|
||||
int ret;
|
||||
|
||||
nvgpu_timeout_init_cpu_timer(g, &timeout, nvgpu_get_poll_timeout(g));
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
do {
|
||||
if (g->ops.runlist.check_pending(g, rl) == 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Avoid sleeping */
|
||||
nvgpu_usleep_range(delay, delay * 2U);
|
||||
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
|
||||
} while (nvgpu_timeout_expired(&timeout) == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nvgpu_runlist_domain_actual_submit(struct gk20a *g, struct nvgpu_runlist *rl)
|
||||
{
|
||||
rl_dbg(g, "Runlist[%u]: submitting domain[%llu]",
|
||||
rl->id, rl->domain->domain_id);
|
||||
|
||||
@@ -467,18 +487,6 @@ static int nvgpu_runlist_domain_actual_submit(struct gk20a *g, struct nvgpu_runl
|
||||
nvgpu_spinlock_acquire(&rl->domain->lock);
|
||||
g->ops.runlist.hw_submit(g, rl);
|
||||
nvgpu_spinlock_release(&rl->domain->lock);
|
||||
|
||||
if (wait_for_finish) {
|
||||
ret = g->ops.runlist.wait_pending(g, rl);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
nvgpu_err(g, "runlist %d update timeout", rl->id);
|
||||
/* trigger runlist update timeout recovery */
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nvgpu_runlist_update_mem_locked(struct gk20a *g, struct nvgpu_runlist *rl,
|
||||
@@ -594,7 +602,7 @@ int nvgpu_runlist_reschedule(struct nvgpu_channel *ch, bool preempt_next,
|
||||
}
|
||||
}
|
||||
|
||||
if (g->ops.runlist.wait_pending(g, runlist) != 0) {
|
||||
if (nvgpu_runlist_wait_pending_legacy(g, runlist) != 0) {
|
||||
nvgpu_err(g, "wait pending failed for runlist %u",
|
||||
runlist->id);
|
||||
}
|
||||
@@ -668,19 +676,15 @@ static int nvgpu_runlist_do_update(struct gk20a *g, struct nvgpu_runlist *rl,
|
||||
/*
|
||||
* This is expected to be called only when device is powered on.
|
||||
*/
|
||||
static int runlist_submit_powered(struct gk20a *g, struct nvgpu_runlist *runlist,
|
||||
struct nvgpu_runlist_domain *next_domain, bool wait_for_finish)
|
||||
static void runlist_submit_powered(struct gk20a *g, struct nvgpu_runlist *runlist,
|
||||
struct nvgpu_runlist_domain *next_domain)
|
||||
{
|
||||
int err;
|
||||
|
||||
runlist->domain = next_domain;
|
||||
|
||||
rl_dbg(g, "Runlist[%u]: switching to domain %llu",
|
||||
runlist->id, next_domain->domain_id);
|
||||
|
||||
err = nvgpu_runlist_domain_actual_submit(g, runlist, wait_for_finish);
|
||||
|
||||
return err;
|
||||
nvgpu_runlist_domain_actual_submit(g, runlist);
|
||||
}
|
||||
|
||||
int nvgpu_rl_domain_sync_submit(struct gk20a *g, struct nvgpu_runlist *runlist,
|
||||
@@ -692,26 +696,28 @@ int nvgpu_rl_domain_sync_submit(struct gk20a *g, struct nvgpu_runlist *runlist,
|
||||
next_domain = runlist->shadow_rl_domain;
|
||||
}
|
||||
|
||||
err = runlist_submit_powered(g, runlist, next_domain, wait_for_finish);
|
||||
runlist_submit_powered(g, runlist, next_domain);
|
||||
if (wait_for_finish) {
|
||||
err = nvgpu_runlist_wait_pending_legacy(g, runlist);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "runlist %d update timeout", runlist->id);
|
||||
/* trigger runlist update timeout recovery */
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int runlist_switch_domain_and_submit(struct gk20a *g,
|
||||
struct nvgpu_runlist *runlist, struct nvgpu_runlist_domain *rl_domain)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = runlist_submit_powered(g, runlist, rl_domain, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nvgpu_runlist_tick(struct gk20a *g, struct nvgpu_runlist_domain **rl_domain)
|
||||
int nvgpu_runlist_tick(struct gk20a *g, struct nvgpu_runlist_domain **rl_domain,
|
||||
u64 preempt_grace_ns)
|
||||
{
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
u32 i;
|
||||
int err = 0;
|
||||
int ret = 0;
|
||||
int err = -ETIMEDOUT;
|
||||
u64 start_time = nvgpu_safe_cast_s64_to_u64(nvgpu_current_time_ns());
|
||||
u64 current_time;
|
||||
|
||||
rl_dbg(g, "domain tick");
|
||||
|
||||
@@ -719,11 +725,23 @@ void nvgpu_runlist_tick(struct gk20a *g, struct nvgpu_runlist_domain **rl_domain
|
||||
struct nvgpu_runlist *runlist;
|
||||
|
||||
runlist = &f->active_runlists[i];
|
||||
err = runlist_switch_domain_and_submit(g, runlist, rl_domain[i]);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "Failed to schedule domain [%llu]", rl_domain[i]->domain_id);
|
||||
}
|
||||
runlist_submit_powered(g, runlist, rl_domain[i]);
|
||||
|
||||
do {
|
||||
ret = g->ops.runlist.check_pending(g, runlist);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
current_time = nvgpu_safe_cast_s64_to_u64(nvgpu_current_time_ns());
|
||||
} while ((preempt_grace_ns == 0ULL)
|
||||
|| (nvgpu_safe_sub_u64(current_time, start_time) <= preempt_grace_ns));
|
||||
}
|
||||
|
||||
if (i == f->num_runlists) {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int nvgpu_runlist_update(struct gk20a *g, struct nvgpu_runlist *rl,
|
||||
|
||||
@@ -144,7 +144,7 @@ static u64 nvgpu_nvs_tick(struct gk20a *g)
|
||||
timeslice = nvs_next->timeslice_ns;
|
||||
nvgpu_domain_next = nvs_next->priv;
|
||||
|
||||
nvgpu_runlist_tick(g, nvgpu_domain_next->rl_domains);
|
||||
(void)nvgpu_runlist_tick(g, nvgpu_domain_next->rl_domains, 0ULL);
|
||||
sched->active_domain = nvs_next->priv;
|
||||
|
||||
nvgpu_mutex_release(&g->sched_mutex);
|
||||
|
||||
@@ -33,7 +33,7 @@ struct nvgpu_runlist;
|
||||
u32 ga10b_runlist_count_max(struct gk20a *g);
|
||||
u32 ga10b_runlist_length_max(struct gk20a *g);
|
||||
void ga10b_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int ga10b_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int ga10b_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask,
|
||||
u32 runlist_state);
|
||||
u32 ga10b_get_runlist_aperture(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
|
||||
@@ -81,25 +81,14 @@ void ga10b_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
runlist_submit_length_f(runlist->domain->mem_hw->count));
|
||||
}
|
||||
|
||||
int ga10b_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
int ga10b_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
{
|
||||
struct nvgpu_timeout timeout;
|
||||
u32 delay = POLL_DELAY_MIN_US;
|
||||
int ret;
|
||||
int ret = 1;
|
||||
|
||||
nvgpu_timeout_init_cpu_timer(g, &timeout, nvgpu_get_poll_timeout(g));
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
do {
|
||||
if ((nvgpu_runlist_readl(g, runlist, runlist_submit_info_r()) &
|
||||
if ((nvgpu_runlist_readl(g, runlist, runlist_submit_info_r()) &
|
||||
runlist_submit_info_pending_true_f()) == 0U) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
nvgpu_usleep_range(delay, delay * 2U);
|
||||
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
|
||||
} while (nvgpu_timeout_expired(&timeout) == 0);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2011-2022, 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"),
|
||||
@@ -41,7 +41,7 @@ u32 gk20a_runlist_count_max(struct gk20a *g);
|
||||
|
||||
u32 gk20a_runlist_length_max(struct gk20a *g);
|
||||
void gk20a_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int gk20a_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int gk20a_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
void gk20a_runlist_write_state(struct gk20a *g, u32 runlists_mask,
|
||||
u32 runlist_state);
|
||||
|
||||
|
||||
@@ -61,29 +61,13 @@ void gk20a_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
nvgpu_spinlock_release(&g->fifo.runlist_submit_lock);
|
||||
}
|
||||
|
||||
int gk20a_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
int gk20a_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
{
|
||||
struct nvgpu_timeout timeout;
|
||||
u32 delay = POLL_DELAY_MIN_US;
|
||||
int ret = 0;
|
||||
int ret = 1;
|
||||
|
||||
nvgpu_timeout_init_cpu_timer(g, &timeout, nvgpu_get_poll_timeout(g));
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
do {
|
||||
if ((nvgpu_readl(g, fifo_eng_runlist_r(runlist->id)) &
|
||||
fifo_eng_runlist_pending_true_f()) == 0U) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
nvgpu_usleep_range(delay, delay * 2U);
|
||||
delay = min_t(u32, delay << 1U, POLL_DELAY_MAX_US);
|
||||
} while (nvgpu_timeout_expired(&timeout) == 0);
|
||||
|
||||
if (ret != 0) {
|
||||
nvgpu_err(g, "runlist wait timeout: runlist id: %u",
|
||||
runlist->id);
|
||||
if ((nvgpu_readl(g, fifo_eng_runlist_r(runlist->id)) &
|
||||
fifo_eng_runlist_pending_true_f()) == 0U) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2018-2022, 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"),
|
||||
@@ -61,25 +61,14 @@ void tu104_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
fifo_runlist_submit_length_f(runlist->domain->mem_hw->count));
|
||||
}
|
||||
|
||||
int tu104_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
int tu104_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist)
|
||||
{
|
||||
struct nvgpu_timeout timeout;
|
||||
u32 delay = POLL_DELAY_MIN_US;
|
||||
int ret;
|
||||
int ret = 1;
|
||||
|
||||
nvgpu_timeout_init_cpu_timer(g, &timeout, nvgpu_get_poll_timeout(g));
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
do {
|
||||
if ((nvgpu_readl(g, fifo_runlist_submit_info_r(runlist->id)) &
|
||||
fifo_runlist_submit_info_pending_true_f()) == 0U) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
nvgpu_usleep_range(delay, delay * 2U);
|
||||
delay = min_t(u32, delay << 1, POLL_DELAY_MAX_US);
|
||||
} while (nvgpu_timeout_expired(&timeout) == 0);
|
||||
if ((nvgpu_readl(g, fifo_runlist_submit_info_r(runlist->id)) &
|
||||
fifo_runlist_submit_info_pending_true_f()) == 0U) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2018-2022, 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"),
|
||||
@@ -30,6 +30,6 @@ struct nvgpu_runlist;
|
||||
|
||||
u32 tu104_runlist_count_max(struct gk20a *g);
|
||||
void tu104_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int tu104_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int tu104_runlist_check_pending(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
|
||||
#endif /* NVGPU_RUNLIST_FIFO_TU104_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* GA10B runlist
|
||||
*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019-2022, 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"),
|
||||
|
||||
@@ -1151,7 +1151,7 @@ static const struct gops_runlist ga100_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = ga100_runlist_hw_submit,
|
||||
.wait_pending = ga10b_runlist_wait_pending,
|
||||
.check_pending = ga10b_runlist_check_pending,
|
||||
.write_state = ga10b_runlist_write_state,
|
||||
.get_runlist_id = ga10b_runlist_get_runlist_id,
|
||||
.get_engine_id_from_rleng_id = ga10b_runlist_get_engine_id_from_rleng_id,
|
||||
|
||||
@@ -1165,7 +1165,7 @@ static const struct gops_runlist ga10b_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = ga10b_runlist_hw_submit,
|
||||
.wait_pending = ga10b_runlist_wait_pending,
|
||||
.check_pending = ga10b_runlist_check_pending,
|
||||
.write_state = ga10b_runlist_write_state,
|
||||
.get_runlist_id = ga10b_runlist_get_runlist_id,
|
||||
.get_runlist_aperture = ga10b_get_runlist_aperture,
|
||||
|
||||
@@ -710,7 +710,7 @@ static const struct gops_runlist gm20b_ops_runlist = {
|
||||
.get_tsg_entry = gk20a_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gk20a_runlist_get_ch_entry,
|
||||
.hw_submit = gk20a_runlist_hw_submit,
|
||||
.wait_pending = gk20a_runlist_wait_pending,
|
||||
.check_pending = gk20a_runlist_check_pending,
|
||||
.write_state = gk20a_runlist_write_state,
|
||||
.init_enginfo = nvgpu_runlist_init_enginfo,
|
||||
.get_tsg_max_timeslice = gk20a_runlist_max_timeslice,
|
||||
|
||||
@@ -989,7 +989,7 @@ static const struct gops_runlist gv11b_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = gk20a_runlist_hw_submit,
|
||||
.wait_pending = gk20a_runlist_wait_pending,
|
||||
.check_pending = gk20a_runlist_check_pending,
|
||||
.write_state = gk20a_runlist_write_state,
|
||||
.init_enginfo = nvgpu_runlist_init_enginfo,
|
||||
.get_tsg_max_timeslice = gv11b_runlist_max_timeslice,
|
||||
|
||||
@@ -1044,7 +1044,7 @@ static const struct gops_runlist tu104_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = tu104_runlist_hw_submit,
|
||||
.wait_pending = tu104_runlist_wait_pending,
|
||||
.check_pending = tu104_runlist_check_pending,
|
||||
.write_state = gk20a_runlist_write_state,
|
||||
.init_enginfo = nvgpu_runlist_init_enginfo,
|
||||
.get_tsg_max_timeslice = gv11b_runlist_max_timeslice,
|
||||
|
||||
@@ -710,7 +710,7 @@ static const struct gops_runlist vgpu_ga10b_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = NULL,
|
||||
.wait_pending = NULL,
|
||||
.check_pending = NULL,
|
||||
.init_enginfo = nvgpu_runlist_init_enginfo,
|
||||
.get_max_channels_per_tsg = gv11b_runlist_get_max_channels_per_tsg,
|
||||
};
|
||||
|
||||
@@ -677,7 +677,7 @@ static const struct gops_runlist vgpu_gv11b_ops_runlist = {
|
||||
.get_tsg_entry = gv11b_runlist_get_tsg_entry,
|
||||
.get_ch_entry = gv11b_runlist_get_ch_entry,
|
||||
.hw_submit = NULL,
|
||||
.wait_pending = NULL,
|
||||
.check_pending = NULL,
|
||||
.init_enginfo = nvgpu_runlist_init_enginfo,
|
||||
.get_tsg_max_timeslice = gv11b_runlist_max_timeslice,
|
||||
.get_max_channels_per_tsg = gv11b_runlist_get_max_channels_per_tsg,
|
||||
|
||||
@@ -93,7 +93,7 @@ struct gops_runlist {
|
||||
u32 *runlist, u32 timeslice);
|
||||
void (*get_ch_entry)(struct nvgpu_channel *ch, u32 *runlist);
|
||||
void (*hw_submit)(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int (*wait_pending)(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
int (*check_pending)(struct gk20a *g, struct nvgpu_runlist *runlist);
|
||||
void (*write_state)(struct gk20a *g, u32 runlists_mask,
|
||||
u32 runlist_state);
|
||||
int (*reschedule)(struct nvgpu_channel *ch, bool preempt_next);
|
||||
|
||||
@@ -198,7 +198,7 @@ struct nvgpu_runlist {
|
||||
const struct nvgpu_device *rl_dev_list[RLENG_PER_RUNLIST_SIZE];
|
||||
/** @endcond DOXYGEN_SHOULD_SKIP_THIS */
|
||||
};
|
||||
|
||||
int nvgpu_runlist_wait_pending_legacy(struct gk20a *g, struct nvgpu_runlist *rl);
|
||||
bool nvgpu_rl_domain_exists(struct gk20a *g, const char *name);
|
||||
struct nvgpu_runlist_domain *nvgpu_runlist_domain_alloc(struct gk20a *g,
|
||||
u64 domain_id);
|
||||
@@ -233,7 +233,20 @@ nvgpu_runlist_domain_from_domains_list(struct nvgpu_list_node *node)
|
||||
((uintptr_t)node - offsetof(struct nvgpu_runlist_domain, domains_list));
|
||||
}
|
||||
|
||||
void nvgpu_runlist_tick(struct gk20a *g, struct nvgpu_runlist_domain **rl_domain);
|
||||
/**
|
||||
* @brief Submit the nvgpu_runlist_domain instance corresponding to a given domain.
|
||||
*
|
||||
* Attempts to switch all the rl_domains and wait appropriately. If preempt_grace_ns
|
||||
* equals 0, the attempt continues infinitely, otherwise it would timeout if the
|
||||
* total time exceeds preempt_grace_ns.
|
||||
*
|
||||
* @param g Global gk20a struct
|
||||
* @param rl_domain > Actual array of rl domain thats meant to be scheduled.
|
||||
* @param preempt_grace_ns -> Max Grace Period for Domain switches.
|
||||
* @return int 0 if domain switch was successful, else -ETIMEDOUT
|
||||
*/
|
||||
int nvgpu_runlist_tick(struct gk20a *g, struct nvgpu_runlist_domain **rl_domain,
|
||||
u64 preempt_grace_ns);
|
||||
|
||||
/**
|
||||
* @brief Rebuild runlist
|
||||
|
||||
@@ -28,7 +28,8 @@ gk20a_ramin_alloc_size
|
||||
gk20a_ramin_base_shift
|
||||
gk20a_runlist_length_max
|
||||
gk20a_runlist_hw_submit
|
||||
gk20a_runlist_wait_pending
|
||||
nvgpu_runlist_wait_pending_legacy
|
||||
gk20a_runlist_check_pending
|
||||
gk20a_runlist_write_state
|
||||
gk20a_userd_entry_size
|
||||
gk20a_vm_release_share
|
||||
|
||||
@@ -27,7 +27,8 @@ gk20a_ramin_alloc_size
|
||||
gk20a_ramin_base_shift
|
||||
gk20a_runlist_length_max
|
||||
gk20a_runlist_hw_submit
|
||||
gk20a_runlist_wait_pending
|
||||
nvgpu_runlist_wait_pending_legacy
|
||||
gk20a_runlist_check_pending
|
||||
gk20a_runlist_write_state
|
||||
gk20a_userd_entry_size
|
||||
gk20a_vm_release_share
|
||||
|
||||
@@ -744,7 +744,7 @@ test_fifo_init_support.init_support=0
|
||||
test_fifo_remove_support.remove_support=0
|
||||
test_gk20a_runlist_hw_submit.hw_submit=0
|
||||
test_gk20a_runlist_length_max.length_max=0
|
||||
test_gk20a_runlist_wait_pending.wait_pending=0
|
||||
test_gk20a_runlist_wait_pending.check_pending=0
|
||||
test_gk20a_runlist_write_state.write_state=0
|
||||
|
||||
[nvgpu_runlist_gv11b]
|
||||
|
||||
@@ -177,22 +177,22 @@ int test_gk20a_runlist_wait_pending(struct unit_module *m,
|
||||
|
||||
/* no wait */
|
||||
ctx->count = 0;
|
||||
err = gk20a_runlist_wait_pending(g, runlist);
|
||||
err = nvgpu_runlist_wait_pending_legacy(g, runlist);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
/* 1 loop */
|
||||
ctx->count = 1;
|
||||
err = gk20a_runlist_wait_pending(g, runlist);
|
||||
err = nvgpu_runlist_wait_pending_legacy(g, runlist);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
/* 2 loops */
|
||||
ctx->count = 2;
|
||||
err = gk20a_runlist_wait_pending(g, runlist);
|
||||
err = nvgpu_runlist_wait_pending_legacy(g, runlist);
|
||||
unit_assert(err == 0, goto done);
|
||||
|
||||
/* timeout */
|
||||
ctx->count = U32_MAX;
|
||||
err = gk20a_runlist_wait_pending(g, runlist);
|
||||
err = nvgpu_runlist_wait_pending_legacy(g, runlist);
|
||||
unit_assert(err == -ETIMEDOUT, goto done);
|
||||
|
||||
ret = UNIT_SUCCESS;
|
||||
@@ -235,7 +235,7 @@ struct unit_module_test nvgpu_runlist_gk20a_tests[] = {
|
||||
UNIT_TEST(init_support, test_fifo_init_support, NULL, 0),
|
||||
UNIT_TEST(length_max, test_gk20a_runlist_length_max, NULL, 0),
|
||||
UNIT_TEST(hw_submit, test_gk20a_runlist_hw_submit, NULL, 0),
|
||||
UNIT_TEST(wait_pending, test_gk20a_runlist_wait_pending, NULL, 0),
|
||||
UNIT_TEST(check_pending, test_gk20a_runlist_wait_pending, NULL, 0),
|
||||
UNIT_TEST(write_state, test_gk20a_runlist_write_state, NULL, 0),
|
||||
UNIT_TEST(remove_support, test_fifo_remove_support, NULL, 0),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019-2022, 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"),
|
||||
@@ -76,28 +76,28 @@ int test_gk20a_runlist_hw_submit(struct unit_module *m,
|
||||
/**
|
||||
* Test specification for: test_gk20a_runlist_wait_pending
|
||||
*
|
||||
* Description: Branch coverage for gk20a_runlist_wait_pending
|
||||
* Description: Branch coverage for nvgpu_runlist_wait_pending_legacy
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_runlist.wait_pending, gk20a_runlist_wait_pending
|
||||
* Targets: gops_runlist.check_pending, nvgpu_runlist_wait_pending_legacy
|
||||
*
|
||||
* Input: test_fifo_init_support() run for this GPU
|
||||
*
|
||||
* Steps:
|
||||
* - Check case where runlist is not pending (not wait).
|
||||
* - Set register to indicate that runlist is NOT pending.
|
||||
* - Call gk20a_runlist_wait_pending.
|
||||
* - Call nvgpu_runlist_wait_pending_legacy.
|
||||
* - Check case where some polling is needed until runlist is not pending:
|
||||
* - Install register IO callbacks in order to control
|
||||
* value read from fifo_eng_runlist_r register.
|
||||
* - Configure callback to clear pending bit after one nvgpu_readl.
|
||||
* - Call gk20a_runlist_wait_pending.
|
||||
* - Call nvgpu_runlist_wait_pending_legacy.
|
||||
* - Configure callback to clear pending bit after two nvgpu_readl.
|
||||
* - Call gk20a_runlist_wait_pending.
|
||||
* - Call nvgpu_runlist_wait_pending_legacy.
|
||||
* - Check case where polling times out:
|
||||
* - Set register to indicate that runlist is pending.
|
||||
* - Call gk20a_runlist_wait_pending.
|
||||
* - Call nvgpu_runlist_wait_pending_legacy.
|
||||
*
|
||||
* Output: Returns PASS if all branches gave expected results. FAIL otherwise.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user