geom_kern.c revision 116196
1215976Sjmallett/*- 2215976Sjmallett * Copyright (c) 2002 Poul-Henning Kamp 3215976Sjmallett * Copyright (c) 2002 Networks Associates Technology, Inc. 4215976Sjmallett * All rights reserved. 5215976Sjmallett * 6215976Sjmallett * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7215976Sjmallett * and NAI Labs, the Security Research Division of Network Associates, Inc. 8215976Sjmallett * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 9215976Sjmallett * DARPA CHATS research program. 10215976Sjmallett * 11215976Sjmallett * Redistribution and use in source and binary forms, with or without 12215976Sjmallett * modification, are permitted provided that the following conditions 13215976Sjmallett * are met: 14215976Sjmallett * 1. Redistributions of source code must retain the above copyright 15215976Sjmallett * notice, this list of conditions and the following disclaimer. 16215976Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 17215976Sjmallett * notice, this list of conditions and the following disclaimer in the 18215976Sjmallett * documentation and/or other materials provided with the distribution. 19215976Sjmallett * 3. The names of the authors may not be used to endorse or promote 20215976Sjmallett * products derived from this software without specific prior written 21215976Sjmallett * permission. 22215976Sjmallett * 23215976Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24215976Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25215976Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26215976Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27215976Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28215976Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29215976Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30215976Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31215976Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32215976Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33215976Sjmallett * SUCH DAMAGE. 34215976Sjmallett */ 35215976Sjmallett 36215976Sjmallett#include <sys/cdefs.h> 37215976Sjmallett__FBSDID("$FreeBSD: head/sys/geom/geom_kern.c 116196 2003-06-11 06:49:16Z obrien $"); 38215976Sjmallett 39215976Sjmallett#include <sys/param.h> 40215976Sjmallett#include <sys/systm.h> 41215976Sjmallett#include <sys/kernel.h> 42215976Sjmallett#include <sys/eventhandler.h> 43215976Sjmallett#include <sys/malloc.h> 44215976Sjmallett#include <sys/bio.h> 45215976Sjmallett#include <sys/sysctl.h> 46215976Sjmallett#include <sys/proc.h> 47215976Sjmallett#include <sys/kthread.h> 48215976Sjmallett#include <sys/lock.h> 49215976Sjmallett#include <sys/mutex.h> 50215976Sjmallett#include <sys/sx.h> 51215976Sjmallett#include <sys/sbuf.h> 52215976Sjmallett#include <geom/geom.h> 53215976Sjmallett#include <geom/geom_int.h> 54215976Sjmallett 55215976SjmallettMALLOC_DEFINE(M_GEOM, "GEOM", "Geom data structures"); 56215976Sjmallett 57215976Sjmallettstruct sx topology_lock; 58215976Sjmallett 59215976Sjmallettstatic struct proc *g_up_proc; 60215976Sjmallett 61215976Sjmallettint g_debugflags; 62215976Sjmallettint g_collectstats = 1; 63215976Sjmallettint g_shutdown; 64215976Sjmallett 65215976Sjmallett/* 66215976Sjmallett * G_UP and G_DOWN are the two threads which push I/O through the 67215976Sjmallett * stack. 68215976Sjmallett * 69215976Sjmallett * Things are procesed in a FIFO order, but these threads could be 70215976Sjmallett * part of I/O prioritization by deciding which bios/bioqs to service 71215976Sjmallett * in what order. 72215976Sjmallett * 73215976Sjmallett * We have only one thread in each direction, it is belived that until 74215976Sjmallett * a very non-trivial workload in the UP/DOWN path this will be enough, 75215976Sjmallett * but more than one can actually be run without problems. 76215976Sjmallett * 77215976Sjmallett * Holding the "mymutex" is a debugging feature: It prevents people 78215976Sjmallett * from sleeping in the UP/DOWN I/O path by mistake or design (doing 79215976Sjmallett * so almost invariably result in deadlocks since it stalls all I/O 80215976Sjmallett * processing in the given direction. 81215976Sjmallett */ 82215976Sjmallett 83215976Sjmallettstatic void 84215976Sjmallettg_up_procbody(void) 85215976Sjmallett{ 86215976Sjmallett struct proc *p = g_up_proc; 87215976Sjmallett struct thread *tp = FIRST_THREAD_IN_PROC(p); 88215976Sjmallett 89215976Sjmallett mtx_assert(&Giant, MA_NOTOWNED); 90215976Sjmallett tp->td_base_pri = PRIBIO; 91215976Sjmallett for(;;) { 92215976Sjmallett g_io_schedule_up(tp); 93215976Sjmallett } 94215976Sjmallett} 95215976Sjmallett 96215976Sjmallettstruct kproc_desc g_up_kp = { 97215976Sjmallett "g_up", 98215976Sjmallett g_up_procbody, 99215976Sjmallett &g_up_proc, 100215976Sjmallett}; 101215976Sjmallett 102215976Sjmallettstatic struct proc *g_down_proc; 103215976Sjmallett 104215976Sjmallettstatic void 105215976Sjmallettg_down_procbody(void) 106215976Sjmallett{ 107215976Sjmallett struct proc *p = g_down_proc; 108215976Sjmallett struct thread *tp = FIRST_THREAD_IN_PROC(p); 109215976Sjmallett 110215976Sjmallett mtx_assert(&Giant, MA_NOTOWNED); 111215976Sjmallett tp->td_base_pri = PRIBIO; 112215976Sjmallett for(;;) { 113215976Sjmallett g_io_schedule_down(tp); 114215976Sjmallett } 115215976Sjmallett} 116215976Sjmallett 117215976Sjmallettstruct kproc_desc g_down_kp = { 118215976Sjmallett "g_down", 119215976Sjmallett g_down_procbody, 120215976Sjmallett &g_down_proc, 121215976Sjmallett}; 122215976Sjmallett 123215976Sjmallettstatic struct proc *g_event_proc; 124215976Sjmallett 125215976Sjmallettstatic void 126215976Sjmallettg_event_procbody(void) 127215976Sjmallett{ 128215976Sjmallett struct proc *p = g_event_proc; 129215976Sjmallett struct thread *tp = FIRST_THREAD_IN_PROC(p); 130215976Sjmallett 131215976Sjmallett mtx_assert(&Giant, MA_NOTOWNED); 132215976Sjmallett tp->td_base_pri = PRIBIO; 133215976Sjmallett for(;;) { 134215976Sjmallett g_run_events(); 135215976Sjmallett tsleep(&g_wait_event, PRIBIO, "g_events", hz/10); 136215976Sjmallett } 137215976Sjmallett} 138215976Sjmallett 139215976Sjmallettstatic struct kproc_desc g_event_kp = { 140215976Sjmallett "g_event", 141215976Sjmallett g_event_procbody, 142215976Sjmallett &g_event_proc, 143215976Sjmallett}; 144215976Sjmallett 145215976Sjmallettstatic void 146215976Sjmallettgeom_shutdown(void *foo __unused) 147215976Sjmallett{ 148215976Sjmallett 149215976Sjmallett g_shutdown = 1; 150215976Sjmallett} 151215976Sjmallett 152215976Sjmallettvoid 153215976Sjmallettg_init(void) 154215976Sjmallett{ 155215976Sjmallett sx_init(&topology_lock, "GEOM topology"); 156215976Sjmallett g_io_init(); 157215976Sjmallett g_event_init(); 158215976Sjmallett g_ctl_init(); 159215976Sjmallett mtx_lock(&Giant); 160215976Sjmallett kproc_start(&g_event_kp); 161215976Sjmallett kproc_start(&g_up_kp); 162215976Sjmallett kproc_start(&g_down_kp); 163215976Sjmallett mtx_unlock(&Giant); 164215976Sjmallett EVENTHANDLER_REGISTER(shutdown_pre_sync, geom_shutdown, NULL, 165215976Sjmallett SHUTDOWN_PRI_FIRST); 166215976Sjmallett} 167215976Sjmallett 168215976Sjmallettstatic int 169215976Sjmallettsysctl_kern_geom_conftxt(SYSCTL_HANDLER_ARGS) 170215976Sjmallett{ 171215976Sjmallett int error; 172215976Sjmallett struct sbuf *sb; 173215976Sjmallett 174215976Sjmallett sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 175215976Sjmallett sbuf_clear(sb); 176215976Sjmallett g_waitfor_event(g_conftxt, sb, M_WAITOK, NULL); 177215976Sjmallett error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 178215976Sjmallett sbuf_delete(sb); 179215976Sjmallett return error; 180215976Sjmallett} 181215976Sjmallett 182215976Sjmallettstatic int 183215976Sjmallettsysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS) 184215976Sjmallett{ 185215976Sjmallett int error; 186215976Sjmallett struct sbuf *sb; 187215976Sjmallett 188215976Sjmallett sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 189215976Sjmallett sbuf_clear(sb); 190215976Sjmallett g_waitfor_event(g_confdot, sb, M_WAITOK, NULL); 191215976Sjmallett error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 192215976Sjmallett sbuf_delete(sb); 193215976Sjmallett return error; 194215976Sjmallett} 195215976Sjmallett 196215976Sjmallettstatic int 197215976Sjmallettsysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS) 198215976Sjmallett{ 199215976Sjmallett int error; 200215976Sjmallett struct sbuf *sb; 201215976Sjmallett 202215976Sjmallett sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 203215976Sjmallett sbuf_clear(sb); 204215976Sjmallett g_waitfor_event(g_confxml, sb, M_WAITOK, NULL); 205215976Sjmallett error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 206215976Sjmallett sbuf_delete(sb); 207215976Sjmallett return error; 208215976Sjmallett} 209215976Sjmallett 210215976SjmallettSYSCTL_NODE(_kern, OID_AUTO, geom, CTLFLAG_RW, 0, "GEOMetry management"); 211215976Sjmallett 212215976SjmallettSYSCTL_PROC(_kern_geom, OID_AUTO, confxml, CTLTYPE_STRING|CTLFLAG_RD, 213215976Sjmallett 0, 0, sysctl_kern_geom_confxml, "", 214215976Sjmallett "Dump the GEOM config in XML"); 215215976Sjmallett 216215976SjmallettSYSCTL_PROC(_kern_geom, OID_AUTO, confdot, CTLTYPE_STRING|CTLFLAG_RD, 217215976Sjmallett 0, 0, sysctl_kern_geom_confdot, "", 218215976Sjmallett "Dump the GEOM config in dot"); 219215976Sjmallett 220215976SjmallettSYSCTL_PROC(_kern_geom, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RD, 221215976Sjmallett 0, 0, sysctl_kern_geom_conftxt, "", 222215976Sjmallett "Dump the GEOM config in txt"); 223215976Sjmallett 224215976SjmallettSYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLFLAG_RW, 225215976Sjmallett &g_debugflags, 0, ""); 226215976Sjmallett 227215976SjmallettSYSCTL_INT(_kern_geom, OID_AUTO, collectstats, CTLFLAG_RW, 228215976Sjmallett &g_collectstats, 0, ""); 229215976Sjmallett 230215976SjmallettSYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD, 231215976Sjmallett 0, sizeof(struct g_class), ""); 232215976SjmallettSYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD, 233215976Sjmallett 0, sizeof(struct g_geom), ""); 234215976SjmallettSYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD, 235215976Sjmallett 0, sizeof(struct g_provider), ""); 236215976SjmallettSYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD, 237215976Sjmallett 0, sizeof(struct g_consumer), ""); 238215976SjmallettSYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD, 239215976Sjmallett 0, sizeof(struct g_bioq), ""); 240215976Sjmallett