kref/kobject: Improve documentation

The current kref and kobject documentation may be
insufficient to understand these common pitfalls regarding
object lifetime and object releasing.

Add a bit more documentation and improve the warnings
seen by the user, pointing to the right piece of documentation.

Also, it's important to understand that making fun of people
publicly is not at all helpful, doesn't provide any value,
and it's not a healthy way of encouraging developers to do better.

"Mocking mercilessly" will, if anything, make developers feel bad
and go away. This kind of behavior should not be encouraged or justified.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Ezequiel Garcia 2018-12-03 13:44:35 -03:00 committed by Greg Kroah-Hartman
parent 3f8e917853
commit 186bddb28f
4 changed files with 10 additions and 10 deletions

View File

@ -281,8 +281,12 @@ release() method, and the kobject must persist (in a consistent state)
until that method is called. If these constraints are not met, the code is until that method is called. If these constraints are not met, the code is
flawed. Note that the kernel will warn you if you forget to provide a flawed. Note that the kernel will warn you if you forget to provide a
release() method. Do not try to get rid of this warning by providing an release() method. Do not try to get rid of this warning by providing an
"empty" release function; you will be mocked mercilessly by the kobject "empty" release function.
maintainer if you attempt this.
If all your cleanup function needs to do is call kfree(), then you must
create a wrapper function which uses container_of() to upcast to the correct
type (as shown in the example above) and then calls kfree() on the overall
structure.
Note, the name of the kobject is available in the release function, but it Note, the name of the kobject is available in the release function, but it
must NOT be changed within this callback. Otherwise there will be a memory must NOT be changed within this callback. Otherwise there will be a memory

View File

@ -897,8 +897,7 @@ static void device_release(struct kobject *kobj)
else if (dev->class && dev->class->dev_release) else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev); dev->class->dev_release(dev);
else else
WARN(1, KERN_ERR "Device '%s' does not have a release() " WARN(1, KERN_ERR "Device '%s' does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
"function, it is broken and must be fixed.\n",
dev_name(dev)); dev_name(dev));
kfree(p); kfree(p);
} }

View File

@ -53,10 +53,7 @@ static inline void kref_get(struct kref *kref)
* @release: pointer to the function that will clean up the object when the * @release: pointer to the function that will clean up the object when the
* last reference to the object is released. * last reference to the object is released.
* This pointer is required, and it is not acceptable to pass kfree * This pointer is required, and it is not acceptable to pass kfree
* in as this function. If the caller does pass kfree to this * in as this function.
* function, you will be publicly mocked mercilessly by the kref
* maintainer, and anyone else who happens to notice it. You have
* been warned.
* *
* Decrement the refcount, and if 0, call release(). * Decrement the refcount, and if 0, call release().
* Return 1 if the object was removed, otherwise return 0. Beware, if this * Return 1 if the object was removed, otherwise return 0. Beware, if this

View File

@ -639,7 +639,7 @@ static void kobject_cleanup(struct kobject *kobj)
kobject_name(kobj), kobj, __func__, kobj->parent); kobject_name(kobj), kobj, __func__, kobj->parent);
if (t && !t->release) if (t && !t->release)
pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed.\n", pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
kobject_name(kobj), kobj); kobject_name(kobj), kobj);
/* send "remove" if the caller did not do it but sent "add" */ /* send "remove" if the caller did not do it but sent "add" */