DragonFly On-Line Manual Pages

Search: Section:  


DSCHED(9)	      DragonFly Kernel Developer's Manual	     DSCHED(9)

NAME

dsched, dsched_cancel_bio, dsched_debug, dsched_disk_ctx_ref, dsched_disk_ctx_unref, dsched_new_policy_thread_tdio, dsched_register, dsched_strategy_async, dsched_strategy_raw, dsched_thread_io_ref, dsched_thread_io_unref, dsched_unregister, DSCHED_POLICY_MODULE, DSCHED_DISK_CTX_LOCK, DSCHED_DISK_CTX_UNLOCK, DSCHED_THREAD_IO_LOCK, DSCHED_THREAD_IO_UNLOCK, dsched_get_bio_dp, dsched_get_bio_priv, dsched_get_disk_priv -- kernel disk scheduler framework

SYNOPSIS

#include <sys/dsched.h> Functions: void dsched_cancel_bio(struct bio *bp); int dsched_debug(int level, char *fmt, ...); void dsched_disk_ctx_ref(struct dsched_disk_ctx *diskctx); void dsched_disk_ctx_unref(struct dsched_disk_ctx *diskctx); void dsched_new_policy_thread_tdio(struct dsched_disk_ctx *diskctx, struct dsched_policy *pol); int dsched_register(struct dsched_policy *d_policy); void dsched_strategy_async(struct disk *dp, struct bio *bp, biodone_t *done, void *priv); void dsched_strategy_raw(struct disk *dp, struct bio *bp); void dsched_thread_io_ref(struct dsched_thread_io *tdio); void dsched_thread_io_unref(struct dsched_thread_io *tdio); int dsched_unregister(struct dsched_policy *d_policy); Macros: DSCHED_POLICY_MODULE(name, modeventhand_t evh, version); DSCHED_DISK_CTX_LOCK(struct dsched_disk_ctx *diskctx); DSCHED_DISK_CTX_UNLOCK(struct dsched_disk_ctx *diskctx); DSCHED_THREAD_IO_LOCK(struct dsched_thread_io *tdio); DSCHED_THREAD_IO_UNLOCK(struct dsched_thread_io *tdio); dsched_get_bio_dp(struct bio *bio); dsched_get_bio_priv(struct bio *bio); dsched_get_disk_priv(struct disk *dp, void *priv); Callbacks: typedef int dsched_prepare_t(struct dsched_disk_ctx *diskctx); typedef void dsched_teardown_t(struct dsched_disk_ctx *diskctx); typedef void dsched_cancel_t(struct dsched_disk_ctx *diskctx); typedef int dsched_queue_t(struct dsched_disk_ctx *diskctx, struct dsched_thread_io *tdio, struct bio *bio); typedef void dsched_new_tdio_t(struct dsched_thread_io *tdio); typedef void dsched_destroy_tdio_t(struct dsched_thread_io *tdio); typedef void dsched_new_diskctx_t(struct dsched_disk_ctx *diskctx); typedef void dsched_destroy_diskctx_t(struct dsched_disk_ctx *diskctx);

DESCRIPTION

