diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index ff6c9694c..e89e17f60 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -109,7 +109,13 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch) */ if (tsg->runlist == NULL) { 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); } else { if (tsg->runlist != ch->runlist) { @@ -147,6 +153,30 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch) 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) { 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->timeslice_us = g->ops.tsg.default_timeslice_us(g); 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 tsg->sm_exception_mask_type = NVGPU_SM_EXCEPTION_TYPE_MASK_NONE; #endif diff --git a/drivers/gpu/nvgpu/include/nvgpu/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/tsg.h index 478edbdaa..46a302961 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/tsg.h @@ -373,6 +373,8 @@ void nvgpu_tsg_disable(struct nvgpu_tsg *tsg); int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, 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. * diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c index 9f5c6b6d0..4c881a89e 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c @@ -176,6 +176,13 @@ out: 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 static int gk20a_tsg_get_event_data_from_id(struct nvgpu_tsg *tsg, unsigned int event_id, @@ -814,6 +821,20 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, 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: { err = gk20a_busy(g); diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 414376ffc..26b1e2f5d 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -38,6 +38,12 @@ struct nvgpu_tsg_bind_channel_ex_args { __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 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 \ _IOW(NVGPU_TSG_IOCTL_MAGIC, 15, \ 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 \ - sizeof(struct nvgpu_tsg_bind_channel_ex_args) + sizeof(struct nvgpu_tsg_bind_scheduling_domain_args) #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