X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=Documentation%2Fkobject.txt;h=3ab2472509cbbc86996b31d809543ca2dd93f2c9;hb=40868c85b8dfe233192f29099f45348f5b363ce9;hp=949f7b5a20538aa3537078d0eafd636df4a5991b;hpb=e9539ee73a9b85bdc6eab9e15dd1ee639a815406;p=safe%2Fjmp%2Flinux-2.6 diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index 949f7b5..3ab2472 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -1,367 +1,410 @@ -The kobject Infrastructure +Everything you never wanted to know about kobjects, ksets, and ktypes -Patrick Mochel +Greg Kroah-Hartman -Updated: 3 June 2003 +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 -Copyright (c) 2003 Patrick Mochel -Copyright (c) 2003 Open Source Development Labs +Part of the difficulty in understanding the driver model - and the kobject +abstraction upon which it is built - is that there is no obvious starting +place. Dealing with kobjects requires understanding a few different types, +all of which make reference to each other. In an attempt to make things +easier, we'll take a multi-pass approach, starting with vague terms and +adding detail as we go. To that end, here are some quick definitions of +some terms we will be working with. -0. Introduction + - A kobject is an object of type struct kobject. Kobjects have a name + and a reference count. A kobject also has a parent pointer (allowing + objects to be arranged into hierarchies), a specific type, and, + usually, a representation in the sysfs virtual filesystem. -The kobject infrastructure performs basic object management that larger -data structures and subsystems can leverage, rather than reimplement -similar functionality. This functionality primarily concerns: + Kobjects are generally not interesting on their own; instead, they are + usually embedded within some other structure which contains the stuff + the code is really interested in. -- Object reference counting. -- Maintaining lists (sets) of objects. -- Object set locking. -- Userspace representation. + No structure should EVER have more than one kobject embedded within it. + If it does, the reference counting for the object is sure to be messed + up and incorrect, and your code will be buggy. So do not do this. -The infrastructure consists of a number of object types to support -this functionality. Their programming interfaces are described below -in detail, and briefly here: + - 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 to the kobject when it is created and destroyed. -- kobjects a simple object. -- kset a set of objects of a certain type. -- ktype a set of helpers for objects of a common type. -- subsystem a controlling object for a number of ksets. + - A kset is a group of kobjects. These kobjects can be of the same ktype + or belong to different ktypes. The kset is the basic container type for + collections of kobjects. Ksets contain their own kobjects, but you can + safely ignore that implementation detail as the kset core code handles + this kobject automatically. + When you see a sysfs directory full of other directories, generally each + of those directories corresponds to a kobject in the same kset. -The kobject infrastructure maintains a close relationship with the -sysfs filesystem. Each kobject that is registered with the kobject -core receives a directory in sysfs. Attributes about the kobject can -then be exported. Please see Documentation/filesystems/sysfs.txt for -more information. +We'll look at how to create and manipulate all of these types. A bottom-up +approach will be taken, so we'll go back to kobjects. -The kobject infrastructure provides a flexible programming interface, -and allows kobjects and ksets to be used without being registered -(i.e. with no sysfs representation). This is also described later. +Embedding kobjects -1. kobjects +It is rare for kernel code to create a standalone kobject, with one major +exception explained below. Instead, kobjects are used to control access to +a larger, domain-specific object. To this end, kobjects will be found +embedded in other structures. If you are used to thinking of things in +object-oriented terms, kobjects can be seen as a top-level, abstract class +from which other classes are derived. A kobject implements a set of +capabilities which are not particularly useful by themselves, but which are +nice to have in other objects. The C language does not allow for the +direct expression of inheritance, so other techniques - such as structure +embedding - must be used. -1.1 Description +(As an aside, for those familiar with the kernel linked list implementation, +this is analogous as to how "list_head" structs are rarely useful on +their own, but are invariably found embedded in the larger objects of +interest.) +So, for example, the UIO code in drivers/uio/uio.c has a structure that +defines the memory region associated with a uio device: -struct kobject is a simple data type that provides a foundation for -more complex object types. It provides a set of basic fields that -almost all complex data types share. kobjects are intended to be -embedded in larger data structures and replace fields they duplicate. + struct uio_map { + struct kobject kobj; + struct uio_mem *mem; + }; -1.2 Defintion - -struct kobject { - char name[KOBJ_NAME_LEN]; - atomic_t refcount; - struct list_head entry; - struct kobject * parent; - struct kset * kset; - struct kobj_type * ktype; - struct dentry * dentry; -}; - -void kobject_init(struct kobject *); -int kobject_add(struct kobject *); -int kobject_register(struct kobject *); - -void kobject_del(struct kobject *); -void kobject_unregister(struct kobject *); - -struct kobject * kobject_get(struct kobject *); -void kobject_put(struct kobject *); +If you have a struct uio_map structure, finding its embedded kobject is +just a matter of using the kobj member. 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 : + container_of(pointer, type, member) -1.3 kobject Programming Interface +where: -kobjects may be dynamically added and removed from the kobject core -using kobject_register() and kobject_unregister(). Registration -includes inserting the kobject in the list of its dominant kset and -creating a directory for it in sysfs. + * "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. -Alternatively, one may use a kobject without adding it to its kset's list -or exporting it via sysfs, by simply calling kobject_init(). An -initialized kobject may later be added to the object hierarchy by -calling kobject_add(). An initialized kobject may be used for -reference counting. +The return value from container_of() is a pointer to the corresponding +container type. So, for example, a pointer "kp" to a struct kobject +embedded *within* a struct uio_map could be converted to a pointer to the +*containing* uio_map structure with: -Note: calling kobject_init() then kobject_add() is functionally -equivalent to calling kobject_register(). + struct uio_map *u_map = container_of(kp, struct uio_map, kobj); -When a kobject is unregistered, it is removed from its kset's list, -removed from the sysfs filesystem, and its reference count is decremented. -List and sysfs removal happen in kobject_del(), and may be called -manually. kobject_put() decrements the reference count, and may also -be called manually. +For convenience, programmers often define a simple macro for "back-casting" +kobject pointers to the containing type. Exactly this happens in the +earlier drivers/uio/uio.c, as you can see here: -A kobject's reference count may be incremented with kobject_get(), -which returns a valid reference to a kobject; and decremented with -kobject_put(). An object's reference count may only be incremented if -it is already positive. + struct uio_map { + struct kobject kobj; + struct uio_mem *mem; + }; -When a kobject's reference count reaches 0, the method struct -kobj_type::release() (which the kobject's kset points to) is called. -This allows any memory allocated for the object to be freed. + #define to_map(map) container_of(map, struct uio_map, kobj) +where the macro argument "map" is a pointer to the struct kobject in +question. That macro is subsequently invoked with: -NOTE!!! + struct uio_map *map = to_map(kobj); -It is _imperative_ that you supply a destructor for dynamically -allocated kobjects to free them if you are using kobject reference -counts. The reference count controls the lifetime of the object. -If it goes to 0, then it is assumed that the object will -be freed and cannot be used. -More importantly, you must free the object there, and not immediately -after an unregister call. If someone else is referencing the object -(e.g. through a sysfs file), they will obtain a reference to the -object, assume it's valid and operate on it. If the object is -unregistered and freed in the meantime, the operation will then -reference freed memory and go boom. +Initialization of kobjects -This can be prevented, in the simplest case, by defining a release -method and freeing the object from there only. Note that this will not -secure reference count/object management models that use a dual -reference count or do other wacky things with the reference count -(like the networking layer). +Code which creates a kobject must, of course, initialize that object. Some +of the internal fields are setup with a (mandatory) call to kobject_init(): + void kobject_init(struct kobject *kobj, struct kobj_type *ktype); -1.4 sysfs +The ktype is required for a kobject to be created properly, as every kobject +must have an associated kobj_type. After calling kobject_init(), to +register the kobject with sysfs, the function kobject_add() must be called: -Each kobject receives a directory in sysfs. This directory is created -under the kobject's parent directory. + int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...); -If a kobject does not have a parent when it is registered, its parent -becomes its dominant kset. +This sets up the parent of the kobject and the name for the kobject +properly. If the kobject is to be associated with a specific kset, +kobj->kset must be assigned 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's parent will be the +kset itself. -If a kobject does not have a parent nor a dominant kset, its directory -is created at the top-level of the sysfs partition. This should only -happen for kobjects that are embedded in a struct subsystem. +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); +kobject_rename does not perform any locking or have a solid notion of +what names are valid so the caller must provide their own sanity checking +and serialization. -2. ksets +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. -2.1 Description +To properly access the name of the kobject, use the function +kobject_name(): -A kset is a set of kobjects that are embedded in the same type. + const char *kobject_name(const struct kobject * kobj); +There is a helper function to both initialize and add the kobject to the +kernel at the same time, called surprisingly enough kobject_init_and_add(): -struct kset { - struct subsystem * subsys; - struct kobj_type * ktype; - struct list_head list; - struct kobject kobj; -}; - + int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, + struct kobject *parent, const char *fmt, ...); -void kset_init(struct kset * k); -int kset_add(struct kset * k); -int kset_register(struct kset * k); -void kset_unregister(struct kset * k); +The arguments are the same as the individual kobject_init() and +kobject_add() functions described above. -struct kset * kset_get(struct kset * k); -void kset_put(struct kset * k); -struct kobject * kset_find_obj(struct kset *, char *); +Uevents +After a kobject has been registered with the kobject core, you need to +announce to the world that it has been created. This can be done with a +call to kobject_uevent(): -The type that the kobjects are embedded in is described by the ktype -pointer. The subsystem that the kobject belongs to is pointed to by the -subsys pointer. + int kobject_uevent(struct kobject *kobj, enum kobject_action action); -A kset contains a kobject itself, meaning that it may be registered in -the kobject hierarchy and exported via sysfs. More importantly, the -kset may be embedded in a larger data type, and may be part of another -kset (of that object type). +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 +for them when this call happens. -For example, a block device is an object (struct gendisk) that is -contained in a set of block devices. It may also contain a set of -partitions (struct hd_struct) that have been found on the device. The -following code snippet illustrates how to express this properly. +When the kobject is removed from the kernel (details on how to do that is +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. - struct gendisk * disk; - ... - disk->kset.kobj.kset = &block_kset; - disk->kset.ktype = &partition_ktype; - kset_register(&disk->kset); -- The kset that the disk's embedded object belongs to is the - block_kset, and is pointed to by disk->kset.kobj.kset. +Reference counts -- The type of objects on the disk's _subordinate_ list are partitions, - and is set in disk->kset.ktype. +One of the key functions of a kobject is to serve as a reference counter +for the object in which it is embedded. As long as references to the object +exist, the object (and the code which supports it) must continue to exist. +The low-level functions for manipulating a kobject's reference counts are: -- The kset is then registered, which handles initializing and adding - the embedded kobject to the hierarchy. + struct kobject *kobject_get(struct kobject *kobj); + void kobject_put(struct kobject *kobj); +A successful call to kobject_get() will increment the kobject's reference +counter and return the pointer to the kobject. -2.2 kset Programming Interface +When a reference is released, the call to kobject_put() will decrement the +reference count and, possibly, free the object. Note that kobject_init() +sets the reference count to one, so the code which sets up the kobject will +need to do a kobject_put() eventually to release that reference. -All kset functions, except kset_find_obj(), eventually forward the -calls to their embedded kobjects after performing kset-specific -operations. ksets offer a similar programming model to kobjects: they -may be used after they are initialized, without registering them in -the hierarchy. +Because kobjects are dynamic, they must not be declared statically or on +the stack, but instead, always allocated dynamically. Future versions of +the kernel will contain a run-time check for kobjects that are created +statically and will warn the developer of this improper usage. -kset_find_obj() may be used to locate a kobject with a particular -name. The kobject, if found, is returned. +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. -2.3 sysfs +Creating "simple" kobjects -ksets are represented in sysfs when their embedded kobjects are -registered. They follow the same rules of parenting, with one -exception. If a kset does not have a parent, nor is its embedded -kobject part of another kset, the kset's parent becomes its dominant -subsystem. +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: -If the kset does not have a parent, its directory is created at the -sysfs root. This should only happen when the kset registered is -embedded in a subsystem itself. + 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: -3. struct ktype + int sysfs_create_file(struct kobject *kobj, struct attribute *attr); +or + int sysfs_create_group(struct kobject *kobj, struct attribute_group *grp); -3.1. Description +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, so no +special custom attribute is needed to be created. -struct kobj_type { - void (*release)(struct kobject *); - struct sysfs_ops * sysfs_ops; - struct attribute ** default_attrs; -}; +See the example module, samples/kobject/kobject-example.c for an +implementation of a simple kobject and attributes. -Object types require specific functions for converting between the -generic object and the more complex type. struct kobj_type provides -the object-specific fields, which include: -- release: Called when the kobject's reference count reaches 0. This - should convert the object to the more complex type and free it. +ktypes and release methods -- sysfs_ops: Provides conversion functions for sysfs access. Please - see the sysfs documentation for more information. +One important thing still missing from the discussion is what happens to a +kobject when its reference count reaches zero. The code which created the +kobject generally does not know when that will happen; if it did, there +would be little point in using a kobject in the first place. Even +predictable object lifecycles become more complicated when sysfs is brought +in as other portions of the kernel can get a reference on any kobject that +is registered in the system. -- default_attrs: Default attributes to be exported via sysfs when the - object is registered.Note that the last attribute has to be - initialized to NULL ! You can find a complete implementation - in block/genhd.c +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 +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. -Instances of struct kobj_type are not registered; only referenced by -the kset. A kobj_type may be referenced by an arbitrary number of -ksets, as there may be disparate sets of identical objects. +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); + } -4. subsystems +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 +maintainer if you attempt this. -4.1 Description +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 +leak in the kobject core, which makes people unhappy. -A subsystem represents a significant entity of code that maintains an -arbitrary number of sets of objects of various types. Since the number -of ksets and the type of objects they contain are variable, a -generic representation of a subsystem is minimal. +Interestingly, the release() method is not stored in the kobject itself; +instead, it is associated with the ktype. So let us introduce struct +kobj_type: + struct kobj_type { + void (*release)(struct kobject *); + const struct sysfs_ops *sysfs_ops; + struct attribute **default_attrs; + }; -struct subsystem { - struct kset kset; - struct rw_semaphore rwsem; -}; - -int subsystem_register(struct subsystem *); -void subsystem_unregister(struct subsystem *); +This structure is used to describe a particular type of kobject (or, more +correctly, of containing object). Every kobject needs to have an associated +kobj_type structure; a pointer to that structure must be specified when you +call kobject_init() or kobject_init_and_add(). -struct subsystem * subsys_get(struct subsystem * s); -void subsys_put(struct subsystem * s); +The release field in struct kobj_type is, of course, a pointer to the +release() method for this type of kobject. The other two fields (sysfs_ops +and default_attrs) control how objects of this type are represented in +sysfs; they are beyond the scope of this document. +The default_attrs pointer is a list of default attributes that will be +automatically created for any kobject that is registered with this ktype. -A subsystem contains an embedded kset so: -- It can be represented in the object hierarchy via the kset's - embedded kobject. +ksets -- It can maintain a default list of objects of one type. +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. -Additional ksets may attach to the subsystem simply by referencing the -subsystem before they are registered. (This one-way reference means -that there is no way to determine the ksets that are attached to the -subsystem.) +A kset serves these functions: -All ksets that are attached to a subsystem share the subsystem's R/W -semaphore. + - It serves as a bag containing a group of objects. A kset can be used by + the kernel to track "all block devices" or "all PCI device drivers." + - A kset is also a subdirectory in sysfs, where the associated kobjects + with the kset can show up. Every kset contains a kobject which can be + set up to be the parent of other kobjects; the top-level directories of + the sysfs hierarchy are constructed in this way. -4.2 subsystem Programming Interface. + - Ksets can support the "hotplugging" of kobjects and influence how + uevent events are reported to user space. -The subsystem programming interface is simple and does not offer the -flexibility that the kset and kobject programming interfaces do. They -may be registered and unregistered, as well as reference counted. Each -call forwards the calls to their embedded ksets (which forward the -calls to their embedded kobjects). +In object-oriented terms, "kset" is the top-level container class; ksets +contain their own kobject, but that kobject is managed by the kset code and +should not be manipulated by any other user. +A kset keeps its children in a standard kernel linked list. Kobjects point +back to their containing kset via their kset field. In almost all cases, +the kobjects belonging to a kset have that kset (or, strictly, its embedded +kobject) in their parent. -4.3 Helpers - -A number of macros are available to make dealing with subsystems and -their embedded objects easier. - - -decl_subsys(name,type) - -Declares a subsystem named '_subsys', with an embedded kset of -type . For example, - -decl_subsys(devices,&ktype_devices); - -is equivalent to doing: - -struct subsystem device_subsys = { - .kset = { - .kobj = { - .name = "devices", - }, - .ktype = &ktype_devices, - } -}; - +As a kset contains a kobject within it, it should always be dynamically +created and never declared statically or on the stack. To create a new +kset use: + struct kset *kset_create_and_add(const char *name, + struct kset_uevent_ops *u, + struct kobject *parent); + +When you are finished with the kset, call: + void kset_unregister(struct kset *kset); +to destroy it. + +An example of using a kset can be seen in the +samples/kobject/kset-example.c file in the kernel tree. + +If a kset wishes to control the uevent operations of the kobjects +associated with it, it can use the struct kset_uevent_ops to handle it: + +struct kset_uevent_ops { + int (*filter)(struct kset *kset, struct kobject *kobj); + const char *(*name)(struct kset *kset, struct kobject *kobj); + int (*uevent)(struct kset *kset, struct kobject *kobj, + struct kobj_uevent_env *env); +}; -The objects that are registered with a subsystem that use the -subsystem's default list must have their kset ptr set properly. These -objects may have embedded kobjects, ksets, or other subsystems. The -following helpers make setting the kset easier: +The filter function allows a kset to prevent a uevent from being emitted to +userspace for a specific kobject. If the function returns 0, the uevent +will not be emitted. -kobj_set_kset_s(obj,subsys) +The name function will be called to override the default name of the kset +that the uevent sends to userspace. By default, the name will be the same +as the kset itself, but this function, if present, can override that name. -- Assumes that obj->kobj exists, and is a struct kobject. -- Sets the kset of that kobject to the subsystem's embedded kset. +The uevent function will be called when the uevent is about to be sent to +userspace to allow more environment variables to be added to the uevent. +One might ask how, exactly, a kobject is added to a kset, given that no +functions which perform that function have been presented. The answer is +that this task is handled by kobject_add(). When a kobject is passed to +kobject_add(), its kset member should point to the kset to which the +kobject will belong. kobject_add() will handle the rest. -kset_set_kset_s(obj,subsys) +If the kobject belonging to a kset has no parent kobject set, it will be +added to the kset's directory. Not all members of a kset do necessarily +live in the kset directory. If an explicit parent kobject is assigned +before the kobject is added, the kobject is registered with the kset, but +added below the parent kobject. -- Assumes that obj->kset exists, and is a struct kset. -- Sets the kset of the embedded kobject to the subsystem's - embedded kset. -subsys_set_kset(obj,subsys) +Kobject removal -- Assumes obj->subsys exists, and is a struct subsystem. -- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset. +After a kobject has been registered with the kobject core successfully, it +must be cleaned up when the code is finished with it. To do that, call +kobject_put(). By doing this, the kobject core will automatically clean up +all of the memory allocated by this kobject. If a KOBJ_ADD uevent has been +sent for the object, a corresponding KOBJ_REMOVE uevent will be sent, and +any other sysfs housekeeping will be handled for the caller properly. +If you need to do a two-stage delete of the kobject (say you are not +allowed to sleep when you need to destroy the object), then call +kobject_del() which will unregister the kobject from sysfs. This makes the +kobject "invisible", but it is not cleaned up, and the reference count of +the object is still the same. At a later time call kobject_put() to finish +the cleanup of the memory associated with the kobject. -4.4 sysfs +kobject_del() can be used to drop the reference to the parent object, if +circular references are constructed. It is valid in some cases, that a +parent objects references a child. Circular references _must_ be broken +with an explicit call to kobject_del(), so that a release functions will be +called, and the objects in the former circle release each other. -subsystems are represented in sysfs via their embedded kobjects. They -follow the same rules as previously mentioned with no exceptions. They -typically receive a top-level directory in sysfs, except when their -embedded kobject is part of another kset, or the parent of the -embedded kobject is explicitly set. -Note that the subsystem's embedded kset must be 'attached' to the -subsystem itself in order to use its rwsem. This is done after -kset_add() has been called. (Not before, because kset_add() uses its -subsystem for a default parent if it doesn't already have one). +Example code to copy from +For a more complete example of using ksets and kobjects properly, see the +example programs samples/kobject/{kobject-example.c,kset-example.c}, +which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.