diff --git a/drivers/gpu/nvgpu/os/linux/channel.h b/drivers/gpu/nvgpu/os/linux/channel.h index 1603f8403..773029737 100644 --- a/drivers/gpu/nvgpu/os/linux/channel.h +++ b/drivers/gpu/nvgpu/os/linux/channel.h @@ -28,6 +28,7 @@ struct nvgpu_channel_fence; struct nvgpu_fence_type; struct nvgpu_swprofile; struct nvgpu_os_linux; +struct nvgpu_cdev; struct sync_fence; struct sync_timeline; @@ -92,6 +93,8 @@ struct nvgpu_channel_linux { struct dma_buf *cyclestate_buffer_handler; struct nvgpu_usermode_bufs_linux usermode; + + struct nvgpu_cdev *cdev; }; u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c index 261c88156..bffe6a242 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c @@ -429,6 +429,7 @@ struct nvgpu_channel *nvgpu_channel_get_from_file(int fd) int gk20a_channel_release(struct inode *inode, struct file *filp) { struct channel_priv *priv = filp->private_data; + struct nvgpu_channel_linux *os_priv; struct nvgpu_channel *ch; struct gk20a *g; @@ -443,6 +444,9 @@ int gk20a_channel_release(struct inode *inode, struct file *filp) ch = priv->c; g = priv->g; + os_priv = ch->os_priv; + os_priv->cdev = NULL; + err = gk20a_busy(g); if (err) { nvgpu_err(g, "failed to release a channel!"); @@ -472,11 +476,16 @@ static int __gk20a_channel_open(struct gk20a *g, struct nvgpu_cdev *cdev, int err; struct nvgpu_channel *ch; struct channel_priv *priv; + struct nvgpu_channel_linux *os_priv; u32 tmp_runlist_id; u32 gpu_instance_id; nvgpu_log_fn(g, " "); + g = nvgpu_get(g); + if (!g) + return -ENODEV; + gpu_instance_id = nvgpu_get_gpu_instance_id_from_cdev(g, cdev); nvgpu_assert(gpu_instance_id < g->mig.num_gpu_instances); @@ -491,10 +500,6 @@ static int __gk20a_channel_open(struct gk20a *g, struct nvgpu_cdev *cdev, } } - g = nvgpu_get(g); - if (!g) - return -ENODEV; - #ifdef CONFIG_NVGPU_TRACE trace_gk20a_channel_open(dev_name(dev_from_gk20a(g))); #endif @@ -530,6 +535,12 @@ static int __gk20a_channel_open(struct gk20a *g, struct nvgpu_cdev *cdev, priv->c = ch; priv->cdev = cdev; + os_priv = ch->os_priv; + os_priv->cdev = cdev; + + nvgpu_log(g, gpu_dbg_mig, "Use runlist %u for channel %u on GPU instance %u", + tmp_runlist_id, ch->chid, gpu_instance_id); + filp->private_data = priv; return 0; diff --git a/drivers/gpu/nvgpu/os/linux/linux-channel.c b/drivers/gpu/nvgpu/os/linux/linux-channel.c index 06e985243..774ea5786 100644 --- a/drivers/gpu/nvgpu/os/linux/linux-channel.c +++ b/drivers/gpu/nvgpu/os/linux/linux-channel.c @@ -33,6 +33,7 @@ #include "channel.h" #include "ioctl_channel.h" +#include "ioctl.h" #include "os_linux.h" #include "dmabuf_priv.h" @@ -631,10 +632,19 @@ u32 nvgpu_get_gpfifo_entry_size(void) u32 nvgpu_channel_get_max_subctx_count(struct nvgpu_channel *ch) { + struct nvgpu_channel_linux *priv = ch->os_priv; struct gk20a *g = ch->g; + u32 gpu_instance_id; - return nvgpu_grmgr_get_gpu_instance_max_veid_count(g, - 0U); + if (priv->cdev == NULL) { + /* CE channels reserved by nvgpu do not have cdev pointer */ + return nvgpu_grmgr_get_gpu_instance_max_veid_count(g, 0U); + } + + gpu_instance_id = nvgpu_get_gpu_instance_id_from_cdev(g, priv->cdev); + nvgpu_assert(gpu_instance_id < g->mig.num_gpu_instances); + + return nvgpu_grmgr_get_gpu_instance_max_veid_count(g, gpu_instance_id); } #ifdef CONFIG_DEBUG_FS