]> git.hungrycats.org Git - linux/commitdiff
Update kobject documentation.
authorPatrick Mochel <mochel@osdl.org>
Tue, 7 Jan 2003 05:25:39 +0000 (23:25 -0600)
committerPatrick Mochel <mochel@osdl.org>
Tue, 7 Jan 2003 05:25:39 +0000 (23:25 -0600)
Documentation/kobject.txt

index 692467d0255c814a092656ef79490ef822095b0c..bd5e3446365ca3a25852ab7ee0465b5d0be2e1ba 100644 (file)
@@ -1,29 +1,61 @@
-kobjects - Simple, Generic Kernel Objects
+The kobject Infrastructure
 
 Patrick Mochel <mochel@osdl.org>
 
-30 October 2002
+7 January 2003
+
+
+0. Introduction
+
+The kobject infrastructure performs basic object managment that larger
+data structures and subsystems can leverage, rather than reimplement
+similar functionality. This functionality consists 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 introduces a simple, intregral datatype and a simple
-set of semantics for operating on the device. kobjects are intended to
-be embedded in larger data structures and replace fields it
-duplicates. A set of library functions has been developed to assist in
-the manipulation of kobjects.
 
+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 it duplicates. 
 
 1.2 Defintion
 
 struct kobject {
-       char                    name[16];
+       char                    name[KOBJ_NAME_LEN];
        atomic_t                refcount;
        struct list_head        entry;
        struct kobject          * parent;
-       struct subsystem        * subsys;
+       struct kset             * kset;
+       struct kobj_type        * ktype;
        struct dentry           * dentry;
 };
 
@@ -32,204 +64,276 @@ int kobject_add(struct kobject *);
 int kobject_register(struct kobject *);
 
 void kobject_del(struct kobject *);
-void kobject_cleanup(struct kobject *);
 void kobject_unregister(struct kobject *);
 
 struct kobject * kobject_get(struct kobject *);
 void kobject_put(struct kobject *);
 
 
+1.3 kobject Programming Interface
 
-2. subsystems
+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.
 
-2.1 Description
+Alternatively, one may use a kobject without adding 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.
 
-struct subsystem is introduced to describe a collection of objects of
-a certain type. subsystems are kobjects themselves, though they
-contain lists of kobjects that belong to that subsystem. Objects of a
-subsystem (the embedder objects in which kobjects live) are all of the
-same type. 
+Note: calling kobject_init(), then kobject_add() is functionally
+equivalent to calling kobject_register().
 
-2.2 Definition
+When a kobject is unregistered, it is removed from its kset's list,
+removed from the sysfs filesystem, and its reference 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. 
 
-struct subsystem {
-       struct kobject          kobj;
+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
+ktype::release() (which the kobject's kset points to) is called. This
+allows any memory allocated for the object to be freed.
+
+
+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 Desecription
+
+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 rw_semaphore     rwsem;
-       struct subsystem        * parent;
+       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
+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 properly express this.
+
+        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 disk->kset.kobj.kset. 
+
+- The type of object of 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 it's 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;
 };
 
-void subsystem_init(struct subsystem *);
-int subsystem_register(struct subsystem *);
-void subsystem_unregister(struct subsystem *);
 
-struct subsystem * subsys_get(struct subsystem * s);
-void subsys_put(struct subsystem * s);
+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 exported via sysfs when the
+  object is registered. 
 
-3. The Interface
 
-The kobject API provides a symmeticral interface that may be used in
-one of two ways: by using the default front-end registration
-interface, or by directly using the backend helpers the registration
-interface uses. 
+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 their may be disparate sets of identical objects. 
 
-3.1 Default Usage
 
-The default usage is to use kobjet_register() to add a device to the
-object hierarchy, and kobject_unregister() to remove it. 
 
-kobject_register() will call kobject_init() and kobject_add()
-consecutively. kobject_init() will initialize the object and increment
-the reference count of the subsystem the object belongs to. It will
-leave the reference count of the object at 1.
+4. subsystems
 
-kobject_add() will insert it into the object hierarchy and create
-a sysfs directory for the object. This will increment the reference
-count of the object, leaving it at 2.
+4.1 Description
 
-kobject_unregister() will call kobject_del() and kobject_put()
-consecutively. kobject_del() will remove the object from the hierarchy
-and the sysfs directory for the object. It will decrement the
-reference count for the object. Assuming there are no other users of
-the object, it will be left at 1.
+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. 
 
-kobject_put() will decrement the reference count of the object, and
-when it reaches 0, call kobject_cleanup(). This will happen
-immediately if there are no other users of the object. 
-kobject_cleanup() will call  the subsystem's release() method
-for the object, and decrement the subsystem's reference count. 
 
-Because kobject_unregister() calls kobject_put(), instead of
-kobject_cleanup() directly, when an object is unregistered, the
-pointer to the object is guaranteed to remain valid until the last
-reference to the object has gone away.
+struct subsystem {
+       struct kset             kset;
+       struct rw_semaphore     rwsem;
+};
+
+int subsystem_register(struct subsystem *);
+void subsystem_unregister(struct subsystem *);
 
-Users of objects should call kobject_get() to obtain a reference to
-the object that they are using. If the object passed to it is a valid
-object (i.e. still present in the system), it will return a pointer to
-the object. Otherwise, it will return NULL.
+struct subsystem * subsys_get(struct subsystem * s);
+void subsys_put(struct subsystem * s);
 
-When users are done using an object, they should call kobject_put() to
-decrement the reference count on the object. As explained above, when
-the reference count for the object reaches 0, kobject_cleanup() will
-be called for the object.
 
+A subsystem contains an embedded kset so:
 
-3.2 Backend Usage
+- It can be represented in the object hierarchy via the kset's
+  embedded kobject. 
 
-Users of the kobject infrastructure may use the backend functions
-directly. In order to maintain consistency and reduce confusion, users
-of the interface should use only the front end registration-oriented
-interface, or the backend helpers. 
+- It can maintain a default list of objects of one type. 
 
-Using the backend helpers allows code to use the kobjects solely for
-the reference counting and garbage collection mechanisms, and
-optionally adding them to the object hierarchy or exporting them via
-sysfs. 
+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.) 
 
