gpu: nvgpu: add sched domain bind ioctl

Support binding TSGs to some other scheduling domain than the default
one. Binding happens by name until a more robust interface appears in
the future, as the name is a natural identifier for users.

No other domains are actually created anywhere yet; that will happen in
next patches.

Jira NVGPU-6788

Change-Id: I5abcdea869b525b0a0e9937302f106f7eee94ec2
Signed-off-by: Konsta Hölttä <kholtta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2628047
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Alex Waterman <alexw@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:
Konsta Hölttä
2021-10-12 16:09:05 +03:00
committed by mobile promotions
parent e692cd9913
commit fe7ae02f5f
4 changed files with 70 additions and 3 deletions

View File

@@ -109,7 +109,13 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch)
*/ */
if (tsg->runlist == NULL) { if (tsg->runlist == NULL) {
tsg->runlist = ch->runlist; tsg->runlist = ch->runlist;
tsg->rl_domain = nvgpu_rl_domain_get(g, tsg->runlist->id, "(default)"); /*
* The rl domain identifier is stashed in tsg->rl_domain->name
* when the tsg is bound to a domain, but at that point there
* are no channels yet to describe which runlist id should be
* used. Now we know.
*/
tsg->rl_domain = nvgpu_rl_domain_get(g, tsg->runlist->id, tsg->rl_domain->name);
WARN_ON(tsg->rl_domain == NULL); WARN_ON(tsg->rl_domain == NULL);
} else { } else {
if (tsg->runlist != ch->runlist) { if (tsg->runlist != ch->runlist) {
@@ -147,6 +153,30 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch)
return err; return err;
} }
int nvgpu_tsg_bind_domain(struct nvgpu_tsg *tsg, const char *domain_name)
{
struct nvgpu_runlist_domain *domain;
struct gk20a *g = tsg->g;
/* Hopping channels from one domain to another is not allowed */
if (tsg->num_active_channels != 0U) {
return -EINVAL;
}
/*
* The domain ptr will get updated with the right id once the runlist
* gets specified based on the first channel.
*/
domain = nvgpu_rl_domain_get(g, 0, domain_name);
if (domain == NULL) {
return -ENOENT;
}
tsg->rl_domain = domain;
return 0;
}
static bool nvgpu_tsg_is_multi_channel(struct nvgpu_tsg *tsg) static bool nvgpu_tsg_is_multi_channel(struct nvgpu_tsg *tsg)
{ {
bool ret = false; bool ret = false;
@@ -807,6 +837,11 @@ int nvgpu_tsg_open_common(struct gk20a *g, struct nvgpu_tsg *tsg, pid_t pid)
tsg->interleave_level = NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW; tsg->interleave_level = NVGPU_FIFO_RUNLIST_INTERLEAVE_LEVEL_LOW;
tsg->timeslice_us = g->ops.tsg.default_timeslice_us(g); tsg->timeslice_us = g->ops.tsg.default_timeslice_us(g);
tsg->runlist = NULL; tsg->runlist = NULL;
/*
* The domain ptr will get updated with the right id once the runlist
* gets specified based on the first channel.
*/
tsg->rl_domain = nvgpu_rl_domain_get(g, 0, "(default)");
#ifdef CONFIG_NVGPU_DEBUGGER #ifdef CONFIG_NVGPU_DEBUGGER
tsg->sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE; tsg->sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE;
#endif #endif

View File

@@ -373,6 +373,8 @@ void nvgpu_tsg_disable(struct nvgpu_tsg *tsg);
int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg,
struct nvgpu_channel *ch); struct nvgpu_channel *ch);
int nvgpu_tsg_bind_domain(struct nvgpu_tsg *tsg, const char *domain_name);
/** /**
* @brief Get pointer to #nvgpu_tsg for the tsgid. * @brief Get pointer to #nvgpu_tsg for the tsgid.
* *

View File

@@ -176,6 +176,13 @@ out:
return err; return err;
} }
static int nvgpu_tsg_bind_scheduling_domain(struct nvgpu_tsg *tsg,
struct nvgpu_tsg_bind_scheduling_domain_args *args)
{
return nvgpu_tsg_bind_domain(tsg, args->domain_name);
}
#ifdef CONFIG_NVGPU_CHANNEL_TSG_CONTROL #ifdef CONFIG_NVGPU_CHANNEL_TSG_CONTROL
static int gk20a_tsg_get_event_data_from_id(struct nvgpu_tsg *tsg, static int gk20a_tsg_get_event_data_from_id(struct nvgpu_tsg *tsg,
unsigned int event_id, unsigned int event_id,
@@ -814,6 +821,20 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
break; break;
} }
case NVGPU_TSG_IOCTL_BIND_SCHEDULING_DOMAIN:
{
err = gk20a_busy(g);
if (err) {
nvgpu_err(g,
"failed to host gk20a for ioctl cmd: 0x%x", cmd);
break;
}
err = nvgpu_tsg_bind_scheduling_domain(tsg,
(struct nvgpu_tsg_bind_scheduling_domain_args *)buf);
gk20a_idle(g);
break;
}
case NVGPU_IOCTL_TSG_ENABLE: case NVGPU_IOCTL_TSG_ENABLE:
{ {
err = gk20a_busy(g); err = gk20a_busy(g);

View File

@@ -38,6 +38,12 @@ struct nvgpu_tsg_bind_channel_ex_args {
__u8 reserved[16]; __u8 reserved[16];
}; };
struct nvgpu_tsg_bind_scheduling_domain_args {
/* in: name of the domain this tsg will be bound to */
__u8 domain_name[16];
__u8 reserved[16];
};
/* /*
* This struct helps to report the SM error state of a single SM. * This struct helps to report the SM error state of a single SM.
* This acts upon the currently resident TSG context. * This acts upon the currently resident TSG context.
@@ -131,11 +137,14 @@ struct nvgpu_tsg_set_l2_sector_promotion_args {
#define NVGPU_TSG_IOCTL_SET_L2_SECTOR_PROMOTION \ #define NVGPU_TSG_IOCTL_SET_L2_SECTOR_PROMOTION \
_IOW(NVGPU_TSG_IOCTL_MAGIC, 15, \ _IOW(NVGPU_TSG_IOCTL_MAGIC, 15, \
struct nvgpu_tsg_set_l2_sector_promotion_args) struct nvgpu_tsg_set_l2_sector_promotion_args)
#define NVGPU_TSG_IOCTL_BIND_SCHEDULING_DOMAIN \
_IOW(NVGPU_TSG_IOCTL_MAGIC, 16, \
struct nvgpu_tsg_bind_scheduling_domain_args)
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \ #define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
sizeof(struct nvgpu_tsg_bind_channel_ex_args) sizeof(struct nvgpu_tsg_bind_scheduling_domain_args)
#define NVGPU_TSG_IOCTL_LAST \ #define NVGPU_TSG_IOCTL_LAST \
_IOC_NR(NVGPU_TSG_IOCTL_SET_L2_SECTOR_PROMOTION) _IOC_NR(NVGPU_TSG_IOCTL_BIND_SCHEDULING_DOMAIN)
/* /*
* /dev/nvhost-dbg-gpu device * /dev/nvhost-dbg-gpu device