To create a new dsched policy `foo' the following is required: DSCHED_POLICY_MODULE(dsched_foo, foo_mod_handler, 1); struct dsched_policy dsched_foo_policy = { .name = "foo", .prepare = foo_prepare, .teardown = foo_teardown, .cancel_all = foo_cancel, .bio_queue = foo_queue, /* The following are optional */ .new_tdio = foo_tdio_ctor, .new_diskctx = foo_diskctx_ctor, .destroy_tdio = foo_tdio_dtor, .destroy_diskctx = foo_diskctx_dtor }; The name is the unique identifier of the dsched policy and the name the user specifies to set this dsched policy. The prepare callback is called whenever the new dsched policy is set for a new disk. This can be used to create per disk threads for the dsched policy instance. Note that any thread created during prepare will not have a dsched_thread_ctx or dsched_thread_io associated with it. If this is required because the thread will do I/O, the thread itself needs to call dsched_new_policy_thread_tdio(). The teardown callback is called whenever a dsched policy is unset/detached from a disk or when a disk is disconnected. It should clean up all per-disk resources such as any thread created in prepare. The dsched framework guarantees that no more calls to any other method such as bio_queue will occur once teardown has been called. The cancel_all callback is called immediately before teardown. It is required to cancel all bios currently queued or stalled in the dsched policy instance for the given disk. The dsched framework guarantees that no more calls to any other method such as bio_queue will occur once cancel_all has been called. The bio_queue callback is called for every bio intended for the disk(s) with the given dsched policy. It needs to either dispatch it, queue it in any other form for later dispatch, or return a non-zero return value, in which case the dsched framework will dispatch that bio directly. If the function took care of the bio and does not want dsched to dispatch it, 0 must be returned. The new_tdio callback is called for every dsched_thread_io created for a disk with this dsched policy. Similarly, the destroy_tdio callback is called on destruction (release of all references) of the dsched_thread_io. These functions don't have to be specified; if they are left out or set to NULL they simply won't be called. The new_diskctx callback is called for every dsched_disk_ctx created for a disk with this dsched policy. Similarly, the destroy_diskctx callback is called on destruction (release of all references) of the dsched_disk_ctx. These functions don't have to be specified; if they are left out or set to NULL, they simply won't be called. For convenience, the structs dsched_thread_io and dsched_disk_ctx are allocated with plenty of spare space, so that each policy can extend these, for example as follows: struct foo_thread_io { struct dsched_thread_io head; int foo; int bar; }; struct foo_disk_ctx { struct dsched_disk_ctx head; int foo; int bar; }; CTASSERT(sizeof(struct foo_thread_io) <= DSCHED_THREAD_IO_MAX_SZ); CTASSERT(sizeof(struct foo_disk_ctx) <= DSCHED_DISK_CTX_MAX_SZ); It is important that the first member of the new struct is one of type dsched_thread_io or dsched_disk_ctx, respectively. The CTASSERT() must be used to ensure that the new structs fit into the space provided by dsched. Not including these asserts can cause serious and difficult to debug issues. For all the functions described in FUNCTIONS that require a dsched_thread_io or dsched_disk_ctx, the address of the head element should be passed, or alternatively the address of the new struct be cast to the right type and that passed.

FUNCTIONS

The DSCHED_POLICY_MODULE() macro declares a dsched policy kernel module. evh is the event handler for the module (see DECLARE_MODULE(9) for more information). The event handler is supposed to register a dsched policy with dsched_register() on load and to unregister it using dsched_unregister() when it is unloaded. version is the version number of the module (see MODULE_VERSION(9) for more information). The dsched_strategy_async() function dispatches a bio bp in an asynchro- nous manner to the disk specified by dp. The private data priv will be attached to the bio and is later retrievable via dsched_get_bio_priv(). The biodone_t routine done will be called once the bio completes. The done routine can use dsched_get_disk_priv(), dsched_get_bio_dp() and dsched_get_bio_priv() to retrieve the context. Since dsched_strategy_async() also saves the current time (via getmicrotime()) in bio->bio_caller_info3.tv, the done routine can also calculate the time passed from dispatch to completion by getting the current time again (via getmicrotime()) and calculating the timeval difference to the value stored in bio->bio_caller_info3.tv. At the end of the done routine it needs to call pop_bio() and biodone() as for any other biodone_t routine. The dsched_cancel_bio() function cancels the bio and sets ENXIO as error on the buf. The dsched_strategy_raw() function simply dispatches the bio directly to the disk specified by dp using dev_dstrategy(). The dsched_debug() function works as a conditional kprintf(). Depending on the setting of the dsched.debug sysctl(8) variable, the debug info will be shown or not. The dsched_register() function registers the policy described by d_policy as a valid dsched policy which can then be used as a scheduler policy for the disks. If a policy with the given name already exists, EEXIST is returned (otherwise 0). The dsched_unregister() function unregisters the policy described by d_policy. The given dsched policy will no longer be valid as a scheduler policy. If the given policy is currently in use, EBUSY will be returned and the policy won't be unregistered; otherwise 0 is returned. The DSCHED_THREAD_IO_LOCK() and DSCHED_THREAD_IO_UNLOCK() functions lock and unlock a dsched_thread_io tdio, respectively. The lock must be held whenever the members queue and qlength are manipulated to avoid messing up the TAILQ. It can also be used to serialize any other access to the derived foo_thread_io members. The DSCHED_DISK_CTX_LOCK() and DSCHED_DISK_CTX_UNLOCK() functions lock and unlock a dsched_disk_ctx diskctx, respectively. The lock must be held whenever the member queue is manipulated to avoid messing up the TAILQ. It can also be used to serialize any other access to the derived foo_disk_ctx members. The dsched_thread_io_ref() and dsched_thread_io_unref() functions increase and decrease the reference count on a dsched_thread_io tdio, respectively. Whenever the reference count drops to 0, the tdio will be released. Be aware that it is possible that the dsched framework holds references on the tdio, too, so it can be that the object is not freed when all references are dropped. The dsched_disk_ctx_ref() and dsched_disk_ctx_unref() functions increase and decrease the reference count on a dsched_disk_ctx diskctx, respec- tively. Whenever the reference count drops to 0, the diskctx will be released. Be aware that it is possible that the dsched framework holds references on the diskctx, too, so it can be that the object is not freed when all references are dropped. The dsched_get_bio_dp(), dsched_get_disk_priv() and dsched_get_bio_priv() are intended for use in the biodone_t routine specified in the call to dsched_strategy_async(). dsched_get_bio_dp() retrieves the struct disk associated with the bio. This can then be used to retrieve the struct dsched_disk_ctx via dsched_get_disk_priv(). The dsched_get_bio_priv() function returns the private data associated with the bio on the call to dsched_strategy_async(). The dsched_new_policy_thread_tdio() function must be called from any thread created within the prepare method that will perform I/O, since these won't have a dsched_thread_io associated with them.

FILES

The uncontended path of the dsched implementation is in /sys/kern/kern_dsched.c. The data structures are in /sys/sys/dsched.h.

SEE ALSO

dsched(4)

HISTORY

The dsched framework first appeared in DragonFly 2.5.

AUTHORS

The dsched framework was written by Alex Hornung. DragonFly 4.3 September 18, 2013 DragonFly 4.3

Search: Section: