geom_kern.c revision 181463
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 36116196Sobrien#include <sys/cdefs.h> 37116196Sobrien__FBSDID("$FreeBSD: head/sys/geom/geom_kern.c 181463 2008-08-09 11:14:05Z des $"); 38116196Sobrien 3992108Sphk#include <sys/param.h> 4092108Sphk#include <sys/systm.h> 4192108Sphk#include <sys/kernel.h> 42113926Sphk#include <sys/eventhandler.h> 4392108Sphk#include <sys/malloc.h> 4492108Sphk#include <sys/bio.h> 4592108Sphk#include <sys/sysctl.h> 4692108Sphk#include <sys/proc.h> 4792108Sphk#include <sys/kthread.h> 4892108Sphk#include <sys/lock.h> 4992108Sphk#include <sys/mutex.h> 50139451Sjhb#include <sys/sbuf.h> 51139451Sjhb#include <sys/sched.h> 5292108Sphk#include <sys/sx.h> 5392108Sphk#include <geom/geom.h> 5493250Sphk#include <geom/geom_int.h> 5592108Sphk 5692108SphkMALLOC_DEFINE(M_GEOM, "GEOM", "Geom data structures"); 5792108Sphk 5892108Sphkstruct sx topology_lock; 5992108Sphk 6092108Sphkstatic struct proc *g_up_proc; 6192108Sphk 6292108Sphkint g_debugflags; 63110592Sphkint g_collectstats = 1; 64113926Sphkint g_shutdown; 6592108Sphk 66104063Sphk/* 67104063Sphk * G_UP and G_DOWN are the two threads which push I/O through the 68104063Sphk * stack. 69104063Sphk * 70104063Sphk * Things are procesed in a FIFO order, but these threads could be 71104063Sphk * part of I/O prioritization by deciding which bios/bioqs to service 72104063Sphk * in what order. 73104063Sphk * 74104063Sphk * We have only one thread in each direction, it is belived that until 75104063Sphk * a very non-trivial workload in the UP/DOWN path this will be enough, 76104063Sphk * but more than one can actually be run without problems. 77104063Sphk * 78104063Sphk * Holding the "mymutex" is a debugging feature: It prevents people 79104063Sphk * from sleeping in the UP/DOWN I/O path by mistake or design (doing 80104063Sphk * so almost invariably result in deadlocks since it stalls all I/O 81104063Sphk * processing in the given direction. 82104063Sphk */ 83104063Sphk 8492108Sphkstatic void 8592108Sphkg_up_procbody(void) 8692108Sphk{ 8792108Sphk struct proc *p = g_up_proc; 8899028Sjulian struct thread *tp = FIRST_THREAD_IN_PROC(p); 8992108Sphk 90108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 91170307Sjeff thread_lock(tp); 92139451Sjhb sched_prio(tp, PRIBIO); 93170307Sjeff thread_unlock(tp); 9492108Sphk for(;;) { 9592108Sphk g_io_schedule_up(tp); 9692108Sphk } 9792108Sphk} 9892108Sphk 99141624Sphkstatic struct kproc_desc g_up_kp = { 10092108Sphk "g_up", 10192108Sphk g_up_procbody, 10292108Sphk &g_up_proc, 10392108Sphk}; 10492108Sphk 10592108Sphkstatic struct proc *g_down_proc; 10692108Sphk 10792108Sphkstatic void 10892108Sphkg_down_procbody(void) 10992108Sphk{ 11092108Sphk struct proc *p = g_down_proc; 11199028Sjulian struct thread *tp = FIRST_THREAD_IN_PROC(p); 11292108Sphk 113108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 114170307Sjeff thread_lock(tp); 115139451Sjhb sched_prio(tp, PRIBIO); 116170307Sjeff thread_unlock(tp); 11792108Sphk for(;;) { 11892108Sphk g_io_schedule_down(tp); 11992108Sphk } 12092108Sphk} 12192108Sphk 122141624Sphkstatic struct kproc_desc g_down_kp = { 12392108Sphk "g_down", 12492108Sphk g_down_procbody, 12592108Sphk &g_down_proc, 12692108Sphk}; 12792108Sphk 12892108Sphkstatic struct proc *g_event_proc; 12992108Sphk 13092108Sphkstatic void 13192108Sphkg_event_procbody(void) 13292108Sphk{ 133107452Sphk struct proc *p = g_event_proc; 134104087Sphk struct thread *tp = FIRST_THREAD_IN_PROC(p); 13592108Sphk 136108296Sphk mtx_assert(&Giant, MA_NOTOWNED); 137170307Sjeff thread_lock(tp); 138139451Sjhb sched_prio(tp, PRIBIO); 139170307Sjeff thread_unlock(tp); 14092108Sphk for(;;) { 14193250Sphk g_run_events(); 142116522Sphk tsleep(&g_wait_event, PRIBIO, "-", hz/10); 14392108Sphk } 14492108Sphk} 14592108Sphk 146114293Smarkmstatic struct kproc_desc g_event_kp = { 14792108Sphk "g_event", 14892108Sphk g_event_procbody, 14992108Sphk &g_event_proc, 15092108Sphk}; 15192108Sphk 152113926Sphkstatic void 153113926Sphkgeom_shutdown(void *foo __unused) 154113926Sphk{ 155113926Sphk 156113926Sphk g_shutdown = 1; 157113926Sphk} 158113926Sphk 15992108Sphkvoid 16092108Sphkg_init(void) 16192108Sphk{ 162116522Sphk 163116522Sphk g_trace(G_T_TOPOLOGY, "g_ignition"); 16492108Sphk sx_init(&topology_lock, "GEOM topology"); 16592108Sphk g_io_init(); 16692108Sphk g_event_init(); 167112534Sphk g_ctl_init(); 16892108Sphk mtx_lock(&Giant); 16992108Sphk kproc_start(&g_event_kp); 17092108Sphk kproc_start(&g_up_kp); 17192108Sphk kproc_start(&g_down_kp); 17292108Sphk mtx_unlock(&Giant); 173113926Sphk EVENTHANDLER_REGISTER(shutdown_pre_sync, geom_shutdown, NULL, 174113926Sphk SHUTDOWN_PRI_FIRST); 17592108Sphk} 17692108Sphk 17792108Sphkstatic int 178106101Sphksysctl_kern_geom_conftxt(SYSCTL_HANDLER_ARGS) 179106101Sphk{ 180106101Sphk int error; 181106101Sphk struct sbuf *sb; 182106101Sphk 183181463Sdes sb = sbuf_new_auto(); 184113940Sphk g_waitfor_event(g_conftxt, sb, M_WAITOK, NULL); 185106101Sphk error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 186106101Sphk sbuf_delete(sb); 187106101Sphk return error; 188106101Sphk} 189106101Sphk 190106101Sphkstatic int 191104452Sphksysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS) 19292108Sphk{ 193104452Sphk int error; 19492108Sphk struct sbuf *sb; 19592108Sphk 196181463Sdes sb = sbuf_new_auto(); 197113940Sphk g_waitfor_event(g_confdot, sb, M_WAITOK, NULL); 198105358Sphk error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); 19992108Sphk sbuf_delete(sb); 200104452Sphk return error; 20192108Sphk} 202104452Sphk 20392108Sphkstatic int 204104452Sphksysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS) 20592108Sphk{ 206104452Sphk int error; 20792108Sphk struct sbuf *sb; 20892108Sphk 209181463Sdes sb = sbuf_new_auto(); 210113940Sphk g_waitfor_event(g_confxml, sb, M_WAITOK, NULL); 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 230135151SpjdTUNABLE_INT("kern.geom.debugflags", &g_debugflags); 231105581SphkSYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLFLAG_RW, 232152784Sle &g_debugflags, 0, "Set various trace levels for GEOM debugging"); 23392108Sphk 234110523SphkSYSCTL_INT(_kern_geom, OID_AUTO, collectstats, CTLFLAG_RW, 235152784Sle &g_collectstats, 0, 236152784Sle "Control statistics collection on GEOM providers and consumers"); 237110523Sphk 238105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD, 239152784Sle 0, sizeof(struct g_class), "sizeof(struct g_class)"); 240105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD, 241152784Sle 0, sizeof(struct g_geom), "sizeof(struct g_geom)"); 242105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD, 243152784Sle 0, sizeof(struct g_provider), "sizeof(struct g_provider)"); 244105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD, 245152784Sle 0, sizeof(struct g_consumer), "sizeof(struct g_consumer)"); 246105581SphkSYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD, 247152784Sle 0, sizeof(struct g_bioq), "sizeof(struct g_bioq)"); 248