diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/kobject.txt | |
download | lwn-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz lwn-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'Documentation/kobject.txt')
-rw-r--r-- | Documentation/kobject.txt | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt new file mode 100644 index 000000000000..8d9bffbd192c --- /dev/null +++ b/Documentation/kobject.txt @@ -0,0 +1,367 @@ +The kobject Infrastructure + +Patrick Mochel <mochel@osdl.org> + +Updated: 3 June 2003 + + +Copyright (c) 2003 Patrick Mochel +Copyright (c) 2003 Open Source Development Labs + + +0. Introduction + +The kobject infrastructure performs basic object management that larger +data structures and subsystems can leverage, rather than reimplement +similar functionality. This functionality primarily concerns: + +- Object reference counting. +- Maintaining lists (sets) of objects. +- Object set locking. +- Userspace representation. + +The infrastructure consists of a number of object types to support +this functionality. Their programming interfaces are described below +in detail, and briefly here: + +- 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. + + +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. + +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. + + +1. kobjects + +1.1 Description + + +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. + +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 *); + + +1.3 kobject Programming Interface + +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. + +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. + +Note: calling kobject_init() then kobject_add() is functionally +equivalent to calling kobject_register(). + +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. + +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. + +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. + + +NOTE!!! + +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. + +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). + + +1.4 sysfs + +Each kobject receives a directory in sysfs. This directory is created +under the kobject's parent directory. + +If a kobject does not have a parent when it is registered, its parent +becomes its dominant kset. + +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. + + + +2. ksets + +2.1 Description + +A kset is a set of kobjects that are embedded in the same type. + + +struct kset { + struct subsystem * subsys; + struct kobj_type * ktype; + struct list_head list; + struct kobject kobj; +}; + + +void kset_init(struct kset * k); +int kset_add(struct kset * k); +int kset_register(struct kset * k); +void kset_unregister(struct kset * k); + +struct kset * kset_get(struct kset * k); +void kset_put(struct kset * k); + +struct kobject * kset_find_obj(struct kset *, char *); + + +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. + +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). + +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. + + 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. + +- The type of objects on the disk's _subordinate_ list are partitions, + and is set in disk->kset.ktype. + +- The kset is then registered, which handles initializing and adding + the embedded kobject to the hierarchy. + + +2.2 kset Programming Interface + +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. + +kset_find_obj() may be used to locate a kobject with a particular +name. The kobject, if found, is returned. + + +2.3 sysfs + +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. + +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. + + +3. struct ktype + +3.1. Description + +struct kobj_type { + void (*release)(struct kobject *); + struct sysfs_ops * sysfs_ops; + struct attribute ** default_attrs; +}; + + +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. + +- sysfs_ops: Provides conversion functions for sysfs access. Please + see the sysfs documentation for more information. + +- 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 drivers/block/genhd.c + + +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. + + + +4. subsystems + +4.1 Description + +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. + + +struct subsystem { + struct kset kset; + struct rw_semaphore rwsem; +}; + +int subsystem_register(struct subsystem *); +void subsystem_unregister(struct subsystem *); + +struct subsystem * subsys_get(struct subsystem * s); +void subsys_put(struct subsystem * s); + + +A subsystem contains an embedded kset so: + +- It can be represented in the object hierarchy via the kset's + embedded kobject. + +- It can maintain a default list of objects of one type. + +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.) + +All ksets that are attached to a subsystem share the subsystem's R/W +semaphore. + + +4.2 subsystem Programming Interface. + +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). + + +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 '<name>_subsys', with an embedded kset of +type <type>. For example, + +decl_subsys(devices,&ktype_devices); + +is equivalent to doing: + +struct subsystem device_subsys = { + .kset = { + .kobj = { + .name = "devices", + }, + .ktype = &ktype_devices, + } +}; + + +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: + + +kobj_set_kset_s(obj,subsys) + +- Assumes that obj->kobj exists, and is a struct kobject. +- Sets the kset of that kobject to the subsystem's embedded kset. + + +kset_set_kset_s(obj,subsys) + +- 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) + +- Assumes obj->subsys exists, and is a struct subsystem. +- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset. + + +4.4 sysfs + +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). + |