2 .\" Copyright (c) 2010-2011 The FreeBSD Foundation
3 .\" All rights reserved.
5 .\" This documentation was written at the Centre for Advanced Internet
6 .\" Architectures, Swinburne University, Melbourne, Australia by David Hayes and
7 .\" Lawrence Stewart under sponsorship from the FreeBSD Foundation.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
12 .\" 1. Redistributions of source code must retain the above copyright
13 .\" notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\" notice, this list of conditions and the following disclaimer in the
16 .\" documentation and/or other materials provided with the distribution.
18 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 .Nm khelp_destroy_osd ,
42 .Nm khelp_remove_hhook ,
43 .Nm KHELP_DECLARE_MOD ,
44 .Nm KHELP_DECLARE_MOD_UMA
45 .Nd Kernel Helper Framework
48 .In sys/module_khelp.h
49 .Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd"
50 .Fn "int khelp_destroy_osd" "struct osd *hosd"
51 .Fn "int32_t khelp_get_id" "char *hname"
52 .Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id"
53 .Fn "int khelp_add_hhook" "struct hookinfo *hki" "uint32_t flags"
54 .Fn "int khelp_remove_hhook" "struct hookinfo *hki"
55 .Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version"
56 .Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor"
59 provides a framework for managing
61 modules, which indirectly use the
63 KPI to register their hook functions with hook points of interest within the
65 Khelp modules aim to provide a structured way to dynamically extend the kernel
66 at runtime in an ABI preserving manner.
67 Depending on the subsystem providing hook points, a
69 module may be able to associate per-object data for maintaining relevant state
75 frameworks are tightly integrated and anyone interested in
79 manual page thoroughly.
80 .Ss Information for Khelp Module Implementors
82 modules are represented within the
86 which has the following members:
87 .Bd -literal -offset indent
89 int (*mod_init) (void);
90 int (*mod_destroy) (void);
91 #define HELPER_NAME_MAXLEN 16
92 char h_name[HELPER_NAME_MAXLEN];
94 struct hookinfo *h_hooks;
98 volatile uint32_t h_refcount;
100 TAILQ_ENTRY(helper) h_next;
104 Modules must instantiate a
106 but are only required to set the
108 field, and may optionally set the
113 fields where required.
114 The framework takes care of all other fields and modules should refrain from
116 Using the C99 designated initialiser feature to set fields is encouraged.
120 function will be run by the
122 framework prior to completing the registration process.
123 Returning a non-zero value from the
125 function will abort the registration process and fail to load the module.
128 function will be run by the
130 framework during the deregistration process, after the module has been
134 The return value is currently ignored.
137 classes are defined in
139 Valid flags are defined in
140 .In sys/module_khelp.h .
141 The HELPER_NEEDS_OSD flag should be set in the
145 module requires persistent per-object data storage.
146 There is no programmatic way (yet) to check if a
148 class provides the ability for
150 modules to associate persistent per-object data, so a manual check is required.
153 .Fn KHELP_DECLARE_MOD
155 .Fn KHELP_DECLARE_MOD_UMA
156 macros provide convenient wrappers around the
158 macro, and are used to register a
163 .Fn KHELP_DECLARE_MOD_UMA
164 should only be used by modules which require the use of persistent per-object
165 storage i.e. modules which set the HELPER_NEEDS_OSD flag in their
166 .Vt struct helper Ns 's
170 The first four arguments common to both macros are as follows.
173 argument specifies the unique
178 It should be no longer than HELPER_NAME_MAXLEN-1 characters in length.
181 argument is a pointer to the module's
185 argument points to a static array of
188 The array should contain a
192 point the module wishes to hook, even when using the same hook function multiple
198 argument specifies a version number for the module which will be passed to
199 .Xr MODULE_VERSION 9 .
201 .Fn KHELP_DECLARE_MOD_UMA
202 macro takes the additional
206 arguments, which specify optional
208 constructor and destructor functions.
209 NULL should be passed where the functionality is not required.
213 function returns the numeric identifier for the
220 function is used to obtain the per-object data pointer for a specified
225 argument is a pointer to the underlying subsystem object's
227 This is provided by the
229 framework when calling into a
231 module's hook function.
234 argument specifies the numeric identifier for the
236 module to extract the data pointer from
241 is obtained using the
248 .Fn khelp_remove_hhook
251 module to dynamically hook/unhook
256 argument specifies a pointer to a
258 which encapsulates the required information about the
260 point and hook function being manipulated.
261 The HHOOK_WAITOK flag may be passed in via the
267 is allowed to sleep waiting for memory to become available.
268 .Ss Integrating Khelp Into a Kernel Subsystem
269 Most of the work required to allow
271 modules to do useful things relates to defining and instantiating suitable
275 modules to hook into.
276 The only additional decision a subsystem needs to make is whether it wants to
279 modules to associate persistent per-object data.
280 Providing support for persistent data storage can allow
282 modules to perform more complex functionality which may be desirable.
283 Subsystems which want to allow Khelp modules to associate
284 persistent per-object data with one of the subsystem's data structures need to
285 make the following two key changes:
290 pointer in the structure definition for the object.
295 .Fn khelp_destroy_osd
296 to the subsystem code paths which are responsible for respectively initialising
297 and destroying the object.
302 function initialises the per-object data storage for all currently loaded
304 modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their
309 argument specifies a bitmask of
311 classes which this subsystem associates with.
314 module matches any of the classes in the bitmask, that module will be associated
318 argument specifies the pointer to the object's
320 which will be used to provide the persistent storage for use by
325 .Fn khelp_destroy_osd
326 function frees all memory that was associated with an object's
328 by a previous call to
332 argument specifies the pointer to the object's
334 which will be purged in preparation for destruction.
335 .Sh IMPLEMENTATION NOTES
337 modules are protected from being prematurely unloaded by a reference count.
338 The count is incremented each time a subsystem calls
340 causing persistent storage to be allocated for the module, and decremented for
341 each corresponding call to
342 .Fn khelp_destroy_osd .
343 Only when a module's reference count has dropped to zero can the module be
348 function returns zero if no errors occurred.
349 It returns ENOMEM if a
351 module which requires per-object storage fails to allocate the necessary memory.
354 .Fn khelp_destroy_osd
355 function only returns zero to indicate that no errors occurred.
359 function returns the unique numeric identifier for the registered
363 It return -1 if no module with the specified name is currently registered.
367 function returns the pointer to the
369 module's persistent object storage memory.
370 If the module identified by
372 does not have persistent object storage registered with the object's
379 function returns zero if no errors occurred.
380 It returns ENOENT if it could not find the requested
385 failed to allocate memory.
386 It returns EEXIST if attempting to register the same hook function more than
392 .Fn khelp_remove_hhook
393 function returns zero if no errors occurred.
394 It returns ENOENT if it could not find the requested
398 A well commented example Khelp module can be found at:
399 .Pa /usr/share/examples/kld/khelp/h_example.c
401 The Enhanced Round Trip Time (ERTT)
404 module provides a more complex example of what is possible.
410 Development and testing of this software were made possible in part by grants
411 from the FreeBSD Foundation and Cisco University Research Program Fund at
412 Community Foundation Silicon Valley.
416 kernel helper framework first appeared in
421 framework was first released in 2010 by Lawrence Stewart whilst studying at
422 Swinburne University's Centre for Advanced Internet Architectures, Melbourne,
424 More details are available at:
426 http://caia.swin.edu.au/urp/newtcp/
431 framework was written by
432 .An Lawrence Stewart Aq lstewart@FreeBSD.org .
434 This manual page was written by
435 .An David Hayes Aq david.hayes@ieee.org
437 .An Lawrence Stewart Aq lstewart@FreeBSD.org .