From owner-svn-src-projects@FreeBSD.ORG Thu Oct 11 19:39:55 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 97E428CB; Thu, 11 Oct 2012 19:39:55 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 771948FC0A; Thu, 11 Oct 2012 19:39:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q9BJdtqx074858; Thu, 11 Oct 2012 19:39:55 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9BJdtBa074853; Thu, 11 Oct 2012 19:39:55 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201210111939.q9BJdtBa074853@svn.freebsd.org> From: Neel Natu Date: Thu, 11 Oct 2012 19:39:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r241454 - in projects/bhyve/sys/amd64: include vmm X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Oct 2012 19:39:55 -0000 Author: neel Date: Thu Oct 11 19:39:54 2012 New Revision: 241454 URL: http://svn.freebsd.org/changeset/base/241454 Log: Fix warnings generated by 'debug.witness.watch' during VM creation and destruction for calling malloc() with M_WAITOK while holding a mutex. Do not allow vmm.ko to be unloaded until all virtual machines are destroyed. Modified: projects/bhyve/sys/amd64/include/vmm_dev.h projects/bhyve/sys/amd64/vmm/vmm.c projects/bhyve/sys/amd64/vmm/vmm_dev.c Modified: projects/bhyve/sys/amd64/include/vmm_dev.h ============================================================================== --- projects/bhyve/sys/amd64/include/vmm_dev.h Thu Oct 11 19:39:45 2012 (r241453) +++ projects/bhyve/sys/amd64/include/vmm_dev.h Thu Oct 11 19:39:54 2012 (r241454) @@ -31,7 +31,7 @@ #ifdef _KERNEL void vmmdev_init(void); -void vmmdev_cleanup(void); +int vmmdev_cleanup(void); #endif struct vm_memory_segment { Modified: projects/bhyve/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm.c Thu Oct 11 19:39:45 2012 (r241453) +++ projects/bhyve/sys/amd64/vmm/vmm.c Thu Oct 11 19:39:54 2012 (r241454) @@ -219,10 +219,12 @@ vmm_handler(module_t mod, int what, void error = vmm_init(); break; case MOD_UNLOAD: - vmmdev_cleanup(); - iommu_cleanup(); - vmm_ipi_cleanup(); - error = VMM_CLEANUP(); + error = vmmdev_cleanup(); + if (error == 0) { + iommu_cleanup(); + vmm_ipi_cleanup(); + error = VMM_CLEANUP(); + } break; default: error = 0; Modified: projects/bhyve/sys/amd64/vmm/vmm_dev.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm_dev.c Thu Oct 11 19:39:45 2012 (r241453) +++ projects/bhyve/sys/amd64/vmm/vmm_dev.c Thu Oct 11 19:39:54 2012 (r241454) @@ -88,18 +88,11 @@ vmmdev_lookup(const char *name) static struct vmmdev_softc * vmmdev_lookup2(struct cdev *cdev) { - struct vmmdev_softc *sc; - #ifdef notyet /* XXX kernel is not compiled with invariants */ mtx_assert(&vmmdev_mtx, MA_OWNED); #endif - SLIST_FOREACH(sc, &head, link) { - if (sc->cdev == cdev) - break; - } - - return (sc); + return (cdev->si_drv1); } static int @@ -114,6 +107,8 @@ vmmdev_rw(struct cdev *cdev, struct uio error = 0; mtx_lock(&vmmdev_mtx); sc = vmmdev_lookup2(cdev); + if (sc == NULL) + error = ENXIO; while (uio->uio_resid > 0 && error == 0) { gpa = uio->uio_offset; @@ -380,20 +375,25 @@ vmmdev_mmap(struct cdev *cdev, vm_ooffse } static void -vmmdev_destroy(struct vmmdev_softc *sc) +vmmdev_destroy(struct vmmdev_softc *sc, boolean_t unlink) { -#ifdef notyet /* XXX kernel is not compiled with invariants */ - mtx_assert(&vmmdev_mtx, MA_OWNED); -#endif - /* * XXX must stop virtual machine instances that may be still * running and cleanup their state. */ - SLIST_REMOVE(&head, sc, vmmdev_softc, link); - destroy_dev(sc->cdev); - vm_destroy(sc->vm); + if (sc->cdev) + destroy_dev(sc->cdev); + + if (sc->vm) + vm_destroy(sc->vm); + + if (unlink) { + mtx_lock(&vmmdev_mtx); + SLIST_REMOVE(&head, sc, vmmdev_softc, link); + mtx_unlock(&vmmdev_mtx); + } + free(sc, M_VMMDEV); } @@ -409,14 +409,22 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS) if (error != 0 || req->newptr == NULL) return (error); + /* + * XXX TODO if any process has this device open then fail + */ + mtx_lock(&vmmdev_mtx); sc = vmmdev_lookup(buf); if (sc == NULL) { mtx_unlock(&vmmdev_mtx); return (EINVAL); } - vmmdev_destroy(sc); + + sc->cdev->si_drv1 = NULL; mtx_unlock(&vmmdev_mtx); + + vmmdev_destroy(sc, TRUE); + return (0); } SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, CTLTYPE_STRING | CTLFLAG_RW, @@ -436,7 +444,7 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS) { int error; struct vm *vm; - struct vmmdev_softc *sc; + struct vmmdev_softc *sc, *sc2; char buf[VM_MAX_NAMELEN]; strlcpy(buf, "beavis", sizeof(buf)); @@ -445,27 +453,37 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS) return (error); mtx_lock(&vmmdev_mtx); - sc = vmmdev_lookup(buf); - if (sc != NULL) { - mtx_unlock(&vmmdev_mtx); + mtx_unlock(&vmmdev_mtx); + if (sc != NULL) return (EEXIST); - } vm = vm_create(buf); - if (vm == NULL) { - mtx_unlock(&vmmdev_mtx); + if (vm == NULL) return (EINVAL); - } sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO); sc->vm = vm; + + /* + * Lookup the name again just in case somebody sneaked in when we + * dropped the lock. + */ + mtx_lock(&vmmdev_mtx); + sc2 = vmmdev_lookup(buf); + if (sc2 == NULL) + SLIST_INSERT_HEAD(&head, sc, link); + mtx_unlock(&vmmdev_mtx); + + if (sc2 != NULL) { + vmmdev_destroy(sc, FALSE); + return (EEXIST); + } + sc->cdev = make_dev(&vmmdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf); sc->cdev->si_drv1 = sc; - SLIST_INSERT_HEAD(&head, sc, link); - mtx_unlock(&vmmdev_mtx); return (0); } SYSCTL_PROC(_hw_vmm, OID_AUTO, create, CTLTYPE_STRING | CTLFLAG_RW, @@ -477,15 +495,15 @@ vmmdev_init(void) mtx_init(&vmmdev_mtx, "vmm device mutex", NULL, MTX_DEF); } -void +int vmmdev_cleanup(void) { - struct vmmdev_softc *sc, *sc2; - - mtx_lock(&vmmdev_mtx); + int error; - SLIST_FOREACH_SAFE(sc, &head, link, sc2) - vmmdev_destroy(sc); + if (SLIST_EMPTY(&head)) + error = 0; + else + error = EBUSY; - mtx_unlock(&vmmdev_mtx); + return (error); }