From owner-svn-src-head@FreeBSD.ORG Mon Oct 29 14:18:55 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 39F04236; Mon, 29 Oct 2012 14:18:55 +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 2238E8FC12; Mon, 29 Oct 2012 14:18: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 q9TEIso4078109; Mon, 29 Oct 2012 14:18:54 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9TEIsrZ078107; Mon, 29 Oct 2012 14:18:54 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201210291418.q9TEIsrZ078107@svn.freebsd.org> From: Alexander Motin Date: Mon, 29 Oct 2012 14:18:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r242314 - head/sys/geom/raid X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 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: Mon, 29 Oct 2012 14:18:55 -0000 Author: mav Date: Mon Oct 29 14:18:54 2012 New Revision: 242314 URL: http://svn.freebsd.org/changeset/base/242314 Log: Make GEOM RAID more aggressive in marking volumes as clean on shutdown and move that action from shutdown_pre_sync to shutdown_post_sync stage to avoid extra flapping. ZFS tends to not close devices on shutdown, that doesn't allow GEOM RAID to shutdown gracefully. To handle that, mark volume as clean just when shutdown time comes and there are no active writes. MFC after: 2 weeks Modified: head/sys/geom/raid/g_raid.c Modified: head/sys/geom/raid/g_raid.c ============================================================================== --- head/sys/geom/raid/g_raid.c Mon Oct 29 13:58:11 2012 (r242313) +++ head/sys/geom/raid/g_raid.c Mon Oct 29 14:18:54 2012 (r242314) @@ -108,8 +108,9 @@ LIST_HEAD(, g_raid_tr_class) g_raid_tr_c LIST_HEAD(, g_raid_volume) g_raid_volumes = LIST_HEAD_INITIALIZER(g_raid_volumes); -static eventhandler_tag g_raid_pre_sync = NULL; +static eventhandler_tag g_raid_post_sync = NULL; static int g_raid_started = 0; +static int g_raid_shutdown = 0; static int g_raid_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp); @@ -881,7 +882,7 @@ g_raid_orphan(struct g_consumer *cp) G_RAID_EVENT_DISK); } -static int +static void g_raid_clean(struct g_raid_volume *vol, int acw) { struct g_raid_softc *sc; @@ -892,22 +893,21 @@ g_raid_clean(struct g_raid_volume *vol, sx_assert(&sc->sc_lock, SX_XLOCKED); // if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOFAILSYNC) != 0) -// return (0); +// return; if (!vol->v_dirty) - return (0); + return; if (vol->v_writes > 0) - return (0); + return; if (acw > 0 || (acw == -1 && vol->v_provider != NULL && vol->v_provider->acw > 0)) { timeout = g_raid_clean_time - (time_uptime - vol->v_last_write); - if (timeout > 0) - return (timeout); + if (!g_raid_shutdown && timeout > 0) + return; } vol->v_dirty = 0; G_RAID_DEBUG1(1, sc, "Volume %s marked as clean.", vol->v_name); g_raid_write_metadata(sc, vol, NULL, NULL); - return (0); } static void @@ -1520,8 +1520,7 @@ process: g_raid_disk_done_request(bp); } else if (rv == EWOULDBLOCK) { TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) { - if (vol->v_writes == 0 && vol->v_dirty) - g_raid_clean(vol, -1); + g_raid_clean(vol, -1); if (bioq_first(&vol->v_inflight) == NULL && vol->v_tr) { t.tv_sec = g_raid_idle_threshold / 1000000; @@ -1783,7 +1782,7 @@ g_raid_access(struct g_provider *pp, int error = ENXIO; goto out; } - if (dcw == 0 && vol->v_dirty) + if (dcw == 0) g_raid_clean(vol, dcw); vol->v_provider_open += acr + acw + ace; /* Handle delayed node destruction. */ @@ -2379,21 +2378,25 @@ g_raid_dumpconf(struct sbuf *sb, const c } static void -g_raid_shutdown_pre_sync(void *arg, int howto) +g_raid_shutdown_post_sync(void *arg, int howto) { struct g_class *mp; struct g_geom *gp, *gp2; struct g_raid_softc *sc; + struct g_raid_volume *vol; int error; mp = arg; DROP_GIANT(); g_topology_lock(); + g_raid_shutdown = 1; LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { if ((sc = gp->softc) == NULL) continue; g_topology_unlock(); sx_xlock(&sc->sc_lock); + TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) + g_raid_clean(vol, -1); g_cancel_event(sc); error = g_raid_destroy(sc, G_RAID_DESTROY_DELAYED); if (error != 0) @@ -2408,9 +2411,9 @@ static void g_raid_init(struct g_class *mp) { - g_raid_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync, - g_raid_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST); - if (g_raid_pre_sync == NULL) + g_raid_post_sync = EVENTHANDLER_REGISTER(shutdown_post_sync, + g_raid_shutdown_post_sync, mp, SHUTDOWN_PRI_FIRST); + if (g_raid_post_sync == NULL) G_RAID_DEBUG(0, "Warning! Cannot register shutdown event."); g_raid_started = 1; } @@ -2419,8 +2422,8 @@ static void g_raid_fini(struct g_class *mp) { - if (g_raid_pre_sync != NULL) - EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_raid_pre_sync); + if (g_raid_post_sync != NULL) + EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_raid_post_sync); g_raid_started = 0; }