From owner-p4-projects@FreeBSD.ORG Mon Aug 11 09:24:15 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5DE121065672; Mon, 11 Aug 2008 09:24:15 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 073ED106564A for ; Mon, 11 Aug 2008 09:24:15 +0000 (UTC) (envelope-from snb@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E68578FC0C for ; Mon, 11 Aug 2008 09:24:14 +0000 (UTC) (envelope-from snb@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m7B9OE1d081620 for ; Mon, 11 Aug 2008 09:24:14 GMT (envelope-from snb@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m7B9OEBL081618 for perforce@freebsd.org; Mon, 11 Aug 2008 09:24:14 GMT (envelope-from snb@FreeBSD.org) Date: Mon, 11 Aug 2008 09:24:14 GMT Message-Id: <200808110924.m7B9OEBL081618@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to snb@FreeBSD.org using -f From: Nick Barkas To: Perforce Change Reviews Cc: Subject: PERFORCE change 147142 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Aug 2008 09:24:15 -0000 http://perforce.freebsd.org/chv.cgi?CH=147142 Change 147142 by snb@snb_toro on 2008/08/11 09:23:37 * Replace DH_RECLAIMAGE with a writeable sysctl (vfs.ufs.dirhash_reclaimage) * Fix bug where ufsdirhash_lowmem() tries to delete old locked hashes instead of skipping them, and doesn't delete the unlocked ones. * ufsdirhash_lowmem() now is more aggressive and deletes at a minimum enough dirhashes to free 10% of ufs_dirhashmem per invocation, and always deletes hashes it can older than ufs_dirhashreclaimage, as suggested by Alan Cox. Affected files ... .. //depot/projects/soc2008/snb-dirhash/sys-ufs-ufs/dirhash.h#3 edit .. //depot/projects/soc2008/snb-dirhash/sys-ufs-ufs/ufs_dirhash.c#8 edit Differences ... ==== //depot/projects/soc2008/snb-dirhash/sys-ufs-ufs/dirhash.h#3 (text+ko) ==== @@ -68,12 +68,6 @@ #define DH_SCOREINIT 8 /* initial dh_score when dirhash built */ #define DH_SCOREMAX 64 /* max dh_score value */ -/* - * If a vm_lowmem signal is received, we will try to free memory by - * deleting all hashes older than DH_RECLAIMAGE seconds. - */ -#define DH_RECLAIMAGE 5 - /* * The main hash table has 2 levels. It is an array of pointers to * blocks of DH_NBLKOFF offsets. ==== //depot/projects/soc2008/snb-dirhash/sys-ufs-ufs/ufs_dirhash.c#8 (text+ko) ==== @@ -85,6 +85,10 @@ static int ufs_dirhashlowmemcount = 0; SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_lowmemcount, CTLFLAG_RD, &ufs_dirhashlowmemcount, 0, "number of times low memory hook called"); +static int ufs_dirhashreclaimage = 5; +SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_reclaimage, CTLFLAG_RW, + &ufs_dirhashreclaimage, 0, + "max time in seconds of hash inactivity before deletion in low VM events"); static int ufsdirhash_hash(struct dirhash *dh, char *name, int namelen); @@ -1173,39 +1177,34 @@ { struct dirhash *dh; int memfreed = 0; + /* XXX: this 10% may need to be adjusted */ int memwanted = ufs_dirhashmem / 10; ufs_dirhashlowmemcount++; DIRHASHLIST_LOCK(); /* - * Delete dirhashes not used for more than DH_RECLAIMAGE seconds. - * If we can't get a lock on the dirhash, it will be skipped. Quit - * when we have freed up 10% or more of the memory currently used by - * dirhashes. - * XXX 10% may need to be adjusted? + * Delete dirhashes not used for more than ufs_dirhashreclaimage + * seconds. If we can't get a lock on the dirhash, it will be skipped. */ for (dh = TAILQ_FIRST(&ufsdirhash_list); dh != NULL; dh = TAILQ_NEXT(dh, dh_list)) { - if (time_second - dh->dh_lastused > DH_RECLAIMAGE && - lockmgr(&dh->dh_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL)) + if (lockmgr(&dh->dh_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL)) + continue; + if (time_second - dh->dh_lastused > ufs_dirhashreclaimage) memfreed += ufsdirhash_destroy(dh); - if (memfreed >= memwanted) - break; } /* - * If no hashes were old enough, instead try deleting a single dirhash - * from the end of the list. + * If not enough memory was freed, keep deleting hashes from the head + * of the dirhash list. The ones closest to the head should be the + * oldest. */ - dh = TAILQ_FIRST(&ufsdirhash_list); - while (memfreed == 0 && dh != NULL) { - if (lockmgr(&dh->dh_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { - dh = TAILQ_NEXT(dh, dh_list); + for (dh = TAILQ_FIRST(&ufsdirhash_list); memfreed < memwanted && + dh !=NULL; dh = TAILQ_NEXT(dh, dh_list)) { + if (lockmgr(&dh->dh_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL)) continue; - } memfreed += ufsdirhash_destroy(dh); - break; } DIRHASHLIST_UNLOCK(); }