3 .\" The DragonFly Project. All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in
13 .\" the documentation and/or other materials provided with the
15 .\" 3. Neither the name of The DragonFly Project nor the names of its
16 .\" contributors may be used to endorse or promote products derived
17 .\" from this software without specific, prior written permission.
19 .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 .\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 .\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 .\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 .Nm dsched_cancel_bio ,
39 .Nm dsched_disk_ctx_ref ,
40 .Nm dsched_disk_ctx_unref ,
41 .Nm dsched_new_policy_thread_tdio ,
43 .Nm dsched_strategy_async ,
44 .Nm dsched_strategy_raw ,
45 .Nm dsched_thread_io_ref ,
46 .Nm dsched_thread_io_unref ,
47 .Nm dsched_unregister ,
48 .Nm DSCHED_POLICY_MODULE ,
49 .Nm DSCHED_DISK_CTX_LOCK ,
50 .Nm DSCHED_DISK_CTX_UNLOCK ,
51 .Nm DSCHED_THREAD_IO_LOCK ,
52 .Nm DSCHED_THREAD_IO_UNLOCK ,
53 .Nm dsched_get_bio_dp ,
54 .Nm dsched_get_bio_priv ,
55 .Nm dsched_get_disk_priv
56 .Nd kernel disk scheduler framework
62 .Fn dsched_cancel_bio "struct bio *bp"
64 .Fn dsched_debug "int level" "char *fmt" "..."
66 .Fn dsched_disk_ctx_ref "struct dsched_disk_ctx *diskctx"
68 .Fn dsched_disk_ctx_unref "struct dsched_disk_ctx *diskctx"
69 .Ft struct dsched_thread_io *
70 .Fn dsched_new_policy_thread_tdio "struct dsched_disk_ctx *diskctx" "struct dsched_policy *pol"
72 .Fn dsched_register "struct dsched_policy *d_policy"
74 .Fn dsched_strategy_async "struct disk *dp" "struct bio *bp" "biodone_t *done" "void *priv"
76 .Fn dsched_strategy_raw "struct disk *dp" "struct bio *bp"
78 .Fn dsched_thread_io_ref "struct dsched_thread_io *tdio"
80 .Fn dsched_thread_io_unref "struct dsched_thread_io *tdio"
82 .Fn dsched_unregister "struct dsched_policy *d_policy"
85 .Fn DSCHED_POLICY_MODULE "name" "modeventhand_t evh" "version"
86 .Fn DSCHED_DISK_CTX_LOCK "struct dsched_disk_ctx *diskctx"
87 .Fn DSCHED_DISK_CTX_UNLOCK "struct dsched_disk_ctx *diskctx"
88 .Fn DSCHED_THREAD_IO_LOCK "struct dsched_thread_io *tdio"
89 .Fn DSCHED_THREAD_IO_UNLOCK "struct dsched_thread_io *tdio"
90 .Fn dsched_get_bio_dp "struct bio *bio"
91 .Fn dsched_get_bio_priv "struct bio *bio"
92 .Fn dsched_get_disk_priv "struct disk *dp" "void *priv"
96 .Fn dsched_prepare_t "struct dsched_disk_ctx *diskctx"
98 .Fn dsched_teardown_t "struct dsched_disk_ctx *diskctx"
100 .Fn dsched_cancel_t "struct dsched_disk_ctx *diskctx"
102 .Fn dsched_queue_t "struct dsched_disk_ctx *diskctx" "struct dsched_thread_io *tdio" "struct bio *bio"
104 .Fn dsched_new_tdio_t "struct dsched_thread_io *tdio"
106 .Fn dsched_destroy_tdio_t "struct dsched_thread_io *tdio"
108 .Fn dsched_new_diskctx_t "struct dsched_disk_ctx *diskctx"
110 .Fn dsched_destroy_diskctx_t "struct dsched_disk_ctx *diskctx"
112 To create a new dsched policy
114 the following is required:
116 DSCHED_POLICY_MODULE(dsched_foo, foo_mod_handler, 1);
118 struct dsched_policy dsched_foo_policy = {
121 .prepare = foo_prepare,
122 .teardown = foo_teardown,
123 .cancel_all = foo_cancel,
124 .bio_queue = foo_queue,
126 /* The following are optional */
127 .new_tdio = foo_tdio_ctor,
128 .new_diskctx = foo_diskctx_ctor,
129 .destroy_tdio = foo_tdio_dtor,
130 .destroy_diskctx = foo_diskctx_dtor
136 is the unique identifier of the dsched policy and the name the user
137 specifies to set this
143 callback is called whenever the new
145 policy is set for a new disk.
146 This can be used to create per disk threads for the
149 Note that any thread created during
152 .Ft dsched_thread_ctx
156 If this is required because the thread will do I/O, the thread itself
158 .Fn dsched_new_policy_thread_tdio .
162 callback is called whenever a
164 policy is unset/detached from a disk or when a disk is disconnected.
165 It should clean up all per-disk resources such as any thread created in
169 framework guarantees that no more calls to any other method such as
177 callback is called immediately before
179 It is required to cancel all
181 currently queued or stalled in the
183 policy instance for the given disk.
186 framework guarantees that no more calls to any other method such as
194 callback is called for every
196 intended for the disk(s) with the given
199 It needs to either dispatch it, queue it in any other form for later
200 dispatch, or return a non-zero return value, in which case the
202 framework will dispatch that
205 If the function took care of the
207 and does not want dsched to dispatch it, 0 must be returned.
211 callback is called for every
213 created for a disk with this
218 callback is called on destruction (release of all references) of the
219 .Vt dsched_thread_io .
220 These functions don't have to be specified; if they are left out or
223 they simply won't be called.
227 callback is called for every
229 created for a disk with this
234 callback is called on destruction (release of all references) of the
235 .Vt dsched_disk_ctx .
236 These functions don't have to be specified; if they are left out or
239 they simply won't be called.
241 For convenience, the structs
245 are allocated with plenty of spare space, so that each policy can extend
246 these, for example as follows:
248 struct foo_thread_io {
249 struct dsched_thread_io head;
254 struct foo_disk_ctx {
255 struct dsched_disk_ctx head;
260 CTASSERT(sizeof(struct foo_thread_io) <= DSCHED_THREAD_IO_MAX_SZ);
261 CTASSERT(sizeof(struct foo_disk_ctx) <= DSCHED_DISK_CTX_MAX_SZ);
264 It is important that the first member of the new struct is one of type
267 .Vt dsched_disk_ctx ,
271 must be used to ensure that the new structs fit into the space provided
274 Not including these asserts can cause serious and difficult to debug
276 For all the functions described in
281 .Vt dsched_disk_ctx ,
284 element should be passed, or alternatively the address of the new struct
285 be cast to the right type and that passed.
288 .Fn DSCHED_POLICY_MODULE
291 policy kernel module.
293 is the event handler for the module (see
295 for more information).
296 The event handler is supposed to register a
300 on load and to unregister it using
301 .Fn dsched_unregister
304 is the version number of the module (see
306 for more information).
309 .Fn dsched_strategy_async
310 function dispatches a
312 in an asynchronous manner to the disk specified by
316 will be attached to the
318 and is later retrievable via
319 .Fn dsched_get_bio_priv .
324 will be called once the
330 .Fn dsched_get_disk_priv ,
331 .Fn dsched_get_bio_dp
333 .Fn dsched_get_bio_priv
334 to retrieve the context.
336 .Fn dsched_strategy_async
337 also saves the current time (via
340 .Fa bio->bio_caller_info3.tv ,
343 routine can also calculate the time passed from dispatch to completion
344 by getting the current time again (via
346 and calculating the timeval difference to the value stored in
347 .Fa bio->bio_caller_info3.tv .
350 routine it needs to call
359 .Fn dsched_cancel_bio
367 .Fn dsched_strategy_raw
368 function simply dispatches the
370 directly to the disk specified by
377 function works as a conditional
379 Depending on the setting of the
382 variable, the debug info will be shown or not.
386 function registers the policy described by
390 policy which can then be used as a scheduler policy for the disks.
391 If a policy with the given name already exists,
393 is returned (otherwise 0).
396 .Fn dsched_unregister
397 function unregisters the policy described by
401 policy will no longer be valid as a scheduler policy.
402 If the given policy is currently in use,
404 will be returned and the policy won't be unregistered; otherwise 0 is returned.
407 .Fn DSCHED_THREAD_IO_LOCK
409 .Fn DSCHED_THREAD_IO_UNLOCK
410 functions lock and unlock a
414 The lock must be held whenever the members
418 are manipulated to avoid messing up the
420 It can also be used to serialize any other access to the derived
425 .Fn DSCHED_DISK_CTX_LOCK
427 .Fn DSCHED_DISK_CTX_UNLOCK
428 functions lock and unlock a
432 The lock must be held whenever the member
434 is manipulated to avoid messing up the
436 It can also be used to serialize any other access to the derived
441 .Fn dsched_thread_io_ref
443 .Fn dsched_thread_io_unref
444 functions increase and decrease the reference count on a
448 Whenever the reference count drops to 0, the
451 Be aware that it is possible that the
453 framework holds references on the
455 too, so it can be that the object is not freed when all
456 references are dropped.
459 .Fn dsched_disk_ctx_ref
461 .Fn dsched_disk_ctx_unref
462 functions increase and decrease the reference count on a
466 Whenever the reference count drops to 0, the
469 Be aware that it is possible that the
471 framework holds references on the
473 too, so it can be that the object is not freed when all
474 references are dropped.
477 .Fn dsched_get_bio_dp ,
478 .Fn dsched_get_disk_priv
480 .Fn dsched_get_bio_priv
481 are intended for use in the
483 routine specified in the call to
484 .Fn dsched_strategy_async .
485 .Fn dsched_get_bio_dp
490 This can then be used to retrieve the
491 .Vt struct dsched_disk_ctx
493 .Fn dsched_get_disk_priv .
495 .Fn dsched_get_bio_priv
496 function returns the private data associated with the
499 .Fn dsched_strategy_async .
502 .Fn dsched_new_policy_thread_tdio
503 function must be called from any thread created within the
505 method that will perform I/O, since these won't have a
507 associated with them.
508 The function returns a new
510 for the current thread, for
517 The uncontended path of the
520 .Pa /sys/kern/kern_dsched.c .
521 The data structures are in
522 .Pa /sys/sys/dsched.h .
528 framework first appeared in
533 framework was written by