From ce26e92de60aff1d607d022877463692bbdf825f Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Tue, 11 Oct 2022 22:05:37 +0530 Subject: [PATCH] gpu: nvgpu: open TSG with the share token Implement OPEN_TSG ioctl with share tokens. Bug 3677982 JIRA NVGPU-8681 Change-Id: If44aef863c932163df769acef5b3586f97aaecd3 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2792082 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: svcacv Reviewed-by: Scott Long Reviewed-by: Vijayakumar Subbu GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 81 ++++++++++++++++++++++++- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.h | 5 ++ drivers/gpu/nvgpu/os/linux/ioctl_tsg.c | 62 +++++++++++++------ drivers/gpu/nvgpu/os/linux/ioctl_tsg.h | 4 +- 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index dc13c250e..eddac17ba 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -725,10 +725,34 @@ clean_up: static int gk20a_ctrl_open_tsg(struct gk20a *g, struct gk20a_ctrl_priv *priv, struct nvgpu_gpu_open_tsg_args *args) { - int err; - int fd; + u64 device_instance_id = 0ULL; + bool open_share = false; struct file *file; char name[64]; + int err; + int fd; + +#ifdef CONFIG_NVGPU_TSG_SHARING + open_share = + (args->flags & NVGPU_GPU_IOCTL_OPEN_TSG_FLAGS_SHARE) != 0U; + + if (!open_share) { + if (args->source_device_instance_id != 0UL || + args->share_token != 0UL) { + nvgpu_err(g, "Source device inst id/token specified"); + return -EINVAL; + } + + } else { + if (args->source_device_instance_id == 0UL || + args->share_token == 0UL) { + nvgpu_err(g, "Source device inst id/token not specified"); + return -EINVAL; + } + } + + device_instance_id = priv->device_instance_id; +#endif err = get_unused_fd_flags(O_RDWR | O_CLOEXEC); if (err < 0) @@ -743,12 +767,17 @@ static int gk20a_ctrl_open_tsg(struct gk20a *g, struct gk20a_ctrl_priv *priv, goto clean_up; } - err = nvgpu_ioctl_tsg_open(g, priv, priv->cdev, file); + err = nvgpu_ioctl_tsg_open(g, priv, priv->cdev, file, open_share, + args->source_device_instance_id, + device_instance_id, + args->share_token); if (err) goto clean_up_file; fd_install(fd, file); + args->tsg_fd = fd; + return 0; clean_up_file: @@ -2999,4 +3028,50 @@ int nvgpu_gpu_tsg_revoke_share_tokens(struct gk20a *g, return 0; } + +struct nvgpu_tsg *nvgpu_gpu_open_tsg_with_share_token(struct gk20a *g, + u64 source_device_instance_id, + u64 target_device_instance_id, + u64 share_token) +{ + struct nvgpu_tsg_share_token_node *token_node, *tmp; + struct gk20a_ctrl_priv *ctrl_priv; + struct nvgpu_tsg *tsg = NULL; + + ctrl_priv = nvgpu_gpu_get_ctrl_priv(g, source_device_instance_id); + if (ctrl_priv == NULL) { + nvgpu_err(g, "Invalid source device instance id"); + return NULL; + } + + nvgpu_log_info(g, "Using the token src: %llx target: %llx token:%llx", + source_device_instance_id, + target_device_instance_id, share_token); + + nvgpu_mutex_acquire(&ctrl_priv->tokens_lock); + + nvgpu_list_for_each_entry_safe(token_node, tmp, + &ctrl_priv->tsg_share_tokens_list, + nvgpu_tsg_share_token_node, ctrl_entry) { + if ((token_node->token == share_token) && + (token_node->target_device_instance_id == + target_device_instance_id)) { + tsg = token_node->tsg; + nvgpu_ref_get(&tsg->refcount); + nvgpu_list_del(&token_node->ctrl_entry); + nvgpu_kfree(g, token_node); + break; + } + } + + nvgpu_mutex_release(&ctrl_priv->tokens_lock); + + if (tsg != NULL) { + nvgpu_mutex_acquire(&tsg->tsg_share_lock); + tsg->share_token_count--; + nvgpu_mutex_release(&tsg->tsg_share_lock); + } + + return tsg; +} #endif diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.h b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.h index 00852c703..e370c472c 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.h @@ -17,6 +17,7 @@ #define __NVGPU_IOCTL_CTRL_H__ struct gk20a_ctrl_priv; +struct nvgpu_tsg; int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp); int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp); @@ -42,6 +43,10 @@ int nvgpu_gpu_tsg_revoke_share_tokens(struct gk20a *g, u64 source_device_instance_id, struct nvgpu_tsg *tsg, u32 *out_count); +struct nvgpu_tsg *nvgpu_gpu_open_tsg_with_share_token(struct gk20a *g, + u64 source_device_instance_id, + u64 target_device_instance_id, + u64 share_token); #endif #endif diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c index 9a6a9ea4b..9638794ba 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c @@ -629,7 +629,9 @@ static int nvgpu_tsg_ioctl_revoke_share_token(struct gk20a *g, #endif int nvgpu_ioctl_tsg_open(struct gk20a *g, struct gk20a_ctrl_priv *ctrl_priv, - struct nvgpu_cdev *cdev, struct file *filp) + struct nvgpu_cdev *cdev, struct file *filp, + bool open_share, u64 source_device_instance_id, + u64 target_device_instance_id, u64 share_token) { struct tsg_private *priv; struct nvgpu_tsg *tsg; @@ -650,20 +652,37 @@ int nvgpu_ioctl_tsg_open(struct gk20a *g, struct gk20a_ctrl_priv *ctrl_priv, goto free_ref; } - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, "failed to power on, %d", err); - goto free_mem; + if (!open_share) { + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on, %d", err); + goto free_mem; + } + + tsg = nvgpu_tsg_open(g, nvgpu_current_pid(g)); + gk20a_idle(g); + if (tsg == NULL) { + err = -ENOMEM; + goto free_mem; + } + + gk20a_sched_ctrl_tsg_added(g, tsg); + +#ifndef CONFIG_NVGPU_TSG_SHARING + } +#else + } else { + tsg = nvgpu_gpu_open_tsg_with_share_token(g, + source_device_instance_id, + target_device_instance_id, + share_token); + if (tsg == NULL) { + nvgpu_err(g, "TSG open with token failed"); + err = -EINVAL; + goto free_mem; + } } - tsg = nvgpu_tsg_open(g, nvgpu_current_pid(g)); - gk20a_idle(g); - if (!tsg) { - err = -ENOMEM; - goto free_mem; - } - -#ifdef CONFIG_NVGPU_TSG_SHARING if (ctrl_priv != NULL) { err = nvgpu_tsg_add_ctrl_dev_inst_id(tsg, ctrl_priv); if (err != 0) { @@ -680,8 +699,6 @@ int nvgpu_ioctl_tsg_open(struct gk20a *g, struct gk20a_ctrl_priv *ctrl_priv, priv->ctrl_priv = ctrl_priv; filp->private_data = priv; - gk20a_sched_ctrl_tsg_added(g, tsg); - return 0; free_mem: @@ -708,7 +725,8 @@ int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp) return ret; } - ret = nvgpu_ioctl_tsg_open(g, NULL, cdev, filp); + ret = nvgpu_ioctl_tsg_open(g, NULL, cdev, filp, false, + 0ULL, 0ULL, 0ULL); gk20a_idle(g); nvgpu_log_fn(g, "done"); @@ -727,13 +745,13 @@ void nvgpu_ioctl_tsg_release(struct nvgpu_ref *ref) gk20a_sched_ctrl_tsg_removed(g, tsg); nvgpu_tsg_release(ref); - nvgpu_put(g); } int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp) { struct tsg_private *priv = filp->private_data; struct nvgpu_tsg *tsg; + struct gk20a *g; #ifdef CONFIG_NVGPU_TSG_SHARING u32 count; int err; @@ -745,15 +763,16 @@ int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp) } tsg = priv->tsg; + g = tsg->g; #ifdef CONFIG_NVGPU_TSG_SHARING nvgpu_mutex_acquire(&tsg->tsg_share_lock); - err = nvgpu_gpu_tsg_revoke_share_tokens(tsg->g, + err = nvgpu_gpu_tsg_revoke_share_tokens(g, nvgpu_gpu_get_device_instance_id(priv->ctrl_priv), tsg, &count); if (err != 0) { - nvgpu_err(tsg->g, "revoke token(%llu) failed %d", + nvgpu_err(g, "revoke token(%llu) failed %d", nvgpu_gpu_get_device_instance_id(priv->ctrl_priv), err); } @@ -766,7 +785,10 @@ int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp) #endif nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); - nvgpu_kfree(tsg->g, priv); + nvgpu_kfree(g, priv); + + nvgpu_put(g); + return 0; } diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h index 341d70c77..5e44cb2b4 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h @@ -25,7 +25,9 @@ struct nvgpu_tsg *nvgpu_tsg_get_from_file(int fd); int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp); int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp); int nvgpu_ioctl_tsg_open(struct gk20a *g, struct gk20a_ctrl_priv *ctrl_priv, - struct nvgpu_cdev *cdev, struct file *filp); + struct nvgpu_cdev *cdev, struct file *filp, + bool open_share, u64 source_device_instance_id, + u64 target_device_instance_id, u64 share_token); long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); void nvgpu_ioctl_tsg_release(struct nvgpu_ref *ref);