From c1b302652e37950fc8637db6e2bd3269a65e245e Mon Sep 17 00:00:00 2001 From: dt Date: Wed, 26 May 2021 16:07:23 +0000 Subject: [PATCH] gpu: nvgpu: Add fix for dev_node leak This is adding fix for dev_node leak when user_deinit called. The dev_nodes in linux are created in two phases. In first phase the power dev_nodes(one for legacy and other for v2) are created. The second phase other dev_nodes are created. While creating the dev_nodes the power cdev_region overwritten by cdev_region. This is fixed by introducing new cdev_region and updating respective nodes. JIRA NVGPU-6721 Change-Id: Iec78db8e5fe40cc0b14fb3fecc35b8881dff716f Signed-off-by: dt Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2535265 Reviewed-by: Debarshi Dutta Reviewed-by: svcacv Reviewed-by: svc_kernel_abi Reviewed-by: Lakshmanan M Reviewed-by: Vaibhav Kachore Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/ioctl.c | 10 +++++++--- drivers/gpu/nvgpu/os/linux/os_linux.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.c b/drivers/gpu/nvgpu/os/linux/ioctl.c index e72944c91..ce7c43871 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl.c @@ -314,6 +314,10 @@ void gk20a_user_deinit(struct device *dev) nvgpu_kfree(g, cdev); } + if (l->power_cdev_region) { + unregister_chrdev_region(l->power_cdev_region, l->power_cdevs); + } + if (l->cdev_region) { unregister_chrdev_region(l->cdev_region, l->num_cdevs); l->num_cdevs = 0; @@ -560,7 +564,7 @@ int gk20a_power_node_init(struct device *dev) goto fail; } - l->cdev_region = devno; + l->power_cdev_region = devno; nvgpu_list_for_each_entry(class, &l->class_list_head, nvgpu_class, list_entry) { cdev = nvgpu_kzalloc(g, sizeof(*cdev)); if (cdev == NULL) { @@ -586,7 +590,7 @@ int gk20a_power_node_init(struct device *dev) nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head); } - l->num_cdevs = total_cdevs; + l->power_cdevs = total_cdevs; return 0; fail: gk20a_user_deinit(dev); @@ -674,7 +678,7 @@ int gk20a_user_init(struct device *dev) } } - l->num_cdevs += total_cdevs; + l->num_cdevs = total_cdevs; return 0; fail: diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index de84c3486..00444d0de 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -77,10 +77,12 @@ struct nvgpu_os_linux { struct nvgpu_list_node class_list_head; struct nvgpu_list_node cdev_list_head; + u32 power_cdevs; u32 num_cdevs; bool dev_nodes_created; bool cdev_list_init_done; + dev_t power_cdev_region; dev_t cdev_region; /* see gk20a_ctrl_priv */