From owner-svn-src-all@FreeBSD.ORG Mon Aug 25 17:06:19 2014 Return-Path: Delivered-To: svn-src-all@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 ESMTPS id 486D34F3; Mon, 25 Aug 2014 17:06:19 +0000 (UTC) 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)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2EF6931E1; Mon, 25 Aug 2014 17:06:19 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7PH6JC5011123; Mon, 25 Aug 2014 17:06:19 GMT (envelope-from davide@FreeBSD.org) Received: (from davide@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7PH6Jbi011122; Mon, 25 Aug 2014 17:06:19 GMT (envelope-from davide@FreeBSD.org) Message-Id: <201408251706.s7PH6Jbi011122@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: davide set sender to davide@FreeBSD.org using -f From: Davide Italiano Date: Mon, 25 Aug 2014 17:06:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270588 - head/sys/ufs/ufs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 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, 25 Aug 2014 17:06:19 -0000 Author: davide Date: Mon Aug 25 17:06:18 2014 New Revision: 270588 URL: http://svnweb.freebsd.org/changeset/base/270588 Log: Rather than using an hardcoded reclaim age, rely on an LRU-like approach for dirhash cache, setting a target percent to reclaim (exposed via SYSCTL). This allows to always make some amount of progress keeping the maximum reclaim age dynamic. Tested by: pho Reviewed by: jhb Modified: head/sys/ufs/ufs/ufs_dirhash.c Modified: head/sys/ufs/ufs/ufs_dirhash.c ============================================================================== --- head/sys/ufs/ufs/ufs_dirhash.c Mon Aug 25 16:56:33 2014 (r270587) +++ head/sys/ufs/ufs/ufs_dirhash.c Mon Aug 25 17:06:18 2014 (r270588) @@ -85,10 +85,10 @@ SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_d 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 = 60; -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 ufs_dirhash_reclaimperc = 10; +SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_reclaimperc, CTLFLAG_RW, + &ufs_dirhash_reclaimperc, 0, + "percentage of dirhash cache to be removed in low VM events"); static int ufsdirhash_hash(struct dirhash *dh, char *name, int namelen); @@ -1247,45 +1247,28 @@ static void ufsdirhash_lowmem() { struct dirhash *dh, *dh_temp; - int memfreed = 0; - /* - * Will free a *minimum* of 10% of the dirhash, but possibly much - * more (depending on dirhashreclaimage). System with large dirhashes - * probably also need a much larger dirhashreclaimage. - * XXX: this percentage may need to be adjusted. - */ - int memwanted = ufs_dirhashmem / 10; + int memfreed, memwanted; ufs_dirhashlowmemcount++; + memfreed = 0; + memwanted = ufs_dirhashmem / ufs_dirhash_reclaimperc; DIRHASHLIST_LOCK(); - /* - * Delete dirhashes not used for more than ufs_dirhashreclaimage - * seconds. If we can't get a lock on the dirhash, it will be skipped. - */ - TAILQ_FOREACH_SAFE(dh, &ufsdirhash_list, dh_list, dh_temp) { - if (!sx_try_xlock(&dh->dh_lock)) - continue; - if (time_second - dh->dh_lastused > ufs_dirhashreclaimage) - memfreed += ufsdirhash_destroy(dh); - /* Unlock if we didn't delete the dirhash */ - else - ufsdirhash_release(dh); - } - /* - * 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. + /* + * Reclaim up to memwanted from the oldest dirhashes. This will allow + * us to make some progress when the system is running out of memory + * without compromising the dinamicity of maximum age. If the situation + * does not improve lowmem will be eventually retriggered and free some + * other entry in the cache. The entries on the head of the list should + * be the oldest. If during list traversal we can't get a lock on the + * dirhash, it will be skipped. */ - if (memfreed < memwanted) { - TAILQ_FOREACH_SAFE(dh, &ufsdirhash_list, dh_list, dh_temp) { - if (!sx_try_xlock(&dh->dh_lock)) - continue; + TAILQ_FOREACH_SAFE(dh, &ufsdirhash_list, dh_list, dh_temp) { + if (sx_try_xlock(&dh->dh_lock)) memfreed += ufsdirhash_destroy(dh); - if (memfreed >= memwanted) - break; - } + if (memfreed >= memwanted) + break; } DIRHASHLIST_UNLOCK(); }