-To take advantage of this side of the interface, users should call
-kobject_init() to initialize the object. As stated above, this will
-leave the reference count of the object at 1, and will enable the
-subsystem to use the reference count of the object.
+All ksets that are attached to a subsystem share the subsystem's R/W
+semaphore. 
 
-When the life of the object is ending, the kobject_put() should be
-called to decrement the reference count of the object. Just like
-above, this will call kobject_cleanup() when the reference count
-reaches 0, and release() method of the object's subsystem will be
-called. 
 
-During the lifetime of the object, kobject_add() and kobject_del() may
-be called to add the object to the hierarchy and export it via
-sysfs. kobject_del() must always be called if kobject_add() has
-previously been called. Care should be taken to ensure kobject_del()
-is called before the final kobject_put() is called, though not doing
-so will not cause catastrophe, only confusion when reading the source
-code. Fatal results are avoided by having kobject_add() increment the
-reference count of the object, for kobject_del() to decrement. 
+4.2 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).
 
-3.3 Summary
 
-Using either interface, users should obtain the same results. The
-registration interface does the same actions as the backend interface,
-though it guarantees that initialization and addition, and deletion
-and cleanup, happen consecutively.
+4.3 Helpers
 
+A number of macros are available to make dealing with subsystems, and
+their embedded objects easier. 
 
-Familial Relations
 
-kobjects and subsystems intersect and intertwine in several ways. Each
-is well-defined (though maybe they could be made simpler). Each kobject
-belongs to a subsystem. Since subsystems are kobjects themselves, they
-also belong to a controlling subsystem. This implies that subsystems
-are hierarchial. 
+decl_subsys(name,type)
 
-Many kobjects are hierarchial in nature, which is represented by
-including a pointer to its parent kobject in struct kobject. Many
-different types of kobject-embedding objects may all point to the same
-parent. 
+Declares a subsystem named '<name>_subsys', with an embedded kset of
+type <type>. For example, 
 
-The ancestral hierarchy of kobjects should not be confused with
-membership in a subsystem, or the ancestral relationship of
-subsystems. A set of kobjects may all belong to a subsystem, but all
-have different parents. 
+decl_subsys(devices,&ktype_devices);
 
-kobjects may be orphans and have no explicit parent. In that case, the
-subsystem to which the object belongs becomes its parent. 
+is equivalent to doing:
 
+struct subsystem device_subsys = {
+       .kset = {
+            .kobj = {
+                  .name = "devices",
+            },
+            .ktype = &ktype_devices,
+       }
+}; 
 
-Sysfs
 
-These rules force a complete kobject hierarchy, which Suprise! maps
-very well onto a filesystem.
+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: 
 
-driverfs was recently cloned, and there now exists sysfs. All driverfs
-operations operate on a separate data type: struct driver_dir_entry,
-which all objects that are represented in driverfs must have. driverfs
-also allowed rogue directory creation that had no explicit objects
-associated with them.
 
-struct kobject is intended to be the common data type which sysfs
-operates on. This gives the filesystem the ability to directly access
-more fields of the object, including the reference count. This also
-forces each directory in the filesystem to be tied directly to a
-kobject. 
+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.
 
-Directory Placement
 
-Parental relationships are determined in the kobject/subsystem layer,
-and the kobject is then passed off to the sysfs layer. kobjects with
-no parent have directories created for them in the sysfs root
-directory. Per the rules above, the only kobjects that remain orphans
-are subsystems without parent subsystems (since leaf objects either
-have an explicit parent, or are assigned their controlling subsystem
-as their foster parent). 
+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. 
 
-File Callbacks
+subsys_set_kset(obj,subsys)
 
-Previously, each driverfs directory contained a pointer to a list of file
-operations for reading and writing driverfs files. These callbacks
-received a struct driver_dir_entry, when they performed a
-container_of() transform on to receive the specific object type for
-which the call was meant. 
+- Assumes obj->subsys exists, and is a struct subsystem.
+- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset.
 
-These callbacks have been converted to accept a struct kobject instead
-of struct driver_dir_entry. Since all kobjects belong to a subsystem
-that contains kobjects all of the same type, the sysfs operations
-have been moved to reside in the subsystem, since they are common for
-all kobjects.
 
+4.4 sysfs
 
-Default Attributes
+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. 
 
-Most subsystems have a set of default attributes associated with an
-object that registers with them. A subsystem definition may contain a
-NULL-terminated array of attributes that will be exported when an
-object is registered with the subsystem. 
+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).