From owner-svn-src-head@FreeBSD.ORG Tue Nov 1 23:12:23 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 428621065675; Tue, 1 Nov 2011 23:12:23 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 32F158FC0C; Tue, 1 Nov 2011 23:12:23 +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 pA1NCNab089114; Tue, 1 Nov 2011 23:12:23 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pA1NCNuY089112; Tue, 1 Nov 2011 23:12:23 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201111012312.pA1NCNuY089112@svn.freebsd.org> From: Alexander Motin Date: Tue, 1 Nov 2011 23:12:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r227009 - head/sys/geom X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Nov 2011 23:12:23 -0000 Author: mav Date: Tue Nov 1 23:12:22 2011 New Revision: 227009 URL: http://svn.freebsd.org/changeset/base/227009 Log: Make orphan() method in geom_dev asynchronous using destroy_dev_sched_cb() instead of destroy_dev(). It moves device destruction waiting out of the topology lock and so fixes dead lock between orphanization and closing. Real provider and geom destruction called from swi context after device destroyed as callback of the destroy_dev_sched_cb(). Modified: head/sys/geom/geom_dev.c Modified: head/sys/geom/geom_dev.c ============================================================================== --- head/sys/geom/geom_dev.c Tue Nov 1 22:22:46 2011 (r227008) +++ head/sys/geom/geom_dev.c Tue Nov 1 23:12:22 2011 (r227009) @@ -506,6 +506,32 @@ g_dev_strategy(struct bio *bp) */ static void +g_dev_cleanup(void *arg) +{ + struct g_geom *gp; + struct g_consumer *cp; + + mtx_unlock(&Giant); + cp = arg; + gp = cp->geom; + g_trace(G_T_TOPOLOGY, "g_dev_cleanup(%p(%s))", cp, cp->provider->name); + + /* Wait for the cows to come home */ + while (cp->nstart != cp->nend) + pause("gdevcleanup", hz / 10); + + g_topology_lock(); + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + g_access(cp, -cp->acr, -cp->acw, -cp->ace); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + g_topology_unlock(); + mtx_lock(&Giant); +} + +static void g_dev_orphan(struct g_consumer *cp) { struct g_geom *gp; @@ -521,18 +547,7 @@ g_dev_orphan(struct g_consumer *cp) set_dumper(NULL); /* Destroy the struct cdev *so we get no more requests */ - destroy_dev(dev); - - /* Wait for the cows to come home */ - while (cp->nstart != cp->nend) - pause("gdevorphan", hz / 10); - - if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) - g_access(cp, -cp->acr, -cp->acw, -cp->ace); - - g_detach(cp); - g_destroy_consumer(cp); - g_destroy_geom(gp); + destroy_dev_sched_cb(dev, g_dev_cleanup, cp); } DECLARE_GEOM_CLASS(g_dev_class, g_dev);