geom_kern.c revision 105581
175584Sru/*- 275584Sru * Copyright (c) 2002 Poul-Henning Kamp 375584Sru * Copyright (c) 2002 Networks Associates Technology, Inc. 475584Sru * All rights reserved. 575584Sru * 675584Sru * This software was developed for the FreeBSD Project by Poul-Henning Kamp 775584Sru * and NAI Labs, the Security Research Division of Network Associates, Inc. 875584Sru * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 975584Sru * DARPA CHATS research program. 1075584Sru * 1175584Sru * Redistribution and use in source and binary forms, with or without 1275584Sru * modification, are permitted provided that the following conditions 1375584Sru * are met: 1475584Sru * 1. Redistributions of source code must retain the above copyright 1575584Sru * notice, this list of conditions and the following disclaimer. 1675584Sru * 2. Redistributions in binary form must reproduce the above copyright 1775584Sru * notice, this list of conditions and the following disclaimer in the 1875584Sru * documentation and/or other materials provided with the distribution. 1975584Sru * 3. The names of the authors may not be used to endorse or promote 2075584Sru * products derived from this software without specific prior written 2175584Sru * permission. 2275584Sru * 2375584Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2475584Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2575584Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2675584Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2775584Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2875584Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2975584Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3075584Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3175584Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3275584Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3375584Sru * SUCH DAMAGE. 3475584Sru * 3575584Sru * $FreeBSD: head/sys/geom/geom_kern.c 105581 2002-10-20 22:46:50Z phk $ 3675584Sru */ 3775584Sru 3875584Sru#include <sys/param.h> 3975584Sru#include <sys/systm.h> 4075584Sru#include <sys/kernel.h> 4175584Sru#include <sys/malloc.h> 4275584Sru#include <sys/bio.h> 4375584Sru#include <sys/sysctl.h> 4475584Sru#include <sys/proc.h> 4575584Sru#include <sys/kthread.h> 4675584Sru#include <sys/lock.h> 4775584Sru#include <sys/mutex.h> 4875584Sru#include <sys/sx.h> 4975584Sru#include <sys/sbuf.h> 5075584Sru#include <geom/geom.h> 5175584Sru#include <geom/geom_int.h> 5275584Sru 5375584SruMALLOC_DEFINE(M_GEOM, "GEOM", "Geom data structures"); 5475584Sru 5575584Srustruct sx topology_lock; 5675584Sru 5775584Srustatic struct proc *g_up_proc; 5875584Sru 5975584Sruint g_debugflags; 6075584Sru 6175584Sru/* 6275584Sru * G_UP and G_DOWN are the two threads which push I/O through the 6375584Sru * stack. 6475584Sru * 6575584Sru * Things are procesed in a FIFO order, but these threads could be 6675584Sru * part of I/O prioritization by deciding which bios/bioqs to service 6775584Sru * in what order. 6875584Sru * 6975584Sru * We have only one thread in each direction, it is belived that until 7075584Sru * a very non-trivial workload in the UP/DOWN path this will be enough, 7175584Sru * but more than one can actually be run without problems. 7275584Sru * 7375584Sru * Holding the "mymutex" is a debugging feature: It prevents people 7475584Sru * from sleeping in the UP/DOWN I/O path by mistake or design (doing 7575584Sru * so almost invariably result in deadlocks since it stalls all I/O 7675584Sru * processing in the given direction. 7775584Sru */ 7875584Sru 7975584Srustatic void 8075584Srug_up_procbody(void) 8175584Sru{ 8275584Sru struct proc *p = g_up_proc; 8375584Sru struct thread *tp = FIRST_THREAD_IN_PROC(p); 8475584Sru struct mtx mymutex; 8575584Sru 8675584Sru bzero(&mymutex, sizeof mymutex); 87 mtx_init(&mymutex, "g_up", MTX_DEF, 0); 88 mtx_lock(&mymutex); 89 tp->td_base_pri = PRIBIO; 90 for(;;) { 91 g_io_schedule_up(tp); 92 msleep(&g_wait_up, &mymutex, PRIBIO, "g_up", hz/10); 93 } 94} 95 96struct kproc_desc g_up_kp = { 97 "g_up", 98 g_up_procbody, 99 &g_up_proc, 100}; 101 102static struct proc *g_down_proc; 103 104static void 105g_down_procbody(void) 106{ 107 struct proc *p = g_down_proc; 108 struct thread *tp = FIRST_THREAD_IN_PROC(p); 109 struct mtx mymutex; 110 111 bzero(&mymutex, sizeof mymutex); 112 mtx_init(&mymutex, "g_down", MTX_DEF, 0); 113 mtx_lock(&mymutex); 114 tp->td_base_pri = PRIBIO; 115 for(;;) { 116 g_io_schedule_down(tp); 117 msleep(&g_wait_down, &mymutex, PRIBIO, "g_down", hz/10); 118 } 119} 120 121struct kproc_desc g_down_kp = { 122 "g_down", 123 g_down_procbody, 124 &g_down_proc, 125}; 126 127static struct proc *g_event_proc; 128 129static void 130g_event_procbody(void) 131{ 132 struct proc *p = g_down_proc; 133 struct thread *tp = FIRST_THREAD_IN_PROC(p); 134 135 tp->td_base_pri = PRIBIO; 136 for(;;) { 137 g_run_events(); 138 tsleep(&g_wait_event, PRIBIO, "g_events", hz/10); 139 } 140} 141 142struct kproc_desc g_event_kp = { 143 "g_event", 144 g_event_procbody, 145 &g_event_proc, 146}; 147 148void 149g_init(void) 150{ 151 printf("Initializing GEOMetry subsystem\n"); 152 if (bootverbose) 153 g_debugflags |= G_T_TOPOLOGY; 154 sx_init(&topology_lock, "GEOM topology"); 155 g_io_init(); 156 g_event_init(); 157 mtx_lock(&Giant); 158 kproc_start(&g_event_kp); 159 kproc_start(&g_up_kp); 160 kproc_start(&g_down_kp); 161 mtx_unlock(&Giant); 162} 163 164static int 165sysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS) 166{ 167 int error; 168 struct sbuf *sb; 169 170 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 171 sbuf_clear(sb); 172 g_call_me(g_confdot, sb); 173 do { 174 tsleep(sb, PZERO, "g_dot", hz); 175 } while(!sbuf_done(sb)); 176 error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 177 sbuf_delete(sb); 178 return error; 179} 180 181static int 182sysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS) 183{ 184 int error; 185 struct sbuf *sb; 186 187 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 188 sbuf_clear(sb); 189 g_call_me(g_confxml, sb); 190 do { 191 tsleep(sb, PZERO, "g_xml", hz); 192 } while(!sbuf_done(sb)); 193 error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 194 sbuf_delete(sb); 195 return error; 196} 197 198SYSCTL_NODE(_kern, OID_AUTO, geom, CTLFLAG_RW, 0, "GEOMetry management"); 199 200SYSCTL_PROC(_kern_geom, OID_AUTO, confxml, CTLTYPE_STRING|CTLFLAG_RD, 201 0, 0, sysctl_kern_geom_confxml, "A", 202 "Dump the GEOM config"); 203 204SYSCTL_PROC(_kern_geom, OID_AUTO, confdot, CTLTYPE_STRING|CTLFLAG_RD, 205 0, 0, sysctl_kern_geom_confdot, "A", 206 "Dump the GEOM config"); 207 208SYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLFLAG_RW, 209 &g_debugflags, 0, ""); 210 211SYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD, 212 0, sizeof(struct g_class), ""); 213SYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD, 214 0, sizeof(struct g_geom), ""); 215SYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD, 216 0, sizeof(struct g_provider), ""); 217SYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD, 218 0, sizeof(struct g_consumer), ""); 219SYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD, 220 0, sizeof(struct g_bioq), ""); 221SYSCTL_INT(_debug_sizeof, OID_AUTO, g_event, CTLFLAG_RD, 222 0, sizeof(struct g_event), ""); 223