Module Name: src Committed By: pgoyette Date: Wed Nov 16 00:46:46 UTC 2016
Modified Files: src/sys/kern: bufq_disksort.c bufq_fcfs.c bufq_priocscan.c bufq_readprio.c init_main.c subr_bufq.c src/sys/sys: bufq.h bufq_impl.h Log Message: Modularize the various bufq strategies To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/kern/bufq_disksort.c cvs rdiff -u -r1.10 -r1.11 src/sys/kern/bufq_fcfs.c cvs rdiff -u -r1.18 -r1.19 src/sys/kern/bufq_priocscan.c cvs rdiff -u -r1.13 -r1.14 src/sys/kern/bufq_readprio.c cvs rdiff -u -r1.484 -r1.485 src/sys/kern/init_main.c cvs rdiff -u -r1.21 -r1.22 src/sys/kern/subr_bufq.c cvs rdiff -u -r1.10 -r1.11 src/sys/sys/bufq.h cvs rdiff -u -r1.9 -r1.10 src/sys/sys/bufq_impl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/bufq_disksort.c diff -u src/sys/kern/bufq_disksort.c:1.11 src/sys/kern/bufq_disksort.c:1.12 --- src/sys/kern/bufq_disksort.c:1.11 Mon Jan 19 14:54:28 2009 +++ src/sys/kern/bufq_disksort.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq_disksort.c,v 1.11 2009/01/19 14:54:28 yamt Exp $ */ +/* $NetBSD: bufq_disksort.c,v 1.12 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: subr_disk.c,v 1.61 2004/09/25 03:30:44 thorpej Exp */ /*- @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bufq_disksort.c,v 1.11 2009/01/19 14:54:28 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bufq_disksort.c,v 1.12 2016/11/16 00:46:46 pgoyette Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: bufq_disksor #include <sys/bufq.h> #include <sys/bufq_impl.h> #include <sys/kmem.h> +#include <sys/module.h> /* * Seek sort for disks. @@ -227,3 +228,19 @@ bufq_disksort_init(struct bufq_state *bu bufq->bq_fini = bufq_disksort_fini; TAILQ_INIT(&disksort->bq_head); } + +MODULE(MODULE_CLASS_MISC, bufq_disksort, NULL); + +static int +bufq_disksort_modcmd(modcmd_t cmd, void *opaque) +{ + + switch (cmd) { + case MODULE_CMD_INIT: + return bufq_register(&bufq_strat_disksort); + case MODULE_CMD_FINI: + return bufq_unregister(&bufq_strat_disksort); + default: + return ENOTTY; + } +} Index: src/sys/kern/bufq_fcfs.c diff -u src/sys/kern/bufq_fcfs.c:1.10 src/sys/kern/bufq_fcfs.c:1.11 --- src/sys/kern/bufq_fcfs.c:1.10 Mon Jan 19 14:54:28 2009 +++ src/sys/kern/bufq_fcfs.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq_fcfs.c,v 1.10 2009/01/19 14:54:28 yamt Exp $ */ +/* $NetBSD: bufq_fcfs.c,v 1.11 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: subr_disk.c,v 1.61 2004/09/25 03:30:44 thorpej Exp */ /*- @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bufq_fcfs.c,v 1.10 2009/01/19 14:54:28 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bufq_fcfs.c,v 1.11 2016/11/16 00:46:46 pgoyette Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: bufq_fcfs.c, #include <sys/bufq.h> #include <sys/bufq_impl.h> #include <sys/kmem.h> +#include <sys/module.h> /* * First-come first-served sort for disks. @@ -151,3 +152,19 @@ bufq_fcfs_init(struct bufq_state *bufq) fcfs = (struct bufq_fcfs *)bufq->bq_private; TAILQ_INIT(&fcfs->bq_head); } + +MODULE(MODULE_CLASS_MISC, bufq_fcfs, NULL); + +static int +bufq_fcfs_modcmd(modcmd_t cmd, void *opaque) +{ + + switch (cmd) { + case MODULE_CMD_INIT: + return bufq_register(&bufq_strat_fcfs); + case MODULE_CMD_FINI: + return bufq_unregister(&bufq_strat_fcfs); + default: + return ENOTTY; + } +} Index: src/sys/kern/bufq_priocscan.c diff -u src/sys/kern/bufq_priocscan.c:1.18 src/sys/kern/bufq_priocscan.c:1.19 --- src/sys/kern/bufq_priocscan.c:1.18 Tue Jan 28 12:50:54 2014 +++ src/sys/kern/bufq_priocscan.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq_priocscan.c,v 1.18 2014/01/28 12:50:54 martin Exp $ */ +/* $NetBSD: bufq_priocscan.c,v 1.19 2016/11/16 00:46:46 pgoyette Exp $ */ /*- * Copyright (c)2004,2005,2006,2008,2009,2011,2012 YAMAMOTO Takashi, @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bufq_priocscan.c,v 1.18 2014/01/28 12:50:54 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bufq_priocscan.c,v 1.19 2016/11/16 00:46:46 pgoyette Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: bufq_priocsc #include <sys/bufq_impl.h> #include <sys/kmem.h> #include <sys/rbtree.h> +#include <sys/module.h> #undef PRIOCSCAN_USE_GLOBAL_POSITION @@ -442,3 +443,19 @@ bufq_priocscan_init(struct bufq_state *b cscan_init(cq, sortby); } } + +MODULE(MODULE_CLASS_MISC, bufq_priocscan, NULL); + +static int +bufq_priocscan_modcmd(modcmd_t cmd, void *opaque) +{ + + switch (cmd) { + case MODULE_CMD_INIT: + return bufq_register(&bufq_strat_priocscan); + case MODULE_CMD_FINI: + return bufq_unregister(&bufq_strat_priocscan); + default: + return ENOTTY; + } +} Index: src/sys/kern/bufq_readprio.c diff -u src/sys/kern/bufq_readprio.c:1.13 src/sys/kern/bufq_readprio.c:1.14 --- src/sys/kern/bufq_readprio.c:1.13 Mon Jan 19 14:54:28 2009 +++ src/sys/kern/bufq_readprio.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq_readprio.c,v 1.13 2009/01/19 14:54:28 yamt Exp $ */ +/* $NetBSD: bufq_readprio.c,v 1.14 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: subr_disk.c,v 1.61 2004/09/25 03:30:44 thorpej Exp */ /*- @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bufq_readprio.c,v 1.13 2009/01/19 14:54:28 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bufq_readprio.c,v 1.14 2016/11/16 00:46:46 pgoyette Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: bufq_readpri #include <sys/bufq.h> #include <sys/bufq_impl.h> #include <sys/kmem.h> +#include <sys/module.h> /* * Seek sort for disks. @@ -280,3 +281,18 @@ bufq_readprio_init(struct bufq_state *bu TAILQ_INIT(&prio->bq_write); } +MODULE(MODULE_CLASS_MISC, bufq_readprio, NULL); + +static int +bufq_readprio_modcmd(modcmd_t cmd, void *opaque) +{ + + switch (cmd) { + case MODULE_CMD_INIT: + return bufq_register(&bufq_strat_readprio); + case MODULE_CMD_FINI: + return bufq_unregister(&bufq_strat_readprio); + default: + return ENOTTY; + } +} Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.484 src/sys/kern/init_main.c:1.485 --- src/sys/kern/init_main.c:1.484 Wed Nov 2 00:11:59 2016 +++ src/sys/kern/init_main.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.484 2016/11/02 00:11:59 pgoyette Exp $ */ +/* $NetBSD: init_main.c,v 1.485 2016/11/16 00:46:46 pgoyette Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.484 2016/11/02 00:11:59 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.485 2016/11/16 00:46:46 pgoyette Exp $"); #include "opt_ddb.h" #include "opt_inet.h" @@ -175,6 +175,7 @@ extern void *_binary_splash_image_end; #include <sys/ksyms.h> #include <sys/uidinfo.h> #include <sys/kprintf.h> +#include <sys/bufq.h> #ifdef IPSEC #include <netipsec/ipsec.h> #endif @@ -427,6 +428,9 @@ main(void) /* Second part of module system initialization. */ module_start_unload_thread(); + /* Initialize the bufq strategy sub-system */ + bufq_init(); + /* Initialize the file systems. */ #ifdef NVNODE_IMPLICIT /* Index: src/sys/kern/subr_bufq.c diff -u src/sys/kern/subr_bufq.c:1.21 src/sys/kern/subr_bufq.c:1.22 --- src/sys/kern/subr_bufq.c:1.21 Tue Feb 25 18:30:11 2014 +++ src/sys/kern/subr_bufq.c Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_bufq.c,v 1.21 2014/02/25 18:30:11 pooka Exp $ */ +/* $NetBSD: subr_bufq.c,v 1.22 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: subr_disk.c,v 1.70 2005/08/20 12:00:01 yamt Exp $ */ /*- @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_bufq.c,v 1.21 2014/02/25 18:30:11 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_bufq.c,v 1.22 2016/11/16 00:46:46 pgoyette Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,22 +76,51 @@ __KERNEL_RCSID(0, "$NetBSD: subr_bufq.c, #include <sys/bufq.h> #include <sys/bufq_impl.h> #include <sys/kmem.h> -#include <sys/once.h> #include <sys/sysctl.h> - -BUFQ_DEFINE(dummy, 0, NULL); /* so that bufq_strats won't be empty */ +#include <sys/module.h> #define STRAT_MATCH(id, bs) (strcmp((id), (bs)->bs_name) == 0) -static int bufq_init(void); static void sysctl_kern_bufq_strategies_setup(struct sysctllog **); +static SLIST_HEAD(, bufq_strat) bufq_strat_list; + +static kmutex_t bufq_mutex; static struct sysctllog *sysctllog; -static int + +void bufq_init(void) { + mutex_init(&bufq_mutex, MUTEX_DEFAULT, IPL_NONE); + SLIST_INIT(&bufq_strat_list); sysctl_kern_bufq_strategies_setup(&sysctllog); +} + +int +bufq_register(struct bufq_strat *bs) +{ + + mutex_enter(&bufq_mutex); + SLIST_INSERT_HEAD(&bufq_strat_list, bs, bs_next); + bs->bs_refcnt = 0; + mutex_exit(&bufq_mutex); + + return 0; +} + +int +bufq_unregister(struct bufq_strat *bs) +{ + + mutex_enter(&bufq_mutex); + if (bs->bs_refcnt != 0) { + mutex_exit(&bufq_mutex); + return EBUSY; + } + SLIST_REMOVE(&bufq_strat_list, bs, bufq_strat, bs_next); + mutex_exit(&bufq_mutex); + return 0; } @@ -101,14 +130,12 @@ bufq_init(void) int bufq_alloc(struct bufq_state **bufqp, const char *strategy, int flags) { - __link_set_decl(bufq_strats, const struct bufq_strat); - const struct bufq_strat *bsp; - const struct bufq_strat * const *it; + struct bufq_strat *bsp, *it; struct bufq_state *bufq; - static ONCE_DECL(bufq_init_ctrl); int error = 0; - - RUN_ONCE(&bufq_init_ctrl, bufq_init); + u_int gen; + bool found_exact; + char module_name[MAXPATHLEN]; KASSERT((flags & BUFQ_EXACT) == 0 || strategy != BUFQ_STRAT_ANY); @@ -132,25 +159,40 @@ bufq_alloc(struct bufq_state **bufqp, co * if a strategy specified by flags is found, use it. * otherwise, select one with the largest bs_prio. */ - bsp = NULL; - __link_set_foreach(it, bufq_strats) { - if ((*it) == &bufq_strat_dummy) - continue; - if (strategy != BUFQ_STRAT_ANY && - STRAT_MATCH(strategy, (*it))) { - bsp = *it; - break; + mutex_enter(&bufq_mutex); + do { + gen = module_gen; + bsp = NULL; + found_exact = false; + + SLIST_FOREACH(it, &bufq_strat_list, bs_next) { + if (strategy != BUFQ_STRAT_ANY && + STRAT_MATCH(strategy, (it))) { + bsp = it; + found_exact = true; + break; + } + if (bsp == NULL || (it)->bs_prio > bsp->bs_prio) + bsp = it; } - if (bsp == NULL || (*it)->bs_prio > bsp->bs_prio) - bsp = *it; - } + if (strategy == BUFQ_STRAT_ANY || found_exact) + break; + + /* Try to autoload device module */ + strlcpy(module_name, "bufq_", sizeof(module_name)); + strlcat(module_name, strategy, sizeof(module_name)); + mutex_exit(&bufq_mutex); + (void) module_autoload(module_name, MODULE_CLASS_MISC); + mutex_enter(&bufq_mutex); + } while (gen != module_gen); if (bsp == NULL) { panic("bufq_alloc: no strategy"); } - if (strategy != BUFQ_STRAT_ANY && !STRAT_MATCH(strategy, bsp)) { + if (strategy != BUFQ_STRAT_ANY && !found_exact) { if ((flags & BUFQ_EXACT)) { error = ENOENT; + mutex_exit(&bufq_mutex); goto out; } #if defined(DEBUG) @@ -163,6 +205,8 @@ bufq_alloc(struct bufq_state **bufqp, co printf("bufq_alloc: using '%s'\n", bsp->bs_name); #endif + bsp->bs_refcnt++; + mutex_exit(&bufq_mutex); *bufqp = bufq = kmem_zalloc(sizeof(*bufq), KM_SLEEP); bufq->bq_flags = flags; bufq->bq_strat = bsp; @@ -225,6 +269,11 @@ bufq_free(struct bufq_state *bufq) KASSERT(bufq_peek(bufq) == NULL); bufq->bq_fini(bufq); + + mutex_enter(&bufq_mutex); + bufq->bq_strat->bs_refcnt--; + mutex_exit(&bufq_mutex); + kmem_free(bufq, sizeof(*bufq)); } @@ -291,33 +340,37 @@ docopynul(char *buf, size_t *bufoffp, si /* * sysctl function that will print all bufq strategies - * built in the kernel. + * currently available to the kernel. */ static int sysctl_kern_bufq_strategies(SYSCTLFN_ARGS) { - __link_set_decl(bufq_strats, const struct bufq_strat); - const struct bufq_strat * const *bq_strat; + const struct bufq_strat *bq_strat; const char *delim = ""; size_t off = 0; size_t buflen = *oldlenp; int error; - __link_set_foreach(bq_strat, bufq_strats) { - if ((*bq_strat) == &bufq_strat_dummy) { - continue; - } + SLIST_FOREACH(bq_strat, &bufq_strat_list, bs_next) { error = docopystr(oldp, &off, buflen, delim); if (error) { goto out; } - error = docopystr(oldp, &off, buflen, (*bq_strat)->bs_name); + error = docopystr(oldp, &off, buflen, (bq_strat)->bs_name); if (error) { goto out; } delim = " "; } + /* In case there are no registered strategies ... */ + if (off == 0) { + error = docopystr(oldp, &off, buflen, "NULL"); + if (error) { + goto out; + } + } + /* NUL terminate */ error = docopynul(oldp, &off, buflen); out: Index: src/sys/sys/bufq.h diff -u src/sys/sys/bufq.h:1.10 src/sys/sys/bufq.h:1.11 --- src/sys/sys/bufq.h:1.10 Tue Jan 13 13:35:54 2009 +++ src/sys/sys/bufq.h Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq.h,v 1.10 2009/01/13 13:35:54 yamt Exp $ */ +/* $NetBSD: bufq.h,v 1.11 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: buf.h,v 1.75 2004/09/18 16:40:11 yamt Exp */ /*- @@ -90,6 +90,7 @@ struct bufq_state; #define BUFQ_EXACT 0x0010 /* Don't fall back to other strategy */ +void bufq_init(void); int bufq_alloc(struct bufq_state **, const char *, int); void bufq_drain(struct bufq_state *); void bufq_free(struct bufq_state *); Index: src/sys/sys/bufq_impl.h diff -u src/sys/sys/bufq_impl.h:1.9 src/sys/sys/bufq_impl.h:1.10 --- src/sys/sys/bufq_impl.h:1.9 Wed Nov 2 13:52:34 2011 +++ src/sys/sys/bufq_impl.h Wed Nov 16 00:46:46 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bufq_impl.h,v 1.9 2011/11/02 13:52:34 yamt Exp $ */ +/* $NetBSD: bufq_impl.h,v 1.10 2016/11/16 00:46:46 pgoyette Exp $ */ /* NetBSD: bufq.h,v 1.3 2005/03/31 11:28:53 yamt Exp */ /* NetBSD: buf.h,v 1.75 2004/09/18 16:40:11 yamt Exp */ @@ -84,7 +84,7 @@ struct bufq_state { void (*bq_fini)(struct bufq_state *); void *bq_private; int bq_flags; /* Flags from bufq_alloc() */ - const struct bufq_strat *bq_strat; + struct bufq_strat *bq_strat; }; static __inline void *bufq_private(const struct bufq_state *) __unused; @@ -128,12 +128,17 @@ struct bufq_strat { const char *bs_name; void (*bs_initfn)(struct bufq_state *); int bs_prio; + int bs_refcnt; + SLIST_ENTRY(bufq_strat) bs_next; }; #define BUFQ_DEFINE(name, prio, initfn) \ -static const struct bufq_strat bufq_strat_##name = { \ +static struct bufq_strat bufq_strat_##name = { \ .bs_name = #name, \ - .bs_prio = prio, \ - .bs_initfn = initfn \ -}; \ -__link_set_add_rodata(bufq_strats, bufq_strat_##name) + .bs_prio = prio, \ + .bs_initfn = initfn, \ + .bs_refcnt = 0 \ +}; + +int bufq_register(struct bufq_strat *); +int bufq_unregister(struct bufq_strat *);