From: Alex Hornung Date: Fri, 23 Apr 2010 10:17:09 +0000 (+0000) Subject: dsched - serno support X-Git-Tag: v2.7.3~59 X-Git-Url: https://gitweb.dragonflybsd.org/~hofmann/dragonfly.git/commitdiff_plain/279e9fd506d4b93d3083b8db7864718937e2f93e dsched - serno support * Add support for serno loader tunables, e.g. dsched.policy.WD1293193 = "fq". * Incidentally do another name change on the loader tunables from kern.dsched.* to dsched.* to have the same namespace as the sysctls. * Add a sysctl dsched.policies showing the currently available policies. --- diff --git a/sys/kern/kern_dsched.c b/sys/kern/kern_dsched.c index 55b1935cf8..44b97d0173 100644 --- a/sys/kern/kern_dsched.c +++ b/sys/kern/kern_dsched.c @@ -144,21 +144,21 @@ dsched_disk_create_callback(struct disk *dp, const char *head_name, int unit) /* kprintf("dsched_disk_create_callback() for disk %s%d\n", head_name, unit); */ lockmgr(&dsched_lock, LK_EXCLUSIVE); - ksnprintf(tunable_key, sizeof(tunable_key), "kern.dsched.policy.%s%d", + ksnprintf(tunable_key, sizeof(tunable_key), "dsched.policy.%s%d", head_name, unit); if (TUNABLE_STR_FETCH(tunable_key, sched_policy, sizeof(sched_policy)) != 0) { policy = dsched_find_policy(sched_policy); } - ksnprintf(tunable_key, sizeof(tunable_key), "kern.dsched.policy.%s", + ksnprintf(tunable_key, sizeof(tunable_key), "dsched.policy.%s", head_name); if (!policy && (TUNABLE_STR_FETCH(tunable_key, sched_policy, sizeof(sched_policy)) != 0)) { policy = dsched_find_policy(sched_policy); } - ksnprintf(tunable_key, sizeof(tunable_key), "kern.dsched.policy.default"); + ksnprintf(tunable_key, sizeof(tunable_key), "dsched.policy.default"); if (!policy && (TUNABLE_STR_FETCH(tunable_key, sched_policy, sizeof(sched_policy)) != 0)) { policy = dsched_find_policy(sched_policy); @@ -175,6 +175,37 @@ dsched_disk_create_callback(struct disk *dp, const char *head_name, int unit) lockmgr(&dsched_lock, LK_RELEASE); } +/* + * Called from disk_setdiskinfo (or rather _setdiskinfo). This will check if + * there's any policy associated with the serial number of the device. + */ +void +dsched_disk_update_callback(struct disk *dp, struct disk_info *info) +{ + char tunable_key[SPECNAMELEN + 48]; + char sched_policy[DSCHED_POLICY_NAME_LENGTH]; + struct dsched_policy *policy = NULL; + + if (info->d_serialno == NULL) + return; + + lockmgr(&dsched_lock, LK_EXCLUSIVE); + + ksnprintf(tunable_key, sizeof(tunable_key), "dsched.policy.%s", + info->d_serialno); + + if((TUNABLE_STR_FETCH(tunable_key, sched_policy, + sizeof(sched_policy)) != 0)) { + policy = dsched_find_policy(sched_policy); + } + + if (policy) { + dsched_switch(dp, policy); + } + + lockmgr(&dsched_lock, LK_RELEASE); +} + /* * Called on disk_destroy() * shuts down the scheduler core and cancels all remaining bios @@ -1100,7 +1131,7 @@ dsched_init(void) bzero(&dsched_stats, sizeof(struct dsched_stats)); - lockinit(&dsched_lock, "dsched lock", 0, 0); + lockinit(&dsched_lock, "dsched lock", 0, LK_CANRECURSE); DSCHED_GLOBAL_THREAD_CTX_LOCKINIT(); dsched_register(&dsched_default_policy); @@ -1139,15 +1170,47 @@ SYSUNINIT(subr_dsched_dev_register, SI_SUB_DRIVERS, SI_ORDER_ANY, dsched_dev_uni * SYSCTL stuff */ static int -do_dsched_stats(SYSCTL_HANDLER_ARGS) +sysctl_dsched_stats(SYSCTL_HANDLER_ARGS) { return (sysctl_handle_opaque(oidp, &dsched_stats, sizeof(struct dsched_stats), req)); } +static int +sysctl_dsched_list_policies(SYSCTL_HANDLER_ARGS) +{ + struct dsched_policy *pol = NULL; + int error, first = 1; + + lockmgr(&dsched_lock, LK_EXCLUSIVE); + + while ((pol = dsched_policy_enumerate(pol))) { + if (!first) { + error = SYSCTL_OUT(req, " ", 1); + if (error) + break; + } else { + first = 0; + } + error = SYSCTL_OUT(req, pol->name, strlen(pol->name)); + if (error) + break; + + } + + lockmgr(&dsched_lock, LK_RELEASE); + + error = SYSCTL_OUT(req, "", 1); + + return error; +} + SYSCTL_NODE(, OID_AUTO, dsched, CTLFLAG_RD, NULL, "Disk Scheduler Framework (dsched) magic"); SYSCTL_INT(_dsched, OID_AUTO, debug, CTLFLAG_RW, &dsched_debug_enable, 0, "Enable dsched debugging"); SYSCTL_PROC(_dsched, OID_AUTO, stats, CTLTYPE_OPAQUE|CTLFLAG_RD, - 0, sizeof(struct dsched_stats), do_dsched_stats, "dsched_stats", + 0, sizeof(struct dsched_stats), sysctl_dsched_stats, "dsched_stats", "dsched statistics"); +SYSCTL_PROC(_dsched, OID_AUTO, policies, CTLTYPE_STRING|CTLFLAG_RD, + NULL, 0, sysctl_dsched_list_policies, "A", "names of available policies"); + diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 23acd0a5b1..530262ac8f 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -567,6 +567,8 @@ _setdiskinfo(struct disk *disk, struct disk_info *info) if (oldserialno) kfree(oldserialno, M_TEMP); + dsched_disk_update_callback(disk, info); + /* * The caller may set d_media_size or d_media_blocks and we * calculate the other. diff --git a/sys/sys/dsched.h b/sys/sys/dsched.h index 6907088304..7beffdaa80 100644 --- a/sys/sys/dsched.h +++ b/sys/sys/dsched.h @@ -57,6 +57,9 @@ #ifndef _SYS_SYSCTL_H_ #include #endif +#ifndef SYS_DISK_H_ +#include +#endif #define DSCHED_POLICY_NAME_LENGTH 64 @@ -196,6 +199,7 @@ static moduledata_t name##_mod = { \ DECLARE_MODULE(name, name##_mod, SI_SUB_PRE_DRIVERS, SI_ORDER_MIDDLE) void dsched_disk_create_callback(struct disk *dp, const char *head_name, int unit); +void dsched_disk_update_callback(struct disk *dp, struct disk_info *info); void dsched_disk_destroy_callback(struct disk *dp); void dsched_queue(struct disk *dp, struct bio *bio); int dsched_register(struct dsched_policy *d_policy);