From owner-svn-src-head@FreeBSD.ORG Mon Aug 5 22:01:17 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 2FC9EB81; Mon, 5 Aug 2013 22:01:17 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id EB09B2AA6; Mon, 5 Aug 2013 22:01:16 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r75M1Gw6048101; Mon, 5 Aug 2013 22:01:16 GMT (envelope-from mckusick@svn.freebsd.org) Received: (from mckusick@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r75M1GCw048099; Mon, 5 Aug 2013 22:01:16 GMT (envelope-from mckusick@svn.freebsd.org) Message-Id: <201308052201.r75M1GCw048099@svn.freebsd.org> From: Kirk McKusick Date: Mon, 5 Aug 2013 22:01:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r253973 - head/sys/ufs/ffs 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, 05 Aug 2013 22:01:17 -0000 Author: mckusick Date: Mon Aug 5 22:01:16 2013 New Revision: 253973 URL: http://svnweb.freebsd.org/changeset/base/253973 Log: To better understand performance problems with journalled soft updates, we need to collect the highest level of allocation for each of the different soft update dependency structures. This change collects these statistics and makes them available using `sysctl debug.softdep.highuse'. Reviewed by: kib Tested by: Peter Holm MFC after: 2 weeks Modified: head/sys/ufs/ffs/ffs_softdep.c Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Mon Aug 5 20:30:15 2013 (r253972) +++ head/sys/ufs/ffs/ffs_softdep.c Mon Aug 5 22:01:16 2013 (r253973) @@ -661,14 +661,16 @@ FEATURE(softupdates, "FFS soft-updates s #define D_LAST D_SENTINEL unsigned long dep_current[D_LAST + 1]; +unsigned long dep_highuse[D_LAST + 1]; unsigned long dep_total[D_LAST + 1]; unsigned long dep_write[D_LAST + 1]; - static SYSCTL_NODE(_debug, OID_AUTO, softdep, CTLFLAG_RW, 0, "soft updates stats"); static SYSCTL_NODE(_debug_softdep, OID_AUTO, total, CTLFLAG_RW, 0, "total dependencies allocated"); +static SYSCTL_NODE(_debug_softdep, OID_AUTO, highuse, CTLFLAG_RW, 0, + "high use dependencies allocated"); static SYSCTL_NODE(_debug_softdep, OID_AUTO, current, CTLFLAG_RW, 0, "current dependencies allocated"); static SYSCTL_NODE(_debug_softdep, OID_AUTO, write, CTLFLAG_RW, 0, @@ -680,6 +682,8 @@ static SYSCTL_NODE(_debug_softdep, OID_A &dep_total[D_ ## type], 0, ""); \ SYSCTL_ULONG(_debug_softdep_current, OID_AUTO, str, CTLFLAG_RD, \ &dep_current[D_ ## type], 0, ""); \ + SYSCTL_ULONG(_debug_softdep_highuse, OID_AUTO, str, CTLFLAG_RD, \ + &dep_highuse[D_ ## type], 0, ""); \ SYSCTL_ULONG(_debug_softdep_write, OID_AUTO, str, CTLFLAG_RD, \ &dep_write[D_ ## type], 0, ""); @@ -1204,8 +1208,12 @@ jwork_insert(dst, jsegdep) */ static void workitem_free(struct worklist *, int); static void workitem_alloc(struct worklist *, int, struct mount *); +static void workitem_reassign(struct worklist *, int); -#define WORKITEM_FREE(item, type) workitem_free((struct worklist *)(item), (type)) +#define WORKITEM_FREE(item, type) \ + workitem_free((struct worklist *)(item), (type)) +#define WORKITEM_REASSIGN(item, type) \ + workitem_reassign((struct worklist *)(item), (type)) static void workitem_free(item, type) @@ -1219,16 +1227,22 @@ workitem_free(item, type) if (item->wk_state & ONWORKLIST) panic("workitem_free: %s(0x%X) still on list", TYPENAME(item->wk_type), item->wk_state); - if (item->wk_type != type) + if (item->wk_type != type && type != D_NEWBLK) panic("workitem_free: type mismatch %s != %s", TYPENAME(item->wk_type), TYPENAME(type)); #endif if (item->wk_state & IOWAITING) wakeup(item); ump = VFSTOUFS(item->wk_mp); + KASSERT(ump->softdep_deps > 0, + ("workitem_free: %s: softdep_deps going negative", + ump->um_fs->fs_fsmnt)); if (--ump->softdep_deps == 0 && ump->softdep_req) wakeup(&ump->softdep_deps); - dep_current[type]--; + KASSERT(dep_current[item->wk_type] > 0, + ("workitem_free: %s: dep_current[%s] going negative", + ump->um_fs->fs_fsmnt, TYPENAME(item->wk_type))); + dep_current[item->wk_type]--; free(item, DtoM(type)); } @@ -1247,12 +1261,31 @@ workitem_alloc(item, type, mp) ump = VFSTOUFS(mp); ACQUIRE_LOCK(&lk); dep_current[type]++; + if (dep_current[type] > dep_highuse[type]) + dep_highuse[type] = dep_current[type]; dep_total[type]++; ump->softdep_deps++; ump->softdep_accdeps++; FREE_LOCK(&lk); } +static void +workitem_reassign(item, newtype) + struct worklist *item; + int newtype; +{ + + KASSERT(dep_current[item->wk_type] > 0, + ("workitem_reassign: %s: dep_current[%s] going negative", + VFSTOUFS(item->wk_mp)->um_fs->fs_fsmnt, TYPENAME(item->wk_type))); + dep_current[item->wk_type]--; + dep_current[newtype]++; + if (dep_current[newtype] > dep_highuse[newtype]) + dep_highuse[newtype] = dep_current[newtype]; + dep_total[newtype]++; + item->wk_type = newtype; +} + /* * Workitem queue management */ @@ -5122,7 +5155,7 @@ softdep_setup_allocdirect(ip, off, newbl /* * Convert the newblk to an allocdirect. */ - newblk->nb_list.wk_type = D_ALLOCDIRECT; + WORKITEM_REASSIGN(newblk, D_ALLOCDIRECT); adp = (struct allocdirect *)newblk; newblk->nb_freefrag = freefrag; adp->ad_offset = off; @@ -5478,7 +5511,7 @@ softdep_setup_allocext(ip, off, newblkno /* * Convert the newblk to an allocdirect. */ - newblk->nb_list.wk_type = D_ALLOCDIRECT; + WORKITEM_REASSIGN(newblk, D_ALLOCDIRECT); adp = (struct allocdirect *)newblk; newblk->nb_freefrag = freefrag; adp->ad_offset = off; @@ -5587,7 +5620,7 @@ newallocindir(ip, ptrno, newblkno, oldbl panic("new_allocindir: lost block"); KASSERT(newblk->nb_list.wk_type == D_NEWBLK, ("newallocindir: newblk already initialized")); - newblk->nb_list.wk_type = D_ALLOCINDIR; + WORKITEM_REASSIGN(newblk, D_ALLOCINDIR); newblk->nb_freefrag = freefrag; aip = (struct allocindir *)newblk; aip->ai_offset = ptrno; @@ -7218,7 +7251,9 @@ free_newblk(newblk) struct worklist *wk; KASSERT(newblk->nb_jnewblk == NULL, - ("free_newblk; jnewblk %p still attached", newblk->nb_jnewblk)); + ("free_newblk: jnewblk %p still attached", newblk->nb_jnewblk)); + KASSERT(newblk->nb_list.wk_type != D_NEWBLK, + ("free_newblk: unclaimed newblk")); rw_assert(&lk, RA_WLOCKED); newblk_freefrag(newblk); if (newblk->nb_state & ONDEPLIST) @@ -7233,7 +7268,6 @@ free_newblk(newblk) while ((indirdep = LIST_FIRST(&newblk->nb_indirdeps)) != NULL) indirdep_complete(indirdep); handle_jwork(&newblk->nb_jwork); - newblk->nb_list.wk_type = D_NEWBLK; WORKITEM_FREE(newblk, D_NEWBLK); }