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 *);