Module Name: src Committed By: hannken Date: Thu Nov 25 08:53:31 UTC 2010
Modified Files: src/sys/dev: md.c Log Message: - Don't detach configured devices on last close. - No kmem allocation and biodone() under lock (from rm...@netbsd.org). To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/sys/dev/md.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/md.c diff -u src/sys/dev/md.c:1.65 src/sys/dev/md.c:1.66 --- src/sys/dev/md.c:1.65 Tue Nov 23 09:30:43 2010 +++ src/sys/dev/md.c Thu Nov 25 08:53:30 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: md.c,v 1.65 2010/11/23 09:30:43 hannken Exp $ */ +/* $NetBSD: md.c,v 1.66 2010/11/25 08:53:30 hannken Exp $ */ /* * Copyright (c) 1995 Gordon W. Ross, Leo Weppelman. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.65 2010/11/23 09:30:43 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.66 2010/11/25 08:53:30 hannken Exp $"); #ifdef _KERNEL_OPT #include "opt_md.h" @@ -85,7 +85,7 @@ struct disk sc_dkdev; /* hook for generic disk handling */ struct md_conf sc_md; kmutex_t sc_lock; /* Protect self. */ - kcondvar_t sc_cv; /* Signal work. */ + kcondvar_t sc_cv; /* Wait here for work. */ struct bufq_state *sc_buflist; }; /* shorthand for fields in sc_md: */ @@ -146,6 +146,7 @@ struct md_softc *sc = device_private(self); sc->sc_dev = self; + sc->sc_type = MD_UNCONFIGURED; mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); cv_init(&sc->sc_cv, "mdidle"); bufq_alloc(&sc->sc_buflist, "fcfs", 0); @@ -181,7 +182,7 @@ rc = 0; mutex_enter(&sc->sc_dkdev.dk_openlock); - if (sc->sc_dkdev.dk_openmask == 0) + if (sc->sc_dkdev.dk_openmask == 0 && sc->sc_type == MD_UNCONFIGURED) ; /* nothing to do */ else if ((flags & DETACH_FORCE) == 0) rc = EBUSY; @@ -433,10 +434,11 @@ bp->b_error = EIO; break; } - done: - biodone(bp); + done: mutex_exit(&sc->sc_lock); + + biodone(bp); } static int @@ -561,14 +563,23 @@ vaddr_t addr; vsize_t size; - KASSERT(mutex_owned(&sc->sc_lock)); + mutex_exit(&sc->sc_lock); /* Sanity check the size. */ size = umd->md_size; addr = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_WIRED|UVM_KMF_ZERO); + + mutex_enter(&sc->sc_lock); + if (!addr) return ENOMEM; + /* If another thread beat us to configure this unit: fail. */ + if (sc->sc_type != MD_UNCONFIGURED) { + uvm_km_free(kernel_map, addr, size, UVM_KMF_WIRED); + return EINVAL; + } + /* This unit is now configured. */ sc->sc_addr = (void *)addr; /* kernel space */ sc->sc_size = (size_t)size;