mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
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 <dt@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2535265 Reviewed-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Lakshmanan M <lm@nvidia.com> Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -314,6 +314,10 @@ void gk20a_user_deinit(struct device *dev)
|
|||||||
nvgpu_kfree(g, cdev);
|
nvgpu_kfree(g, cdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l->power_cdev_region) {
|
||||||
|
unregister_chrdev_region(l->power_cdev_region, l->power_cdevs);
|
||||||
|
}
|
||||||
|
|
||||||
if (l->cdev_region) {
|
if (l->cdev_region) {
|
||||||
unregister_chrdev_region(l->cdev_region, l->num_cdevs);
|
unregister_chrdev_region(l->cdev_region, l->num_cdevs);
|
||||||
l->num_cdevs = 0;
|
l->num_cdevs = 0;
|
||||||
@@ -560,7 +564,7 @@ int gk20a_power_node_init(struct device *dev)
|
|||||||
goto fail;
|
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) {
|
nvgpu_list_for_each_entry(class, &l->class_list_head, nvgpu_class, list_entry) {
|
||||||
cdev = nvgpu_kzalloc(g, sizeof(*cdev));
|
cdev = nvgpu_kzalloc(g, sizeof(*cdev));
|
||||||
if (cdev == NULL) {
|
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);
|
nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
l->num_cdevs = total_cdevs;
|
l->power_cdevs = total_cdevs;
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
gk20a_user_deinit(dev);
|
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;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
|
|||||||
@@ -77,10 +77,12 @@ struct nvgpu_os_linux {
|
|||||||
|
|
||||||
struct nvgpu_list_node class_list_head;
|
struct nvgpu_list_node class_list_head;
|
||||||
struct nvgpu_list_node cdev_list_head;
|
struct nvgpu_list_node cdev_list_head;
|
||||||
|
u32 power_cdevs;
|
||||||
u32 num_cdevs;
|
u32 num_cdevs;
|
||||||
bool dev_nodes_created;
|
bool dev_nodes_created;
|
||||||
bool cdev_list_init_done;
|
bool cdev_list_init_done;
|
||||||
|
|
||||||
|
dev_t power_cdev_region;
|
||||||
dev_t cdev_region;
|
dev_t cdev_region;
|
||||||
|
|
||||||
/* see gk20a_ctrl_priv */
|
/* see gk20a_ctrl_priv */
|
||||||
|
|||||||
Reference in New Issue
Block a user