![]() | |||||||||||
Messages in this thread |
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 | ||||||||||
| Last update: 2007-12-20 07:35 [from the cache] ©2003-2008 | |||||||||||