]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
staging: vchiq_arm: Stop kthreads if vchiq cdev register fails
authorStefan Wahren <wahrenst@gmx.net>
Sun, 9 Mar 2025 12:50:12 +0000 (13:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Mar 2025 14:11:20 +0000 (07:11 -0700)
In case the vchiq character device cannot be registered during probe,
all kthreads needs to be stopped to avoid resource leaks.

Fixes: 863a756aaf49 ("staging: vc04_services: vchiq_core: Stop kthreads on vchiq module unload")
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20250309125014.37166-4-wahrenst@gmx.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c

index 910b8fd34cb1a8084bfb0a58f81c98e0d4b42967..6434cbdc1a6ef30a292bf94bdb60a363c23aad61 100644 (file)
@@ -308,6 +308,20 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *
        return (struct vchiq_arm_state *)state->platform_state;
 }
 
+static void
+vchiq_platform_uninit(struct vchiq_drv_mgmt *mgmt)
+{
+       struct vchiq_arm_state *arm_state;
+
+       kthread_stop(mgmt->state.sync_thread);
+       kthread_stop(mgmt->state.recycle_thread);
+       kthread_stop(mgmt->state.slot_handler_thread);
+
+       arm_state = vchiq_platform_get_arm_state(&mgmt->state);
+       if (!IS_ERR_OR_NULL(arm_state->ka_thread))
+               kthread_stop(arm_state->ka_thread);
+}
+
 void vchiq_dump_platform_state(struct seq_file *f)
 {
        seq_puts(f, "  Platform: 2835 (VC master)\n");
@@ -1396,6 +1410,7 @@ static int vchiq_probe(struct platform_device *pdev)
        ret = vchiq_register_chrdev(&pdev->dev);
        if (ret) {
                dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
+               vchiq_platform_uninit(mgmt);
                return ret;
        }
 
@@ -1410,20 +1425,12 @@ static int vchiq_probe(struct platform_device *pdev)
 static void vchiq_remove(struct platform_device *pdev)
 {
        struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev);
-       struct vchiq_arm_state *arm_state;
 
        vchiq_device_unregister(bcm2835_audio);
        vchiq_device_unregister(bcm2835_camera);
        vchiq_debugfs_deinit();
        vchiq_deregister_chrdev();
-
-       kthread_stop(mgmt->state.sync_thread);
-       kthread_stop(mgmt->state.recycle_thread);
-       kthread_stop(mgmt->state.slot_handler_thread);
-
-       arm_state = vchiq_platform_get_arm_state(&mgmt->state);
-       if (!IS_ERR_OR_NULL(arm_state->ka_thread))
-               kthread_stop(arm_state->ka_thread);
+       vchiq_platform_uninit(mgmt);
 }
 
 static struct platform_driver vchiq_driver = {