Re: cdev/devm_* issues (was Re: [TECH TOPIC] Rust for Linux)

Dan Carpenter
2021-07-10T07:09:51Z

The other thing which is quite tricky to get right is kobj releases. I
have a bunch of these static checker warning but they're annoying
because they're not something which really affects real life so I can't
be bothered to fix or report them.

Also some of them are just unfixable, for example
__video_register_device().

drivers/media/v4l2-core/v4l2-dev.c
1031 /* Part 4: register the device with sysfs */
1032 vdev->dev.class = &video_class;
1033 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
1034 vdev->dev.parent = vdev->dev_parent;
1035 dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
1036 ret = device_register(&vdev->dev);

If device_register() fails then it's illegal to manually clean up.

1037 if (ret < 0) {
1038 pr_err("%s: device_register failed\n", __func__);
1039 goto cleanup;
^^^^^^^^^^^^^
But this does, but it turns out it's fine.

1040 }
1041 /* Register the release callback that will be called when the last
1042 reference to the device goes away. */
1043 vdev->dev.release = v4l2_device_release;

The ->release() function is not set until here so it's just going to
trigger the debug message in kobject_cleanup() about a missing
->release() function. So no problems.

1044
1045 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
1046 pr_warn("%s: requested %s%d, got %s\n", __func__,
1047 name_base, nr, video_device_node_name(vdev));
1048
1049 /* Increase v4l2_device refcount */
1050 v4l2_device_get(vdev->v4l2_dev);
1051
1052 /* Part 5: Register the entity. */
1053 ret = video_register_media_controller(vdev);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
But then there is no way to clean up from this is
video_register_media_controller() fails. If we call put_device() it
would lead to use after frees in the callers. We just have to ignore
the error.

It's a minor thing, but it's so frustrating.

1054
1055 /* Part 6: Activate this minor. The char device can now be used. */
1056 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
1057
1058 return 0;

regards,
dan carpenter