xref: /freebsd/share/man/man9/khelp.9 (revision a64729f5077d77e13b9497cb33ecb3c82e606ee8)
1.\"
2.\" Copyright (c) 2010-2011 The FreeBSD Foundation
3.\"
4.\" This documentation was written at the Centre for Advanced Internet
5.\" Architectures, Swinburne University of Technology, Melbourne, Australia by
6.\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD
7.\" Foundation.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
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.
17.\"
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
28.\" SUCH DAMAGE.
29.\"
30.Dd October 1, 2024
31.Dt KHELP 9
32.Os
33.Sh NAME
34.Nm khelp ,
35.Nm khelp_init_osd ,
36.Nm khelp_destroy_osd ,
37.Nm khelp_get_id ,
38.Nm khelp_get_osd ,
39.Nm khelp_add_hhook ,
40.Nm khelp_remove_hhook ,
41.Nm KHELP_DECLARE_MOD ,
42.Nm KHELP_DECLARE_MOD_UMA
43.Nd Kernel Helper Framework
44.Sh SYNOPSIS
45.In sys/khelp.h
46.In sys/module_khelp.h
47.Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd"
48.Fn "int khelp_destroy_osd" "struct osd *hosd"
49.Fn "int32_t khelp_get_id" "char *hname"
50.Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id"
51.Fn "int khelp_add_hhook" "const struct hookinfo *hki" "uint32_t flags"
52.Fn "int khelp_remove_hhook" "const struct hookinfo *hki"
53.Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version"
54.Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor"
55.Sh DESCRIPTION
56.Nm
57provides a framework for managing
58.Nm
59modules, which indirectly use the
60.Xr hhook 9
61KPI to register their hook functions with hook points of interest within the
62kernel.
63Khelp modules aim to provide a structured way to dynamically extend the kernel
64at runtime in an ABI preserving manner.
65Depending on the subsystem providing hook points, a
66.Nm
67module may be able to associate per-object data for maintaining relevant state
68between hook calls.
69The
70.Xr hhook 9
71and
72.Nm
73frameworks are tightly integrated and anyone interested in
74.Nm
75should also read the
76.Xr hhook 9
77manual page thoroughly.
78.Ss Information for Khelp Module Implementors
79.Nm
80modules are represented within the
81.Nm
82framework by a
83.Vt struct helper
84which has the following members:
85.Bd -literal -offset indent
86struct helper {
87	int (*mod_init) (void);
88	int (*mod_destroy) (void);
89#define	HELPER_NAME_MAXLEN 16
90	char			h_name[HELPER_NAME_MAXLEN];
91	uma_zone_t		h_zone;
92	struct hookinfo		*h_hooks;
93	uint32_t		h_nhooks;
94	uint32_t		h_classes;
95	int32_t			h_id;
96	volatile uint32_t	h_refcount;
97	uint16_t		h_flags;
98	TAILQ_ENTRY(helper)	h_next;
99};
100.Ed
101.Pp
102Modules must instantiate a
103.Vt struct helper ,
104but are only required to set the
105.Va h_classes
106field, and may optionally set the
107.Va h_flags ,
108.Va mod_init
109and
110.Va mod_destroy
111fields where required.
112The framework takes care of all other fields and modules should refrain from
113manipulating them.
114Using the C99 designated initialiser feature to set fields is encouraged.
115.Pp
116If specified, the
117.Va mod_init
118function will be run by the
119.Nm
120framework prior to completing the registration process.
121Returning a non-zero value from the
122.Va mod_init
123function will abort the registration process and fail to load the module.
124If specified, the
125.Va mod_destroy
126function will be run by the
127.Nm
128framework during the deregistration process, after the module has been
129deregistered by the
130.Nm
131framework.
132The return value is currently ignored.
133Valid
134.Nm
135classes are defined in
136.In sys/khelp.h .
137Valid flags are defined in
138.In sys/module_khelp.h .
139The HELPER_NEEDS_OSD flag should be set in the
140.Va h_flags
141field if the
142.Nm
143module requires persistent per-object data storage.
144There is no programmatic way (yet) to check if a
145.Nm
146class provides the ability for
147.Nm
148modules to associate persistent per-object data, so a manual check is required.
149.Pp
150The
151.Fn KHELP_DECLARE_MOD
152and
153.Fn KHELP_DECLARE_MOD_UMA
154macros provide convenient wrappers around the
155.Xr DECLARE_MODULE 9
156macro, and are used to register a
157.Nm
158module with the
159.Nm
160framework.
161.Fn KHELP_DECLARE_MOD_UMA
162should only be used by modules which require the use of persistent per-object
163storage i.e. modules which set the HELPER_NEEDS_OSD flag in their
164.Vt struct helper Ns 's
165.Va h_flags
166field.
167.Pp
168The first four arguments common to both macros are as follows.
169The
170.Fa hname
171argument specifies the unique
172.Xr ascii 7
173name for the
174.Nm
175module.
176It should be no longer than HELPER_NAME_MAXLEN-1 characters in length.
177The
178.Fa hdata
179argument is a pointer to the module's
180.Vt struct helper .
181The
182.Fa hhooks
183argument points to a static array of
184.Vt struct hookinfo
185structures.
186The array should contain a
187.Vt struct hookinfo
188for each
189.Xr hhook 9
190point the module wishes to hook, even when using the same hook function multiple
191times for different
192.Xr hhook 9
193points.
194The
195.Fa version
196argument specifies a version number for the module which will be passed to
197.Xr MODULE_VERSION 9 .
198The
199.Fn KHELP_DECLARE_MOD_UMA
200macro takes the additional
201.Fa ctor
202and
203.Fa dtor
204arguments, which specify optional
205.Xr uma 9
206constructor and destructor functions.
207NULL should be passed where the functionality is not required.
208.Pp
209The
210.Fn khelp_get_id
211function returns the numeric identifier for the
212.Nm
213module with name
214.Fa hname .
215.Pp
216The
217.Fn khelp_get_osd
218function is used to obtain the per-object data pointer for a specified
219.Nm
220module.
221The
222.Fa hosd
223argument is a pointer to the underlying subsystem object's
224.Vt struct osd .
225This is provided by the
226.Xr hhook 9
227framework when calling into a
228.Nm
229module's hook function.
230The
231.Fa id
232argument specifies the numeric identifier for the
233.Nm
234module to extract the data pointer from
235.Fa hosd
236for.
237The
238.Fa id
239is obtained using the
240.Fn khelp_get_id
241function.
242.Pp
243The
244.Fn khelp_add_hhook
245and
246.Fn khelp_remove_hhook
247functions allow a
248.Nm
249module to dynamically hook/unhook
250.Xr hhook 9
251points at run time.
252The
253.Fa hki
254argument specifies a pointer to a
255.Vt struct hookinfo
256which encapsulates the required information about the
257.Xr hhook 9
258point and hook function being manipulated.
259The HHOOK_WAITOK flag may be passed in via the
260.Fa flags
261argument of
262.Fn khelp_add_hhook
263if
264.Xr malloc 9
265is allowed to sleep waiting for memory to become available.
266.Ss Integrating Khelp Into a Kernel Subsystem
267Most of the work required to allow
268.Nm
269modules to do useful things relates to defining and instantiating suitable
270.Xr hhook 9
271points for
272.Nm
273modules to hook into.
274The only additional decision a subsystem needs to make is whether it wants to
275allow
276.Nm
277modules to associate persistent per-object data.
278Providing support for persistent data storage can allow
279.Nm
280modules to perform more complex functionality which may be desirable.
281Subsystems which want to allow Khelp modules to associate
282persistent per-object data with one of the subsystem's data structures need to
283make the following two key changes:
284.Bl -bullet
285.It
286Embed a
287.Vt struct osd
288pointer in the structure definition for the object.
289.It
290Add calls to
291.Fn khelp_init_osd
292and
293.Fn khelp_destroy_osd
294to the subsystem code paths which are responsible for respectively initialising
295and destroying the object.
296.El
297.Pp
298The
299.Fn khelp_init_osd
300function initialises the per-object data storage for all currently loaded
301.Nm
302modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their
303.Va h_flags
304field.
305The
306.Fa classes
307argument specifies a bitmask of
308.Nm
309classes which this subsystem associates with.
310If a
311.Nm
312module matches any of the classes in the bitmask, that module will be associated
313with the object.
314The
315.Fa hosd
316argument specifies the pointer to the object's
317.Vt struct osd
318which will be used to provide the persistent storage for use by
319.Nm
320modules.
321.Pp
322The
323.Fn khelp_destroy_osd
324function frees all memory that was associated with an object's
325.Vt struct osd
326by a previous call to
327.Fn khelp_init_osd .
328The
329.Fa hosd
330argument specifies the pointer to the object's
331.Vt struct osd
332which will be purged in preparation for destruction.
333.Sh IMPLEMENTATION NOTES
334.Nm
335modules are protected from being prematurely unloaded by a reference count.
336The count is incremented each time a subsystem calls
337.Fn khelp_init_osd
338causing persistent storage to be allocated for the module, and decremented for
339each corresponding call to
340.Fn khelp_destroy_osd .
341Only when a module's reference count has dropped to zero can the module be
342unloaded.
343.Sh RETURN VALUES
344The
345.Fn khelp_init_osd
346function returns zero if no errors occurred.
347It returns ENOMEM if a
348.Nm
349module which requires per-object storage fails to allocate the necessary memory.
350.Pp
351The
352.Fn khelp_destroy_osd
353function only returns zero to indicate that no errors occurred.
354.Pp
355The
356.Fn khelp_get_id
357function returns the unique numeric identifier for the registered
358.Nm
359module with name
360.Fa hname .
361It return -1 if no module with the specified name is currently registered.
362.Pp
363The
364.Fn khelp_get_osd
365function returns the pointer to the
366.Nm
367module's persistent object storage memory.
368If the module identified by
369.Fa id
370does not have persistent object storage registered with the object's
371.Fa hosd
372.Vt struct osd ,
373NULL is returned.
374.Pp
375The
376.Fn khelp_add_hhook
377function returns zero if no errors occurred.
378It returns ENOENT if it could not find the requested
379.Xr hhook 9
380point.
381It returns ENOMEM if
382.Xr malloc 9
383failed to allocate memory.
384It returns EEXIST if attempting to register the same hook function more than
385once for the same
386.Xr hhook 9
387point.
388.Pp
389The
390.Fn khelp_remove_hhook
391function returns zero if no errors occurred.
392It returns ENOENT if it could not find the requested
393.Xr hhook 9
394point.
395.Sh EXAMPLES
396A well commented example Khelp module can be found at:
397.Pa /usr/share/examples/kld/khelp/h_example.c
398.Pp
399The Enhanced Round Trip Time (ERTT)
400.Xr h_ertt 4
401.Nm
402module provides a more complex example of what is possible.
403.Sh SEE ALSO
404.Xr h_ertt 4 ,
405.Xr hhook 9 ,
406.Xr osd 9
407.Sh ACKNOWLEDGEMENTS
408Development and testing of this software were made possible in part by grants
409from the FreeBSD Foundation and Cisco University Research Program Fund at
410Community Foundation Silicon Valley.
411.Sh HISTORY
412The
413.Nm
414kernel helper framework first appeared in
415.Fx 9.0 .
416.Pp
417The
418.Nm
419framework was first released in 2010 by Lawrence Stewart whilst studying at
420Swinburne University of Technology's Centre for Advanced Internet Architectures,
421Melbourne, Australia.
422More details are available at:
423.Pp
424http://caia.swin.edu.au/urp/newtcp/
425.Sh AUTHORS
426.An -nosplit
427The
428.Nm
429framework was written by
430.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
431.Pp
432This manual page was written by
433.An David Hayes Aq Mt david.hayes@ieee.org
434and
435.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
436