Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Oct 2012 10:02:18 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241773 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201210201002.q9KA2I1n002525@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Sat Oct 20 10:02:18 2012
New Revision: 241773
URL: http://svn.freebsd.org/changeset/base/241773

Log:
  zfs: wait in arc_lowmem only if curproc == pageproc
  
  ... otherwise the current thread might be holding ARC locks and thus run
  into a deadlock.  This happens, for example, when a thread does memory
  allocation in the ARC code and runs into KVA shortage.
  Also, it really makes the most sense to wait in pageproc, so that the
  results of ARC reclamation are seen before the page cache is acted upon.
  In other cases where vm_lowmem is invoked, e.g. on KVA space shortage,
  the callers perform multiple attempts (up to 8) and wait for rather
  long intervals between them (up to 4 seconds), so ARC reclaim results
  should become visible even without explicit waiting on the ARC thread.
  
  Note that this is not a critical issue for typical ZFS usages where KVA
  space should already be large enough.  On amd64 systems setting KVA size
  to twice the physical memory size is known to mitigate KVA fragmentation
  issues in practice.
  
  Side note: perhaps vm_lowmem 'how' parameter should be used to
  differentiate between causes of the event.
  
  Reported by:	Nikolay Denev <ndenev@gmail.com>
  MFC after:	19 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Sat Oct 20 09:40:34 2012	(r241772)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Sat Oct 20 10:02:18 2012	(r241773)
@@ -3792,8 +3792,16 @@ arc_lowmem(void *arg __unused, int howto
 	mutex_enter(&arc_reclaim_thr_lock);
 	needfree = 1;
 	cv_signal(&arc_reclaim_thr_cv);
-	while (needfree)
-		msleep(&needfree, &arc_reclaim_thr_lock, 0, "zfs:lowmem", 0);
+
+	/*
+	 * It is unsafe to block here in arbitrary threads, because we can come
+	 * here from ARC itself and may hold ARC locks and thus risk a deadlock
+	 * with ARC reclaim thread.
+	 */
+	if (curproc == pageproc) {
+		while (needfree)
+			msleep(&needfree, &arc_reclaim_thr_lock, 0, "zfs:lowmem", 0);
+	}
 	mutex_exit(&arc_reclaim_thr_lock);
 	mutex_exit(&arc_lowmem_lock);
 }



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