On Thu, Jul 13, 2017 at 5:21 PM, Sakari Ailus <sakari.ai...@iki.fi> wrote:
>> >> +     ret = v4l2_async_notifier_register(&cio2->v4l2_dev, 
>> >> &cio2->notifier);
>> >> +     if (ret) {
>> >> +             cio2->notifier.num_subdevs = 0;
>> >
>> > No need to assign num_subdevs as 0.
>> >
>> > [YZ] _notifier_exit() will call _unregister() if this is not 0.
>>
>> You shouldn't call _exit() if _init() failed. I noticed that many
>> error paths in your code does this. Please fix it.
>
> In general most functions that initialise and clean up something are
> implemented so that the cleanup function can be called without calling the
> corresponding init function. This eases driver implementation by reducing
> complexity in error paths that are difficult to implement and test to begin
> with, so I don't see anything wrong with that, quite the contrary.
>
> I.e. in this case you should call v4l2_async_notifier_unregister() without
> checking the number of async sub-devices.
>
> There are exceptions to that though; not all the framework functions behave
> this way. Of kernel APIs, e.g. kmalloc() and kfree() do this --- you can
> pass a NULL pointer to kfree() and it does nothing.

I'd argue that most of the cleanup paths I've seen in the kernel are
the opposite. If you properly check for errors in your code, it's
actually very unlikely that you need to call a cleanup function
without the init function called... That said, I've seen the pattern
you describe too, so probably either there is no strict rule or it's
not strictly enforced. (Still, judging by
https://www.kernel.org/doc/html/v4.10/process/coding-style.html#centralized-exiting-of-functions,
which mentions "one err bugs" and suggests "to split it up into two
error labels", the pattern I'm arguing for might be the recommended
default.)

Best regards,
Tomasz

Reply via email to