geom_kern.c revision 108308
192108Sphk/*- 292108Sphk * Copyright (c) 2002 Poul-Henning Kamp 392108Sphk * Copyright (c) 2002 Networks Associates Technology, Inc. 492108Sphk * All rights reserved. 592108Sphk * 692108Sphk * This software was developed for the FreeBSD Project by Poul-Henning Kamp 792108Sphk * and NAI Labs, the Security Research Division of Network Associates, Inc. 892108Sphk * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 992108Sphk * DARPA CHATS research program. 1092108Sphk * 1192108Sphk * Redistribution and use in source and binary forms, with or without 1292108Sphk * modification, are permitted provided that the following conditions 1392108Sphk * are met: 1492108Sphk * 1. Redistributions of source code must retain the above copyright 1592108Sphk * notice, this list of conditions and the following disclaimer. 1692108Sphk * 2. Redistributions in binary form must reproduce the above copyright 1792108Sphk * notice, this list of conditions and the following disclaimer in the 1892108Sphk * documentation and/or other materials provided with the distribution. 1992108Sphk * 3. The names of the authors may not be used to endorse or promote 2092108Sphk * products derived from this software without specific prior written 2192108Sphk * permission. 2292108Sphk * 2392108Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2492108Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2592108Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2692108Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2792108Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2892108Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2992108Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3092108Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3192108Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3292108Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3392108Sphk * SUCH DAMAGE. 3492108Sphk * 3592108Sphk * $FreeBSD: head/sys/geom/geom_kern.c 108308 2002-12-27 07:58:59Z phk $ 3692108Sphk */ 3792108Sphk 3892108Sphk#include <sys/param.h> 3992108Sphk#include <sys/systm.h> 4092108Sphk#include <sys/kernel.h> 4192108Sphk#include <sys/malloc.h> 4292108Sphk#include <sys/bio.h> 4392108Sphk#include <sys/sysctl.h> 4492108Sphk#include <sys/proc.h> 4592108Sphk#include <sys/kthread.h> 4692108Sphk#include <sys/lock.h> 4792108Sphk#include <sys/mutex.h> 4892108Sphk#include <sys/sx.h> 4992108Sphk#include <sys/sbuf.h> 5092108Sphk#include <geom/geom.h> 5193250Sphk#include <geom/geom_int.h> 5292108Sphk 5392108SphkMALLOC_DEFINE(M_GEOM, "GEOM", "Geom data structures"); 5492108Sphk 5592108Sphkstruct sx topology_lock; 5692108Sphk 5792108Sphkstatic struct proc *g_up_proc; 5892108Sphk 5992108Sphkint g_debugflags; 6092108Sphk 61104063Sphk/* 62104063Sphk * G_UP and G_DOWN are the two threads which push I/O through the 63104063Sphk * stack. 64104063Sphk * 65104063Sphk * Things are procesed in a FIFO order, but these threads could be 66104063Sphk * part of I/O prioritization by deciding which bios/bioqs to service 67104063Sphk * in what order. 68104063Sphk * 69104063Sphk * We have only one thread in each direction, it is belived that until 70104063Sphk * a very non-trivial workload in the UP/DOWN path this will be enough, 71104063Sphk * but more than one can actually be run without problems. 72104063Sphk * 73104063Sphk * Holding the "mymutex" is a debugging feature: It prevents people 74104063Sphk * from sleeping in the UP/DOWN I/O path by mistake or design (doing 75104063Sphk * so almost invariably result in deadlocks since it stalls all I/O 76104063Sphk * processing in the given direction. 77104063Sphk */ 78104063Sphk 7992108Sphkstatic void 8092108Sphkg_up_procbody(void) 8192108Sphk{ 8292108Sphk struct proc *p = g_up_proc; 8399028Sjulian struct thread *tp = FIRST_THREAD_IN_PROC(p); 84104063Sphk struct mtx mymutex; 8592108Sphk 86108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 87104107Sphk bzero(&mymutex, sizeof mymutex); 88104063Sphk mtx_init(&mymutex, "g_up", MTX_DEF, 0); 89104063Sphk mtx_lock(&mymutex); 90104087Sphk tp->td_base_pri = PRIBIO; 9192108Sphk for(;;) { 9292108Sphk g_io_schedule_up(tp); 93104063Sphk msleep(&g_wait_up, &mymutex, PRIBIO, "g_up", hz/10); 9492108Sphk } 9592108Sphk} 9692108Sphk 9792108Sphkstruct kproc_desc g_up_kp = { 9892108Sphk "g_up", 9992108Sphk g_up_procbody, 10092108Sphk &g_up_proc, 10192108Sphk}; 10292108Sphk 10392108Sphkstatic struct proc *g_down_proc; 10492108Sphk 10592108Sphkstatic void 10692108Sphkg_down_procbody(void) 10792108Sphk{ 10892108Sphk struct proc *p = g_down_proc; 10999028Sjulian struct thread *tp = FIRST_THREAD_IN_PROC(p); 110104063Sphk struct mtx mymutex; 11192108Sphk 112108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 113104107Sphk bzero(&mymutex, sizeof mymutex); 114104063Sphk mtx_init(&mymutex, "g_down", MTX_DEF, 0); 115104063Sphk mtx_lock(&mymutex); 116104087Sphk tp->td_base_pri = PRIBIO; 11792108Sphk for(;;) { 11892108Sphk g_io_schedule_down(tp); 119104063Sphk msleep(&g_wait_down, &mymutex, PRIBIO, "g_down", hz/10); 12092108Sphk } 12192108Sphk} 12292108Sphk 12392108Sphkstruct kproc_desc g_down_kp = { 12492108Sphk "g_down", 12592108Sphk g_down_procbody, 12692108Sphk &g_down_proc, 12792108Sphk}; 12892108Sphk 12992108Sphkstatic struct proc *g_event_proc; 13092108Sphk 13192108Sphkstatic void 13292108Sphkg_event_procbody(void) 13392108Sphk{ 134107452Sphk struct proc *p = g_event_proc; 135104087Sphk struct thread *tp = FIRST_THREAD_IN_PROC(p); 13692108Sphk 137108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 138104087Sphk tp->td_base_pri = PRIBIO; 13992108Sphk for(;;) { 14093250Sphk g_run_events(); 14192108Sphk tsleep(&g_wait_event, PRIBIO, "g_events", hz/10); 14292108Sphk } 14392108Sphk} 14492108Sphk 14592108Sphkstruct kproc_desc g_event_kp = { 14692108Sphk "g_event", 14792108Sphk g_event_procbody, 14892108Sphk &g_event_proc, 14992108Sphk}; 15092108Sphk 15192108Sphkvoid 15292108Sphkg_init(void) 15392108Sphk{ 15492108Sphk printf("Initializing GEOMetry subsystem\n"); 15592108Sphk sx_init(&topology_lock, "GEOM topology"); 15692108Sphk g_io_init(); 15792108Sphk g_event_init(); 15892108Sphk mtx_lock(&Giant); 15992108Sphk kproc_start(&g_event_kp); 16092108Sphk kproc_start(&g_up_kp); 16192108Sphk kproc_start(&g_down_kp); 16292108Sphk mtx_unlock(&Giant); 16392108Sphk} 16492108Sphk 16592108Sphkstatic int 166106101Sphksysctl_kern_geom_conftxt(SYSCTL_HANDLER_ARGS) 167106101Sphk{ 168106101Sphk int error; 169106101Sphk struct sbuf *sb; 170106101Sphk 171106101Sphk sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 172106101Sphk sbuf_clear(sb); 173106101Sphk g_call_me(g_conftxt, sb); 174106101Sphk do { 175106101Sphk tsleep(sb, PZERO, "g_dot", hz); 176106101Sphk } while(!sbuf_done(sb)); 177106101Sphk error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 178106101Sphk sbuf_delete(sb); 179106101Sphk return error; 180106101Sphk} 181106101Sphk 182106101Sphkstatic int 183104452Sphksysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS) 18492108Sphk{ 185104452Sphk int error; 18692108Sphk struct sbuf *sb; 18792108Sphk 188104452Sphk sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 189104452Sphk sbuf_clear(sb); 190104452Sphk g_call_me(g_confdot, sb); 191104452Sphk do { 192104452Sphk tsleep(sb, PZERO, "g_dot", hz); 193104452Sphk } while(!sbuf_done(sb)); 194105358Sphk error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 19592108Sphk sbuf_delete(sb); 196104452Sphk return error; 19792108Sphk} 198104452Sphk 19992108Sphkstatic int 200104452Sphksysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS) 20192108Sphk{ 202104452Sphk int error; 20392108Sphk struct sbuf *sb; 20492108Sphk 205104452Sphk sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 206104452Sphk sbuf_clear(sb); 207104452Sphk g_call_me(g_confxml, sb); 208104452Sphk do { 209104452Sphk tsleep(sb, PZERO, "g_xml", hz); 210104452Sphk } while(!sbuf_done(sb)); 211105358Sphk error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 21292108Sphk sbuf_delete(sb); 213104452Sphk return error; 21492108Sphk} 21592108Sphk 216104359SphkSYSCTL_NODE(_kern, OID_AUTO, geom, CTLFLAG_RW, 0, "GEOMetry management"); 217104359Sphk 218104452SphkSYSCTL_PROC(_kern_geom, OID_AUTO, confxml, CTLTYPE_STRING|CTLFLAG_RD, 219108308Sphk 0, 0, sysctl_kern_geom_confxml, "", 220106101Sphk "Dump the GEOM config in XML"); 22192108Sphk 222104452SphkSYSCTL_PROC(_kern_geom, OID_AUTO, confdot, CTLTYPE_STRING|CTLFLAG_RD, 223108308Sphk 0, 0, sysctl_kern_geom_confdot, "", 224106101Sphk "Dump the GEOM config in dot"); 225104359Sphk 226106101SphkSYSCTL_PROC(_kern_geom, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RD, 227108308Sphk 0, 0, sysctl_kern_geom_conftxt, "", 228106101Sphk "Dump the GEOM config in txt"); 229106101Sphk 230105581SphkSYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLFLAG_RW, 23192108Sphk &g_debugflags, 0, ""); 23292108Sphk 233105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD, 23493248Sphk 0, sizeof(struct g_class), ""); 235105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD, 23692108Sphk 0, sizeof(struct g_geom), ""); 237105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD, 23892108Sphk 0, sizeof(struct g_provider), ""); 239105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD, 24092108Sphk 0, sizeof(struct g_consumer), ""); 241105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD, 24292108Sphk 0, sizeof(struct g_bioq), ""); 243105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_event, CTLFLAG_RD, 24492108Sphk 0, sizeof(struct g_event), ""); 245