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
32 .Dd September 29, 2010
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"
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);
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
305 .Fn dsched_strategy_async
306 function dispatches a
308 in an asynchronous manner to the disk specified by
312 will be attached to the
314 and is later retrievable via
315 .Fn dsched_get_bio_priv .
320 will be called once the
326 .Fn dsched_get_disk_priv ,
327 .Fn dsched_get_bio_dp
329 .Fn dsched_get_bio_priv
330 to retrieve the context.
332 .Fn dsched_strategy_async
333 also saves the current time (via
336 .Fa bio->bio_caller_info3.tv ,
339 routine can also calculate the time passed from dispatch to completion
340 by getting the current time again (via
342 and calculating the timeval difference to the value stored in
343 .Fa bio->bio_caller_info3.tv .
346 routine it needs to call
355 .Fn dsched_cancel_bio
363 .Fn dsched_strategy_raw
364 function simply dispatches the
366 directly to the disk specified by
373 function works as a conditional
375 Depending on the setting of the
378 variable, the debug info will be shown or not.
382 function registers the policy described by
386 policy which can then be used as a scheduler policy for the disks.
387 If a policy with the given name already exists,
389 is returned (otherwise 0).
392 .Fn dsched_unregister
393 function unregisters the policy described by
397 policy will no longer be valid as a scheduler policy.
398 If the given policy is currently in use,
400 will be returned and the policy won't be unregistered; otherwise 0 is returned.
403 .Fn DSCHED_THREAD_IO_LOCK
405 .Fn DSCHED_THREAD_IO_UNLOCK
406 functions lock and unlock a
410 The lock must be held whenever the members
414 are manipulated to avoid messing up the
416 It can also be used to serialize any other access to the derived
421 .Fn DSCHED_DISK_CTX_LOCK
423 .Fn DSCHED_DISK_CTX_UNLOCK
424 functions lock and unlock a
428 The lock must be held whenever the member
430 is manipulated to avoid messing up the
432 It can also be used to serialize any other access to the derived
437 .Fn dsched_thread_io_ref
439 .Fn dsched_thread_io_unref
440 functions increase and decrease the reference count on a
444 Whenever the reference count drops to 0, the
447 Be aware that it is possible that the
449 framework holds references on the
451 too, so it can be that the object is not freed when all
452 references are dropped.
455 .Fn dsched_disk_ctx_ref
457 .Fn dsched_disk_ctx_unref
458 functions increase and decrease the reference count on a
462 Whenever the reference count drops to 0, the
465 Be aware that it is possible that the
467 framework holds references on the
469 too, so it can be that the object is not freed when all
470 references are dropped.
473 .Fn dsched_get_bio_dp ,
474 .Fn dsched_get_disk_priv
476 .Fn dsched_get_bio_priv
477 are intended for use in the
479 routine specified in the call to
480 .Fn dsched_strategy_async .
481 .Fn dsched_get_bio_dp
486 This can then be used to retrieve the
487 .Vt struct dsched_disk_ctx
489 .Fn dsched_get_disk_priv .
491 .Fn dsched_get_bio_priv
492 function returns the private data associated with the
495 .Fn dsched_strategy_async .
498 .Fn dsched_new_policy_thread_tdio
499 function must be called from any thread created within the
501 method that will perform I/O, since these won't have a
503 associated with them.
504 The function returns a new
506 for the current thread, for
513 The uncontended path of the
516 .Pa /sys/kern/kern_dsched.c .
517 The data structures are in
518 .Pa /sys/sys/dsched.h .
524 framework first appeared in
529 framework was written by