Messages in this thread | | | Date | Wed, 19 Dec 2007 22:32:06 -0800 | From | Randy Dunlap <> | Subject | Re: [RFC] kobject/kset/ktype documentation and example code updated |
| |
On Wed, 19 Dec 2007 16:30:31 -0800 Greg KH wrote:
> Everything you never wanted to know about kobjects, ksets, and ktypes > > Greg Kroah-Hartman <gregkh@suse.de> > > Based on an original article by Jon Corbet for lwn.net written October 1, > 2003 and located at http://lwn.net/Articles/51437/ > > Last updated December 19, 2007 > > ... > - A ktype is the type of object that embeds a kobject. Every structure > that embeds a kobject needs a corresponding ktype. The ktype controls > what happens when a kobject is no longer referenced and the kobject's > default representation in sysfs.
I can't quite parse the last sentence above. Is it:
The ktype controls (a) what happens ... and (b) the kobject's default representation in sysfs.
?
> Embedding kobjects > > So, for example, the UIO code has a structure that defines the memory > region associated with a uio device: > > struct uio_mem { > struct kobject kobj; > unsigned long addr; > unsigned long size; > int memtype; > void __iomem *internal_addr; > }; > > If you have a struct uio_mem structure, finding its embedded kobject is > just a matter of using the kobj structure. Code that works with kobjects > will often have the opposite problem, however: given a struct kobject > pointer, what is the pointer to the containing structure? You must avoid > tricks (such as assuming that the kobject is at the beginning of the > structure) and, instead, use the container_of() macro, found in > <linux/kernel.h>: > > container_of(pointer, type, member) > > where pointer is the pointer to the embedded kobject, type is the type of > the containing structure, and member is the name of the structure field to > which pointer points. The return value from container_of() is a pointer to > the given type. So, for example, a pointer to a struct kobject embedded
This is (still) confusing to me. Is it: a pointer "kp" to a ... or is struct uio_mem the "kp"?
> within a struct uio_mem called "kp" could be converted to a pointer to the > containing structure with: > > struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj); > > Programmers will often define a simple macro for "back-casting" kobject
Drop the "will".
> pointers to the containing type. > > > Initialization of kobjects > > > int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...); > > This sets up the parent of the kobject, and the name for the kobject
Drop the comma.
> properly. If the kobject is to be associated with a specific kset, that > assignment must be done before calling kobject_add(). If a kset is > associated with a kobject, then the parent for the kobject can be set to > NULL in the call to kobject_add() and then the kobject will be placed under > the kset itself. > > As the name of the kobject is set when it is added to the kernel, the name > of the kobject should never be manipulated directly. If you must change > the name of the kobject, call kobject_rename(): > > int kobject_rename(struct kobject *kobj, const char *new_name); > > There is a function called kobject_set_name() but that is legacy cruft and > is being removed. If your code needs to call this function, it is > incorrect and needs to be fixed.
Is kobject_set_name() marked as __deprecated ?
> Uevents > > After a kobject has been registered with the kobject core, it needs to be > announced to the world that it has been created. This can be done with > call to kobject_uevent():
a call ...
> > int kobject_uevent(struct kobject *kobj, enum kobject_action action); > > Use the KOBJ_ADD action for when the kobject is first added to the kernel. > This should be done only after any attributes or children of the kobject > have been initialized properly, as userspace will instantly start to look
s/will/may/
> for them when this call happens. > > When the kobject is removed from the kernel (details on how to do that is
are
> below), the uevent for KOBJ_REMOVE will be automatically created by the > kobject core, so the caller does not have to worry about doing that by > hand. > > > Reference counts > ... > > Because kobjects are dynamic, they must not be declared statically or on > the stack, but instead, always allocated from the heap. Future versions of
The kernel has heapspace?
> the kernel will contain a run-time check for kobjects that are created > statically and will warn the developer of this improper usage. > > If all that you are wanting to use a kobject for is to provide a reference
If all that you want to use a kobject for is to provide a reference
> counter for your structure, please use the struct kref instead, a kobject > would be overkill. For more information on how to use struct kref, please > see the file, Documentation/kref.txt in the Linux kernel source tree.
Drop comma.
> > > Creating "simple" kobjects > > Sometimes all that a developer wants is a way to create a simple directory > in the sysfs hierarchy, and not have to mess with the whole complication of > ksets, show and store functions, and other details. This is the one > exception where a single kobject should be created. To create such an > entry, use the function: > > struct kobject *kobject_create_and_add(char *name, struct kobject *parent); > > This function will create a kobject and place it in sysfs in the location > underneath the specified parent kobject. To create simple attributes > associated with this kobject, use: > > int sysfs_create_file(struct kobject *kobj, struct attribute *attr); > or > int sysfs_create_group(struct kobject *kobj, struct attribute_group *grp); > > Both types of attributes used here, with a kobject that has been created > with the kobject_create_and_add() can be of type kobj_attribute, no special > custom attribute is needed to be created.
^ multi-run-on sentences....
> See the example module, samples/kobject/kobject-example.c for an > implementation of a simple kobject and attributes. > > > > ktypes and release methods > ... > The end result is that a structure protected by a kobject cannot be freed > before its reference count goes to zero. The reference count is not under > the direct control of the code which created the kobject. So that code must
kobject, so that code
> be notified asynchronously whenever the last reference to one of its > kobjects goes away. > > Once you registered your kobject via kobject_add(), you must never use > kfree() to free it directly. The only safe way is to use kobject_put(). It > is good practice to always use kobject_put() after kobject_init() to avoid > errors creeping in. > > This notification is done through a kobject's release() method. Usually > such a method has a form like: > > void my_object_release(struct kobject *kobj) > { > struct my_object *mine = container_of(kobj, struct my_object, kobj); > > /* Perform any additional cleanup on this object, then... */ > kfree (mine);
No space after "kfree". :)
> } > > One important point cannot be overstated: every kobject must have a > 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 > 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 > "empty" release function, you will be mocked mercilessly by the kobject
s/,/;/
> maintainer if you attempt this. > ... > > ksets > > A kset is merely a collection of kobjects that want to be associated with > each other. There is no restriction that they be of the same ktype, but be > very careful if they are not. > > A kset serves these functions: > ... > > Kobject cleaning up > ... > Any initialization of the kobject that has been done will be automatically > cleaned up by the kobject core. If a KOBJ_ADD uevent has been sent for > the object, a corrisponding KOBJ_REMOVE uevent will be sent, and any other
corresponding
> sysfs housekeeping will be handled for the caller properly. > > In the future, the kobject_unregister() call will be going away to help > clean up the kobject api. > > > For a more complete example of using ksets and kobjects properly, see the > sample/kobject/kset-example.c code. > --
--- ~Randy
| |