From owner-svn-src-all@FreeBSD.ORG Mon Nov 22 16:47:54 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ECAE01065672; Mon, 22 Nov 2010 16:47:53 +0000 (UTC) (envelope-from jh@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id DBC9C8FC0C; Mon, 22 Nov 2010 16:47:53 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAMGlrYf098188; Mon, 22 Nov 2010 16:47:53 GMT (envelope-from jh@svn.freebsd.org) Received: (from jh@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAMGlrEB098185; Mon, 22 Nov 2010 16:47:53 GMT (envelope-from jh@svn.freebsd.org) Message-Id: <201011221647.oAMGlrEB098185@svn.freebsd.org> From: Jaakko Heinonen Date: Mon, 22 Nov 2010 16:47:53 +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: r215687 - head/sys/geom X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Nov 2010 16:47:54 -0000 Author: jh Date: Mon Nov 22 16:47:53 2010 New Revision: 215687 URL: http://svn.freebsd.org/changeset/base/215687 Log: Use g_eventlock to protect against losing wakeups in the g_event process and replace tsleep(9) with msleep(9) which doesn't use a timeout. The previously used timeout caused the event process to wake up ten times per second on an idle system. one_event() is now called with the topology lock held and it returns with both the topology and event locks held when there are no more events in the queue. Reported by: mav, Marius NĂ¼nnerich Reviewed by: freebsd-geom Modified: head/sys/geom/geom_event.c head/sys/geom/geom_kern.c Modified: head/sys/geom/geom_event.c ============================================================================== --- head/sys/geom/geom_event.c Mon Nov 22 16:43:05 2010 (r215686) +++ head/sys/geom/geom_event.c Mon Nov 22 16:47:53 2010 (r215687) @@ -183,33 +183,27 @@ one_event(void) struct g_event *ep; struct g_provider *pp; - g_topology_lock(); - for (;;) { - mtx_lock(&g_eventlock); - TAILQ_FOREACH(pp, &g_doorstep, orphan) { - if (pp->nstart == pp->nend) - break; - } - if (pp != NULL) { - G_VALID_PROVIDER(pp); - TAILQ_REMOVE(&g_doorstep, pp, orphan); - } - mtx_unlock(&g_eventlock); - if (pp == NULL) + g_topology_assert(); + mtx_lock(&g_eventlock); + TAILQ_FOREACH(pp, &g_doorstep, orphan) { + if (pp->nstart == pp->nend) break; + } + if (pp != NULL) { + G_VALID_PROVIDER(pp); + TAILQ_REMOVE(&g_doorstep, pp, orphan); + mtx_unlock(&g_eventlock); g_orphan_register(pp); + return (1); } - mtx_lock(&g_eventlock); + ep = TAILQ_FIRST(&g_events); if (ep == NULL) { wakeup(&g_pending_events); - mtx_unlock(&g_eventlock); - g_topology_unlock(); return (0); } if (ep->flag & EV_INPROGRESS) { mtx_unlock(&g_eventlock); - g_topology_unlock(); return (1); } ep->flag |= EV_INPROGRESS; @@ -228,7 +222,6 @@ one_event(void) mtx_unlock(&g_eventlock); g_free(ep); } - g_topology_unlock(); return (1); } @@ -237,16 +230,27 @@ g_run_events() { int i; - while (one_event()) - ; - g_topology_lock(); - i = g_wither_work; - while (i) { - i = g_wither_washer(); - g_wither_work = i & 1; - i &= 2; + for (;;) { + g_topology_lock(); + while (one_event()) + ; + mtx_assert(&g_eventlock, MA_OWNED); + i = g_wither_work; + if (i) { + mtx_unlock(&g_eventlock); + while (i) { + i = g_wither_washer(); + g_wither_work = i & 1; + i &= 2; + } + g_topology_unlock(); + } else { + g_topology_unlock(); + msleep(&g_wait_event, &g_eventlock, PRIBIO | PDROP, + "-", 0); + } } - g_topology_unlock(); + /* NOTREACHED */ } void @@ -338,9 +342,12 @@ g_post_event(g_event_t *func, void *arg, } void -g_do_wither() { +g_do_wither() +{ + mtx_lock(&g_eventlock); g_wither_work = 1; + mtx_unlock(&g_eventlock); wakeup(&g_wait_event); } Modified: head/sys/geom/geom_kern.c ============================================================================== --- head/sys/geom/geom_kern.c Mon Nov 22 16:43:05 2010 (r215686) +++ head/sys/geom/geom_kern.c Mon Nov 22 16:47:53 2010 (r215687) @@ -137,10 +137,8 @@ g_event_procbody(void) thread_lock(tp); sched_prio(tp, PRIBIO); thread_unlock(tp); - for(;;) { - g_run_events(); - tsleep(&g_wait_event, PRIBIO, "-", hz/10); - } + g_run_events(); + /* NOTREACHED */ } static struct kproc_desc g_event_kp = {