mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: allow managing runlist domains
Add support for adding and deleting domains for all runlists together. The core scheduler logic will control runlist domains. Initially, however, it may be necessary to only actually schedule only the GR runlist, but keeping the runlist code agnostic of such scheduling logic helps isolate the control complexity. NVGPU-6425 Change-Id: Id6039bd37a293a2cf3eaee5ed84d35459e8b89e7 Signed-off-by: Konsta Hölttä <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2628049 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
3af33f2454
commit
6de716a196
@@ -777,6 +777,52 @@ static void nvgpu_runlist_domain_free(struct gk20a *g,
|
||||
nvgpu_kfree(g, domain);
|
||||
}
|
||||
|
||||
int nvgpu_rl_domain_delete(struct gk20a *g, const char *name)
|
||||
{
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
u32 i;
|
||||
struct nvgpu_runlist *runlist;
|
||||
|
||||
for (i = 0; i < f->num_runlists; i++) {
|
||||
struct nvgpu_runlist_domain *domain;
|
||||
|
||||
runlist = &f->active_runlists[i];
|
||||
|
||||
nvgpu_mutex_acquire(&runlist->runlist_lock);
|
||||
domain = nvgpu_rl_domain_get(g, i, name);
|
||||
if (domain != NULL) {
|
||||
struct nvgpu_runlist_domain *first;
|
||||
struct nvgpu_runlist_domain *last;
|
||||
|
||||
/*
|
||||
* For now there has to be at least one domain, or else
|
||||
* we'd have to explicitly prepare for no domains and
|
||||
* submit nothing to the runlist HW in various corner
|
||||
* cases. Don't allow deletion if this is the last one.
|
||||
*/
|
||||
first = nvgpu_list_first_entry(&runlist->domains,
|
||||
nvgpu_runlist_domain, domains_list);
|
||||
|
||||
last = nvgpu_list_last_entry(&runlist->domains,
|
||||
nvgpu_runlist_domain, domains_list);
|
||||
|
||||
if (first == last) {
|
||||
nvgpu_mutex_release(&runlist->runlist_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (domain == runlist->domain) {
|
||||
/* Don't let the HW access this anymore */
|
||||
runlist_switch_domain_locked(g, runlist);
|
||||
}
|
||||
nvgpu_runlist_domain_free(g, domain);
|
||||
}
|
||||
nvgpu_mutex_release(&runlist->runlist_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nvgpu_runlist_cleanup_sw(struct gk20a *g)
|
||||
{
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
@@ -996,6 +1042,11 @@ static struct nvgpu_runlist_domain *nvgpu_runlist_domain_alloc(struct gk20a *g,
|
||||
/* deleted in nvgpu_runlist_domain_free() */
|
||||
nvgpu_list_add_tail(&domain->domains_list, &runlist->domains);
|
||||
|
||||
/* Select the first created domain as the boot-time default */
|
||||
if (runlist->domain == NULL) {
|
||||
runlist->domain = domain;
|
||||
}
|
||||
|
||||
return domain;
|
||||
free_active_channels:
|
||||
nvgpu_kfree(g, domain->active_channels);
|
||||
@@ -1025,6 +1076,40 @@ struct nvgpu_runlist_domain *nvgpu_rl_domain_get(struct gk20a *g, u32 runlist_id
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int nvgpu_rl_domain_alloc(struct gk20a *g, const char *name)
|
||||
{
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
int err;
|
||||
u32 i;
|
||||
|
||||
for (i = 0U; i < f->num_runlists; i++) {
|
||||
struct nvgpu_runlist *runlist;
|
||||
struct nvgpu_runlist_domain *domain;
|
||||
|
||||
runlist = &f->active_runlists[i];
|
||||
|
||||
nvgpu_mutex_acquire(&runlist->runlist_lock);
|
||||
/* this may only happen on the very first runlist */
|
||||
if (nvgpu_rl_domain_get(g, runlist->id, name) != NULL) {
|
||||
nvgpu_mutex_release(&runlist->runlist_lock);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
domain = nvgpu_runlist_domain_alloc(g, runlist, name);
|
||||
nvgpu_mutex_release(&runlist->runlist_lock);
|
||||
if (domain == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
clear:
|
||||
/* deletion skips runlists where the domain isn't found */
|
||||
(void)nvgpu_rl_domain_delete(g, name);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void nvgpu_init_active_runlist_mapping(struct gk20a *g)
|
||||
{
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
|
||||
@@ -183,6 +183,8 @@ struct nvgpu_runlist {
|
||||
/** @endcond DOXYGEN_SHOULD_SKIP_THIS */
|
||||
};
|
||||
|
||||
int nvgpu_rl_domain_alloc(struct gk20a *g, const char *name);
|
||||
int nvgpu_rl_domain_delete(struct gk20a *g, const char *name);
|
||||
struct nvgpu_runlist_domain *nvgpu_rl_domain_get(struct gk20a *g, u32 runlist_id,
|
||||
const char *name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user