Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Aug 2009 11:00:38 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196206 - head/sys/ufs/ffs
Message-ID:  <200908141100.n7EB0cnM032109@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Aug 14 11:00:38 2009
New Revision: 196206
URL: http://svn.freebsd.org/changeset/base/196206

Log:
  When a UFS node is truncated to the zero length, e.g. by explicit
  truncate(2) call, or by being removed or truncated on open, either
  new softupdate freeblks structure is allocated to track the freed
  blocks of the node, or truncation is done syncronously when too many SU
  dependencies are accumulated. The decision does not take into account
  the allocated freeblks dependencies, allowing workloads that do huge
  amount of truncations to exhaust the kernel memory.
  
  Take the number of allocated freeblks into consideration for
  softdep_slowdown().
  
  Reported by:	pluknet gmail com
  Diagnosed and tested by:	pho
  Approved by:	re (rwatson)
  MFC after:	1 month

Modified:
  head/sys/ufs/ffs/ffs_softdep.c

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c	Fri Aug 14 10:59:17 2009	(r196205)
+++ head/sys/ufs/ffs/ffs_softdep.c	Fri Aug 14 11:00:38 2009	(r196206)
@@ -663,6 +663,8 @@ static int req_clear_inodedeps;	/* synce
 static int req_clear_remove;	/* syncer process flush some freeblks */
 #define FLUSH_REMOVE		2
 #define FLUSH_REMOVE_WAIT	3
+static long num_freeblkdep;	/* number of freeblks workitems allocated */
+
 /*
  * runtime statistics
  */
@@ -2223,6 +2225,9 @@ softdep_setup_freeblocks(ip, length, fla
 	freeblks->fb_uid = ip->i_uid;
 	freeblks->fb_previousinum = ip->i_number;
 	freeblks->fb_devvp = ip->i_devvp;
+	ACQUIRE_LOCK(&lk);
+	num_freeblkdep++;
+	FREE_LOCK(&lk);
 	extblocks = 0;
 	if (fs->fs_magic == FS_UFS2_MAGIC)
 		extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize));
@@ -2815,6 +2820,7 @@ handle_workitem_freeblocks(freeblks, fla
 
 	ACQUIRE_LOCK(&lk);
 	WORKITEM_FREE(freeblks, D_FREEBLKS);
+	num_freeblkdep--;
 	FREE_LOCK(&lk);
 }
 
@@ -5768,7 +5774,8 @@ softdep_slowdown(vp)
 	max_softdeps_hard = max_softdeps * 11 / 10;
 	if (num_dirrem < max_softdeps_hard / 2 &&
 	    num_inodedep < max_softdeps_hard &&
-	    VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps) {
+	    VFSTOUFS(vp->v_mount)->um_numindirdeps < maxindirdeps &&
+	    num_freeblkdep < max_softdeps_hard) {
 		FREE_LOCK(&lk);
   		return (0);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908141100.n7EB0cnM032109>