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