diff options
author | mav <mav@FreeBSD.org> | 2011-11-14 19:32:05 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2011-11-14 19:32:05 +0000 |
commit | 37d5d5108cef436d7c051302ebfce1a2dc896d75 (patch) | |
tree | 26e449be0af546845a7e5185f5bc903ebfd5d281 /sys/geom/geom_dev.c | |
parent | ac43b78431b6743d37ad937a415adbc0d502e2e3 (diff) | |
download | FreeBSD-src-37d5d5108cef436d7c051302ebfce1a2dc896d75.zip FreeBSD-src-37d5d5108cef436d7c051302ebfce1a2dc896d75.tar.gz |
Temporary revert r227009 to fix freeze on UP systems without PREEMPTION.
Before r215687, if some withered geom or provider could not be destroyed,
g_event thread went to sleep for 0.1s before retrying. After that change
it is just restarting immediately. r227009 made orphaned (withered) provider
to not detach immediately, but only after context switch. That made loop
inside g_event thread infinite on UP systems without PREEMPTION.
To address original problem with possible dead lock addressed by r227009
we have to fix r215687 change first, that needs some time to think and test.
Diffstat (limited to 'sys/geom/geom_dev.c')
-rw-r--r-- | sys/geom/geom_dev.c | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index fa2a89a..210f2ee 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -506,32 +506,6 @@ 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; @@ -547,7 +521,18 @@ g_dev_orphan(struct g_consumer *cp) set_dumper(NULL); /* Destroy the struct cdev *so we get no more requests */ - destroy_dev_sched_cb(dev, g_dev_cleanup, cp); + 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); } DECLARE_GEOM_CLASS(g_dev_class, g_dev); |